aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeng Tao <bergwolf@gmail.com>2010-10-16 22:07:46 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2011-07-08 23:15:13 -0700
commit712283fb329cf8ff02e72f2f70cf735f01f7c040 (patch)
treead5183fabbf3f2d92f2852d2e27c7a5a6e26f28b
parentd1229b3c4d52210b6ee09902b5a705c6509eeb1a (diff)
NFS41: do not update isize if inode needs layoutcommit
commit 0f66b5984df2fe1617c05900a39a7ef493ca9de9 upstream. nfs_update_inode will update isize if there is no queued pages. For pNFS, layoutcommit is supposed to change file size on server, the same effect as queued pages. nfs_update_inode may be called when dirty pages are written back (nfsi->npages==0) but layoutcommit is not sent, and it will change client file size according to server file size. Then client ends up losing what it just writes back in pNFS path. So we should skip updating client file size if file needs layoutcommit. Signed-off-by: Peng Tao <peng_tao@emc.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--fs/nfs/inode.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 57bb31ad7a5..4e0ddb3ac41 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1294,7 +1294,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
if (new_isize != cur_isize) {
/* Do we perhaps have any outstanding writes, or has
* the file grown beyond our last write? */
- if (nfsi->npages == 0 || new_isize > cur_isize) {
+ if ((nfsi->npages == 0 && !test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) ||
+ new_isize > cur_isize) {
i_size_write(inode, new_isize);
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
}