diff options
| author | Abhishek Kulkarni <adkulkar@umail.iu.edu> | 2009-09-22 12:34:05 -0400 |
|---|---|---|
| committer | Eric Van Hensbergen <ericvh@strongmad.austin.ibm.com> | 2009-09-23 14:03:46 -0400 |
| commit | 637d020a02cd734bf27acfc56c6d942cddd9eb80 (patch) | |
| tree | cff971ce538a12c1d0b315772c733bc91b1913a6 | |
| parent | 7549ae3e81cc45908cbeee54a52b24f247fb0a2d (diff) | |
9p: Fix the incorrect update of inode size in v9fs_file_write()
When using the cache=loose flags, the inode's size was not being
updated correctly on a remote write. Thus subsequent reads of
the whole file resulted in a truncated read. Fix it.
Signed-off-by: Abhishek Kulkarni <adkulkar@umail.iu.edu>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
| -rw-r--r-- | fs/9p/vfs_file.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index de7690eec4d8..cafaa46434ba 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/string.h> | 32 | #include <linux/string.h> |
| 33 | #include <linux/inet.h> | 33 | #include <linux/inet.h> |
| 34 | #include <linux/list.h> | 34 | #include <linux/list.h> |
| 35 | #include <linux/pagemap.h> | ||
| 35 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
| 36 | #include <linux/idr.h> | 37 | #include <linux/idr.h> |
| 37 | #include <net/9p/9p.h> | 38 | #include <net/9p/9p.h> |
| @@ -210,6 +211,7 @@ v9fs_file_write(struct file *filp, const char __user * data, | |||
| 210 | struct p9_client *clnt; | 211 | struct p9_client *clnt; |
| 211 | struct inode *inode = filp->f_path.dentry->d_inode; | 212 | struct inode *inode = filp->f_path.dentry->d_inode; |
| 212 | int origin = *offset; | 213 | int origin = *offset; |
| 214 | unsigned long pg_start, pg_end; | ||
| 213 | 215 | ||
| 214 | P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data, | 216 | P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data, |
| 215 | (int)count, (int)*offset); | 217 | (int)count, (int)*offset); |
| @@ -225,7 +227,7 @@ v9fs_file_write(struct file *filp, const char __user * data, | |||
| 225 | if (count < rsize) | 227 | if (count < rsize) |
| 226 | rsize = count; | 228 | rsize = count; |
| 227 | 229 | ||
| 228 | n = p9_client_write(fid, NULL, data+total, *offset+total, | 230 | n = p9_client_write(fid, NULL, data+total, origin+total, |
| 229 | rsize); | 231 | rsize); |
| 230 | if (n <= 0) | 232 | if (n <= 0) |
| 231 | break; | 233 | break; |
| @@ -234,13 +236,12 @@ v9fs_file_write(struct file *filp, const char __user * data, | |||
| 234 | } while (count > 0); | 236 | } while (count > 0); |
| 235 | 237 | ||
| 236 | if (total > 0) { | 238 | if (total > 0) { |
| 237 | invalidate_inode_pages2_range(inode->i_mapping, origin, | 239 | pg_start = origin >> PAGE_CACHE_SHIFT; |
| 238 | origin+total); | 240 | pg_end = (origin + total - 1) >> PAGE_CACHE_SHIFT; |
| 241 | invalidate_inode_pages2_range(inode->i_mapping, pg_start, | ||
| 242 | pg_end); | ||
| 239 | *offset += total; | 243 | *offset += total; |
| 240 | } | 244 | i_size_write(inode, i_size_read(inode) + total); |
| 241 | |||
| 242 | if (*offset > i_size_read(inode)) { | ||
| 243 | i_size_write(inode, *offset); | ||
| 244 | inode->i_blocks = (i_size_read(inode) + 512 - 1) >> 9; | 245 | inode->i_blocks = (i_size_read(inode) + 512 - 1) >> 9; |
| 245 | } | 246 | } |
| 246 | 247 | ||
