diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-07-05 20:06:38 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-07-22 17:15:53 -0400 |
commit | 2b83d3de4c18af49800e0b26ae013db4fcf43a4a (patch) | |
tree | b713bc1f4e0bd37ef74f05f131feac0a1f0f2845 /fs/nfs/write.c | |
parent | 3c38cbe2ade88240fabb585b408f779ad3b9a31b (diff) |
NFSv4/pnfs: Ensure we don't miss a file extension
pNFS writes don't return attributes, however that doesn't mean that we
should ignore the fact that they may be extending the file. This patch
ensures that if a write is seen to extend the file, then we always set
an attribute barrier, and update the cached file size.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 359e9ad596c9..0e6a2b8786b4 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -1378,24 +1378,27 @@ static void nfs_writeback_check_extend(struct nfs_pgio_header *hdr, | |||
1378 | { | 1378 | { |
1379 | struct nfs_pgio_args *argp = &hdr->args; | 1379 | struct nfs_pgio_args *argp = &hdr->args; |
1380 | struct nfs_pgio_res *resp = &hdr->res; | 1380 | struct nfs_pgio_res *resp = &hdr->res; |
1381 | u64 size = argp->offset + resp->count; | ||
1381 | 1382 | ||
1382 | if (!(fattr->valid & NFS_ATTR_FATTR_SIZE)) | 1383 | if (!(fattr->valid & NFS_ATTR_FATTR_SIZE)) |
1384 | fattr->size = size; | ||
1385 | if (nfs_size_to_loff_t(fattr->size) < i_size_read(hdr->inode)) { | ||
1386 | fattr->valid &= ~NFS_ATTR_FATTR_SIZE; | ||
1383 | return; | 1387 | return; |
1384 | if (argp->offset + resp->count != fattr->size) | 1388 | } |
1385 | return; | 1389 | if (size != fattr->size) |
1386 | if (nfs_size_to_loff_t(fattr->size) < i_size_read(hdr->inode)) | ||
1387 | return; | 1390 | return; |
1388 | /* Set attribute barrier */ | 1391 | /* Set attribute barrier */ |
1389 | nfs_fattr_set_barrier(fattr); | 1392 | nfs_fattr_set_barrier(fattr); |
1393 | /* ...and update size */ | ||
1394 | fattr->valid |= NFS_ATTR_FATTR_SIZE; | ||
1390 | } | 1395 | } |
1391 | 1396 | ||
1392 | void nfs_writeback_update_inode(struct nfs_pgio_header *hdr) | 1397 | void nfs_writeback_update_inode(struct nfs_pgio_header *hdr) |
1393 | { | 1398 | { |
1394 | struct nfs_fattr *fattr = hdr->res.fattr; | 1399 | struct nfs_fattr *fattr = &hdr->fattr; |
1395 | struct inode *inode = hdr->inode; | 1400 | struct inode *inode = hdr->inode; |
1396 | 1401 | ||
1397 | if (fattr == NULL) | ||
1398 | return; | ||
1399 | spin_lock(&inode->i_lock); | 1402 | spin_lock(&inode->i_lock); |
1400 | nfs_writeback_check_extend(hdr, fattr); | 1403 | nfs_writeback_check_extend(hdr, fattr); |
1401 | nfs_post_op_update_inode_force_wcc_locked(inode, fattr); | 1404 | nfs_post_op_update_inode_force_wcc_locked(inode, fattr); |