aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Van Hensbergen <ericvh@gmail.com>2008-10-13 20:36:16 -0500
committerEric Van Hensbergen <ericvh@gmail.com>2008-10-17 11:04:43 -0500
commitdfb0ec2e13a906ff19a0bbfa9208caab50cfc2e3 (patch)
treec08a73d0da715aa0c2aa47653edfe055dff5c454
parentfbedadc16e5c888e4df9df3b1757de4993508d35 (diff)
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 <ericvh@gmail.com>
-rw-r--r--fs/9p/vfs_file.c36
1 files changed, 29 insertions, 7 deletions
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 = {