From: Dan Smith <danms@us.ibm.com>
To: danms@us.ibm.com
Cc: linux-fsdevel@vger.kernel.org, Oren Laadan <orenl@cs.columbia.edu>
Subject: [PATCH 04/19] Make file_pos_read/write() public and export kernel_write()
Date: Tue, 14 Dec 2010 08:14:52 -0800 [thread overview]
Message-ID: <1292343307-7870-4-git-send-email-danms@us.ibm.com> (raw)
In-Reply-To: <1292343307-7870-1-git-send-email-danms@us.ibm.com>
From: Oren Laadan <orenl@cs.columbia.edu>
These three are used in a subsequent patch to allow the kernel c/r
code to call vfs_read/write() to read and write data to and from the
checkpoint image.
This patch makes the following changes:
1) Move kernel_write() from fs/splice.c to fs/exec.c to be near
kernel_read()
2) Make kernel_read/write() iterate if they face partial reads or
writes, and retry if they face -EAGAIN.
3) Adjust prototypes of kernel_read/write() to use size_t and ssize_t
4) Move file_pos_read/write() to include/linux/fs.h
Changelog [ckpt-v21]
- Introduce kernel_write(), fix kernel_read()
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Oren Laadan <orenl@cs.columbia.edu>
Acked-by: Serge E. Hallyn <serue@us.ibm.com>
---
fs/exec.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++----
fs/read_write.c | 10 -------
fs/splice.c | 17 +------------
include/linux/fs.h | 13 +++++++++-
4 files changed, 77 insertions(+), 32 deletions(-)
diff --git a/fs/exec.c b/fs/exec.c
index 99d33a1..5d7a67b 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -720,23 +720,82 @@ exit:
}
EXPORT_SYMBOL(open_exec);
-int kernel_read(struct file *file, loff_t offset,
- char *addr, unsigned long count)
+static ssize_t _kernel_read(struct file *file, loff_t offset,
+ char __user *ubuf, size_t count)
{
- mm_segment_t old_fs;
+ ssize_t nread;
+ size_t nleft;
loff_t pos = offset;
- int result;
+
+ for (nleft = count; nleft; nleft -= nread) {
+ nread = vfs_read(file, ubuf, nleft, &pos);
+ if (nread <= 0) {
+ if (nread == -EAGAIN) {
+ nread = 0;
+ continue;
+ } else if (nread == 0)
+ break;
+ else
+ return nread;
+ }
+ ubuf += nread;
+ }
+ return count - nleft;
+}
+
+ssize_t kernel_read(struct file *file, loff_t offset,
+ char *addr, size_t count)
+{
+ mm_segment_t old_fs;
+ ssize_t result;
old_fs = get_fs();
set_fs(get_ds());
/* The cast to a user pointer is valid due to the set_fs() */
- result = vfs_read(file, (void __user *)addr, count, &pos);
+ result = _kernel_read(file, offset, (void __user *)addr, count);
set_fs(old_fs);
return result;
}
EXPORT_SYMBOL(kernel_read);
+static ssize_t _kernel_write(struct file *file, loff_t offset,
+ const char __user *ubuf, size_t count)
+{
+ ssize_t nwrite;
+ size_t nleft;
+ loff_t pos = offset;
+
+ for (nleft = count; nleft; nleft -= nwrite) {
+ nwrite = vfs_write(file, ubuf, nleft, &pos);
+ if (nwrite < 0) {
+ if (nwrite == -EAGAIN) {
+ nwrite = 0;
+ continue;
+ } else
+ return nwrite;
+ }
+ ubuf += nwrite;
+ }
+ return count - nleft;
+}
+
+ssize_t kernel_write(struct file *file, loff_t offset,
+ const char *addr, size_t count)
+{
+ mm_segment_t old_fs;
+ ssize_t result;
+
+ old_fs = get_fs();
+ set_fs(get_ds());
+ /* The cast to a user pointer is valid due to the set_fs() */
+ result = _kernel_write(file, offset, (void __user *)addr, count);
+ set_fs(old_fs);
+ return result;
+}
+
+EXPORT_SYMBOL(kernel_write);
+
static int exec_mmap(struct mm_struct *mm)
{
struct task_struct *tsk;
diff --git a/fs/read_write.c b/fs/read_write.c
index 431a0ed..91baf85 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -395,16 +395,6 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
EXPORT_SYMBOL(vfs_write);
-static inline loff_t file_pos_read(struct file *file)
-{
- return file->f_pos;
-}
-
-static inline void file_pos_write(struct file *file, loff_t pos)
-{
- file->f_pos = pos;
-}
-
SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
{
struct file *file;
diff --git a/fs/splice.c b/fs/splice.c
index 8f1dfae..b9e90e0 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -562,21 +562,6 @@ static ssize_t kernel_readv(struct file *file, const struct iovec *vec,
return res;
}
-static ssize_t kernel_write(struct file *file, const char *buf, size_t count,
- loff_t pos)
-{
- mm_segment_t old_fs;
- ssize_t res;
-
- old_fs = get_fs();
- set_fs(get_ds());
- /* The cast to a user pointer is valid due to the set_fs() */
- res = vfs_write(file, (const char __user *)buf, count, &pos);
- set_fs(old_fs);
-
- return res;
-}
-
ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
struct pipe_inode_info *pipe, size_t len,
unsigned int flags)
@@ -1049,7 +1034,7 @@ static int write_pipe_buf(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
return ret;
data = buf->ops->map(pipe, buf, 0);
- ret = kernel_write(sd->u.file, data + buf->offset, sd->len, sd->pos);
+ ret = kernel_write(sd->u.file, sd->pos, data + buf->offset, sd->len);
buf->ops->unmap(pipe, buf, data);
return ret;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 334d68a..12cc2e6 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1581,6 +1581,16 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
struct iovec *fast_pointer,
struct iovec **ret_pointer);
+static inline loff_t file_pos_read(struct file *file)
+{
+ return file->f_pos;
+}
+
+static inline void file_pos_write(struct file *file, loff_t pos)
+{
+ file->f_pos = pos;
+}
+
extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *);
extern ssize_t vfs_readv(struct file *, const struct iovec __user *,
@@ -2186,7 +2196,8 @@ extern struct file *do_filp_open(int dfd, const char *pathname,
int open_flag, int mode, int acc_mode);
extern int may_open(struct path *, int, int);
-extern int kernel_read(struct file *, loff_t, char *, unsigned long);
+extern ssize_t kernel_read(struct file *, loff_t, char *, size_t);
+extern ssize_t kernel_write(struct file *, loff_t, const char *, size_t);
extern struct file * open_exec(const char *);
/* fs/dcache.c -- generic fs support functions */
--
1.7.2.2
next prev parent reply other threads:[~2010-12-14 16:24 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-14 16:14 [PATCH 01/19] c/r: extend arch_setup_additional_pages() Dan Smith
2010-12-14 16:14 ` [PATCH 03/19] cgroup freezer: Add CHECKPOINTING state to safeguard container checkpoint Dan Smith
2010-12-14 16:41 ` Dan Smith
2010-12-14 16:14 ` Dan Smith [this message]
2010-12-14 16:45 ` [PATCH 04/19] Make file_pos_read/write() public and export kernel_write() Dan Smith
[not found] ` <1292343307-7870-1-git-send-email-danms-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2010-12-14 16:14 ` [PATCH 05/19] c/r: documentation Dan Smith
2010-12-14 16:14 ` Dan Smith
2010-12-14 16:46 ` Dan Smith
2010-12-14 16:14 ` [PATCH 06/19] c/r: create syscalls: sys_checkpoint, sys_restart Dan Smith
2010-12-14 16:14 ` Dan Smith
2010-12-14 16:14 ` [PATCH 07/19] c/r: basic infrastructure for checkpoint/restart Dan Smith
2010-12-14 16:15 ` [PATCH 12/19] c/r: introduce vfs_fcntl() Dan Smith
2010-12-14 16:15 ` [PATCH 13/19] c/r: introduce new 'file_operations': ->checkpoint, ->collect() Dan Smith
2010-12-14 16:15 ` [PATCH 14/19] c/r: checkpoint and restart open file descriptors Dan Smith
2010-12-14 16:15 ` [PATCH 15/19] c/r: introduce method '->checkpoint()' in struct vm_operations_struct Dan Smith
2010-12-14 16:15 ` [PATCH 16/19] Introduce FOLL_DIRTY to follow_page() for "dirty" pages Dan Smith
2010-12-14 16:15 ` [PATCH 17/19] c/r: dump memory address space (private memory) Dan Smith
2010-12-14 16:15 ` [PATCH 18/19] c/r: add generic '->checkpoint' f_op to ext fses Dan Smith
2010-12-14 16:51 ` Dan Smith
2010-12-14 16:15 ` [PATCH 19/19] c/r: add generic '->checkpoint()' f_op to simple devices Dan Smith
2010-12-14 16:23 ` [PATCH 01/19] c/r: extend arch_setup_additional_pages() Dan Smith
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1292343307-7870-4-git-send-email-danms@us.ibm.com \
--to=danms@us.ibm.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=orenl@cs.columbia.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.