linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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


       reply	other threads:[~2010-12-14 16:24 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1292343307-7870-1-git-send-email-danms@us.ibm.com>
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 ` [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 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:15 ` [PATCH 19/19] c/r: add generic '->checkpoint()' f_op to simple devices 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).