From 0fc9655ec67ec5d4dfd08e469e0e9f0a494bf5bc Mon Sep 17 00:00:00 2001 From: Eric Van Hensbergen Date: Mon, 13 Oct 2008 20:36:17 -0500 Subject: 9p: consolidate read/write functions Currently there are two separate versions of read and write. One for dealing with user buffers and the other for dealing with kernel buffers. There is a tremendous amount of code duplication in the otherwise identical versions of these functions. This patch adds an additional user buffer parameter to read and write and conditionalizes handling of the buffer on whether the kernel buffer or the user buffer is populated. Signed-off-by: Eric Van Hensbergen --- fs/9p/vfs_file.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/9p/vfs_file.c') diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 52944d2249a..3819a195de8 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -136,7 +136,7 @@ v9fs_file_read(struct file *filp, char __user * data, size_t count, P9_DPRINTK(P9_DEBUG_VFS, "\n"); fid = filp->private_data; - ret = p9_client_uread(fid, data, *offset, count); + ret = p9_client_read(fid, NULL, data, *offset, count); if (ret > 0) *offset += ret; @@ -164,7 +164,7 @@ v9fs_file_write(struct file *filp, const char __user * data, (int)count, (int)*offset); fid = filp->private_data; - ret = p9_client_uwrite(fid, data, *offset, count); + ret = p9_client_write(fid, NULL, data, *offset, count); if (ret > 0) { invalidate_inode_pages2_range(inode->i_mapping, *offset, *offset+ret); -- cgit v1.2.3 From fbedadc16e5c888e4df9df3b1757de4993508d35 Mon Sep 17 00:00:00 2001 From: Eric Van Hensbergen Date: Mon, 13 Oct 2008 20:36:16 -0500 Subject: 9p: move readn meta-function from client to fs layer There are a couple of methods in the client code which aren't actually wire operations. To keep things organized cleaner, these operations are being moved to the fs layer. This patch moves the readn meta-function (which executes multiple wire reads until a buffer is full) to the fs layer. Signed-off-by: Eric Van Hensbergen --- fs/9p/vfs_file.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) (limited to 'fs/9p/vfs_file.c') diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 3819a195de8..4d6d7657fb7 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -120,23 +120,72 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl) } /** - * v9fs_file_read - read from a file + * v9fs_file_readn - read from a file * @filp: file pointer to read * @data: data buffer to read data into + * @udata: user data buffer to read data into * @count: size of buffer * @offset: offset at which to read data * */ + +ssize_t +v9fs_file_readn(struct file *filp, char *data, char __user *udata, u32 count, + u64 offset) +{ + int n, total; + struct p9_fid *fid = filp->private_data; + + P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid, + (long long unsigned) offset, count); + + n = 0; + total = 0; + do { + n = p9_client_read(fid, data, udata, offset, count); + if (n <= 0) + break; + + if (data) + data += n; + if (udata) + udata += n; + + offset += n; + count -= n; + total += n; + } while (count > 0 && n == (fid->clnt->msize - P9_IOHDRSZ)); + + if (n < 0) + total = n; + + return total; +} + +/** + * v9fs_file_read - read from a file + * @filp: file pointer to read + * @udata: user data buffer to read data into + * @count: size of buffer + * @offset: offset at which to read data + * + */ + static ssize_t -v9fs_file_read(struct file *filp, char __user * data, size_t count, +v9fs_file_read(struct file *filp, char __user *udata, size_t count, loff_t * offset) { int ret; struct p9_fid *fid; - P9_DPRINTK(P9_DEBUG_VFS, "\n"); + P9_DPRINTK(P9_DEBUG_VFS, "count %d offset %lld\n", count, *offset); fid = filp->private_data; - ret = p9_client_read(fid, NULL, data, *offset, count); + + if (count > (fid->clnt->msize - P9_IOHDRSZ)) + ret = v9fs_file_readn(filp, NULL, udata, count, *offset); + else + ret = p9_client_read(fid, NULL, udata, *offset, count); + if (ret > 0) *offset += ret; -- cgit v1.2.3 From dfb0ec2e13a906ff19a0bbfa9208caab50cfc2e3 Mon Sep 17 00:00:00 2001 From: Eric Van Hensbergen Date: Mon, 13 Oct 2008 20:36:16 -0500 Subject: 9p: adjust 9p vfs write operation Currently, the 9p net wire operation ensures that all data is sent by sending multiple packets if the data requested is larger than the msize. This is better handled in the vfs code so that we can simplify wire operations to being concerned with only putting data onto and taking data off of the wire. Signed-off-by: Eric Van Hensbergen --- fs/9p/vfs_file.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) (limited to 'fs/9p/vfs_file.c') diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 4d6d7657fb7..3fd28bbafc8 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -205,19 +205,38 @@ static ssize_t v9fs_file_write(struct file *filp, const char __user * data, size_t count, loff_t * offset) { - int ret; + int n, rsize, total = 0; struct p9_fid *fid; + struct p9_client *clnt; struct inode *inode = filp->f_path.dentry->d_inode; + int origin = *offset; P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data, (int)count, (int)*offset); fid = filp->private_data; - ret = p9_client_write(fid, NULL, data, *offset, count); - if (ret > 0) { - invalidate_inode_pages2_range(inode->i_mapping, *offset, - *offset+ret); - *offset += ret; + clnt = fid->clnt; + + rsize = fid->iounit; + if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) + rsize = clnt->msize - P9_IOHDRSZ; + + do { + if (count < rsize) + rsize = count; + + n = p9_client_write(fid, NULL, data+total, *offset+total, + rsize); + if (n <= 0) + break; + count -= n; + total += n; + } while (count > 0); + + if (total > 0) { + invalidate_inode_pages2_range(inode->i_mapping, origin, + origin+total); + *offset += total; } if (*offset > inode->i_size) { @@ -225,7 +244,10 @@ v9fs_file_write(struct file *filp, const char __user * data, inode->i_blocks = (inode->i_size + 512 - 1) >> 9; } - return ret; + if (n < 0) + return n; + + return total; } static const struct file_operations v9fs_cached_file_operations = { -- cgit v1.2.3 From 51a87c552dfd428e304c865e24ecbe091556f226 Mon Sep 17 00:00:00 2001 From: Eric Van Hensbergen Date: Thu, 16 Oct 2008 08:30:07 -0500 Subject: 9p: rework client code to use new protocol support functions Now that the new protocol functions are in place, this patch switches the client code to using the new support code. Signed-off-by: Eric Van Hensbergen --- fs/9p/vfs_file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/9p/vfs_file.c') diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 3fd28bbafc8..041c5269228 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -136,7 +136,7 @@ v9fs_file_readn(struct file *filp, char *data, char __user *udata, u32 count, int n, total; struct p9_fid *fid = filp->private_data; - P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid, + P9_DPRINTK(P9_DEBUG_VFS, "fid %d offset %llu count %d\n", fid->fid, (long long unsigned) offset, count); n = 0; -- cgit v1.2.3