aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Van Hensbergen <ericvh@gmail.com>2008-10-13 21:36:16 -0400
committerEric Van Hensbergen <ericvh@gmail.com>2008-10-17 12:04:43 -0400
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 4d6d7657fb75..3fd28bbafc87 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -205,19 +205,38 @@ static ssize_t
205v9fs_file_write(struct file *filp, const char __user * data, 205v9fs_file_write(struct file *filp, const char __user * data,
206 size_t count, loff_t * offset) 206 size_t count, loff_t * offset)
207{ 207{
208 int ret; 208 int n, rsize, total = 0;
209 struct p9_fid *fid; 209 struct p9_fid *fid;
210 struct p9_client *clnt;
210 struct inode *inode = filp->f_path.dentry->d_inode; 211 struct inode *inode = filp->f_path.dentry->d_inode;
212 int origin = *offset;
211 213
212 P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data, 214 P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data,
213 (int)count, (int)*offset); 215 (int)count, (int)*offset);
214 216
215 fid = filp->private_data; 217 fid = filp->private_data;
216 ret = p9_client_write(fid, NULL, data, *offset, count); 218 clnt = fid->clnt;
217 if (ret > 0) { 219
218 invalidate_inode_pages2_range(inode->i_mapping, *offset, 220 rsize = fid->iounit;
219 *offset+ret); 221 if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
220 *offset += ret; 222 rsize = clnt->msize - P9_IOHDRSZ;
223
224 do {
225 if (count < rsize)
226 rsize = count;
227
228 n = p9_client_write(fid, NULL, data+total, *offset+total,
229 rsize);
230 if (n <= 0)
231 break;
232 count -= n;
233 total += n;
234 } while (count > 0);
235
236 if (total > 0) {
237 invalidate_inode_pages2_range(inode->i_mapping, origin,
238 origin+total);
239 *offset += total;
221 } 240 }
222 241
223 if (*offset > inode->i_size) { 242 if (*offset > inode->i_size) {
@@ -225,7 +244,10 @@ v9fs_file_write(struct file *filp, const char __user * data,
225 inode->i_blocks = (inode->i_size + 512 - 1) >> 9; 244 inode->i_blocks = (inode->i_size + 512 - 1) >> 9;
226 } 245 }
227 246
228 return ret; 247 if (n < 0)
248 return n;
249
250 return total;
229} 251}
230 252
231static const struct file_operations v9fs_cached_file_operations = { 253static const struct file_operations v9fs_cached_file_operations = {