summaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs42proc.c
diff options
context:
space:
mode:
authorAnna Schumaker <Anna.Schumaker@netapp.com>2015-03-16 14:06:23 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-04-23 14:36:28 -0400
commit9a51940bf65bf9fdc93027d70bdecdfc403c5b24 (patch)
tree2b5a6788cebb2ed1a02d398d929d5a78572bec46 /fs/nfs/nfs42proc.c
parent8c18d76bcba874e872410ca63c7e59b10aafa17d (diff)
downloadlinux-9a51940bf65bf9fdc93027d70bdecdfc403c5b24.tar.bz2
NFS: Don't zap caches on fallocate()
This patch adds a GETATTR to the end of ALLOCATE and DEALLOCATE operations so we can set the updated inode size and change attribute directly. DEALLOCATE will still need to release pagecache pages, so nfs42_proc_deallocate() now calls truncate_pagecache_range() before contacting the server. Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/nfs42proc.c')
-rw-r--r--fs/nfs/nfs42proc.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
index cb170722769c..b9aa6bbcc8ed 100644
--- a/fs/nfs/nfs42proc.c
+++ b/fs/nfs/nfs42proc.c
@@ -36,13 +36,16 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
loff_t offset, loff_t len)
{
struct inode *inode = file_inode(filep);
+ struct nfs_server *server = NFS_SERVER(inode);
struct nfs42_falloc_args args = {
.falloc_fh = NFS_FH(inode),
.falloc_offset = offset,
.falloc_length = len,
+ .falloc_bitmask = server->cache_consistency_bitmask,
+ };
+ struct nfs42_falloc_res res = {
+ .falloc_server = server,
};
- struct nfs42_falloc_res res;
- struct nfs_server *server = NFS_SERVER(inode);
int status;
msg->rpc_argp = &args;
@@ -52,8 +55,17 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
if (status)
return status;
- return nfs4_call_sync(server->client, server, msg,
- &args.seq_args, &res.seq_res, 0);
+ res.falloc_fattr = nfs_alloc_fattr();
+ if (!res.falloc_fattr)
+ return -ENOMEM;
+
+ status = nfs4_call_sync(server->client, server, msg,
+ &args.seq_args, &res.seq_res, 0);
+ if (status == 0)
+ status = nfs_post_op_update_inode(inode, res.falloc_fattr);
+
+ kfree(res.falloc_fattr);
+ return status;
}
static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
@@ -101,7 +113,10 @@ int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len)
if (!nfs_server_capable(inode, NFS_CAP_DEALLOCATE))
return -EOPNOTSUPP;
+ nfs_wb_all(inode);
err = nfs42_proc_fallocate(&msg, filep, offset, len);
+ if (err == 0)
+ truncate_pagecache_range(inode, offset, (offset + len) -1);
if (err == -EOPNOTSUPP)
NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE;
return err;