aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
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
parent8c18d76bcba874e872410ca63c7e59b10aafa17d (diff)
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')
-rw-r--r--fs/nfs/inode.c1
-rw-r--r--fs/nfs/nfs42proc.c23
-rw-r--r--fs/nfs/nfs42xdr.c20
-rw-r--r--fs/nfs/nfs4file.c1
4 files changed, 35 insertions, 10 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 0c3be2658546..83743a133204 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -199,7 +199,6 @@ void nfs_zap_caches(struct inode *inode)
199 nfs_zap_caches_locked(inode); 199 nfs_zap_caches_locked(inode);
200 spin_unlock(&inode->i_lock); 200 spin_unlock(&inode->i_lock);
201} 201}
202EXPORT_SYMBOL_GPL(nfs_zap_caches);
203 202
204void nfs_zap_mapping(struct inode *inode, struct address_space *mapping) 203void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
205{ 204{
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,
36 loff_t offset, loff_t len) 36 loff_t offset, loff_t len)
37{ 37{
38 struct inode *inode = file_inode(filep); 38 struct inode *inode = file_inode(filep);
39 struct nfs_server *server = NFS_SERVER(inode);
39 struct nfs42_falloc_args args = { 40 struct nfs42_falloc_args args = {
40 .falloc_fh = NFS_FH(inode), 41 .falloc_fh = NFS_FH(inode),
41 .falloc_offset = offset, 42 .falloc_offset = offset,
42 .falloc_length = len, 43 .falloc_length = len,
44 .falloc_bitmask = server->cache_consistency_bitmask,
45 };
46 struct nfs42_falloc_res res = {
47 .falloc_server = server,
43 }; 48 };
44 struct nfs42_falloc_res res;
45 struct nfs_server *server = NFS_SERVER(inode);
46 int status; 49 int status;
47 50
48 msg->rpc_argp = &args; 51 msg->rpc_argp = &args;
@@ -52,8 +55,17 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
52 if (status) 55 if (status)
53 return status; 56 return status;
54 57
55 return nfs4_call_sync(server->client, server, msg, 58 res.falloc_fattr = nfs_alloc_fattr();
56 &args.seq_args, &res.seq_res, 0); 59 if (!res.falloc_fattr)
60 return -ENOMEM;
61
62 status = nfs4_call_sync(server->client, server, msg,
63 &args.seq_args, &res.seq_res, 0);
64 if (status == 0)
65 status = nfs_post_op_update_inode(inode, res.falloc_fattr);
66
67 kfree(res.falloc_fattr);
68 return status;
57} 69}
58 70
59static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, 71static 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)
101 if (!nfs_server_capable(inode, NFS_CAP_DEALLOCATE)) 113 if (!nfs_server_capable(inode, NFS_CAP_DEALLOCATE))
102 return -EOPNOTSUPP; 114 return -EOPNOTSUPP;
103 115
116 nfs_wb_all(inode);
104 err = nfs42_proc_fallocate(&msg, filep, offset, len); 117 err = nfs42_proc_fallocate(&msg, filep, offset, len);
118 if (err == 0)
119 truncate_pagecache_range(inode, offset, (offset + len) -1);
105 if (err == -EOPNOTSUPP) 120 if (err == -EOPNOTSUPP)
106 NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE; 121 NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE;
107 return err; 122 return err;
diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c
index 038a7e1521fa..1a25b27248f2 100644
--- a/fs/nfs/nfs42xdr.c
+++ b/fs/nfs/nfs42xdr.c
@@ -25,16 +25,20 @@
25 25
26#define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \ 26#define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \
27 encode_putfh_maxsz + \ 27 encode_putfh_maxsz + \
28 encode_allocate_maxsz) 28 encode_allocate_maxsz + \
29 encode_getattr_maxsz)
29#define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \ 30#define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
30 decode_putfh_maxsz + \ 31 decode_putfh_maxsz + \
31 decode_allocate_maxsz) 32 decode_allocate_maxsz + \
33 decode_getattr_maxsz)
32#define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \ 34#define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
33 encode_putfh_maxsz + \ 35 encode_putfh_maxsz + \
34 encode_deallocate_maxsz) 36 encode_deallocate_maxsz + \
37 encode_getattr_maxsz)
35#define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \ 38#define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \
36 decode_putfh_maxsz + \ 39 decode_putfh_maxsz + \
37 decode_deallocate_maxsz) 40 decode_deallocate_maxsz + \
41 decode_getattr_maxsz)
38#define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \ 42#define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \
39 encode_putfh_maxsz + \ 43 encode_putfh_maxsz + \
40 encode_seek_maxsz) 44 encode_seek_maxsz)
@@ -92,6 +96,7 @@ static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
92 encode_sequence(xdr, &args->seq_args, &hdr); 96 encode_sequence(xdr, &args->seq_args, &hdr);
93 encode_putfh(xdr, args->falloc_fh, &hdr); 97 encode_putfh(xdr, args->falloc_fh, &hdr);
94 encode_allocate(xdr, args, &hdr); 98 encode_allocate(xdr, args, &hdr);
99 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
95 encode_nops(&hdr); 100 encode_nops(&hdr);
96} 101}
97 102
@@ -110,6 +115,7 @@ static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
110 encode_sequence(xdr, &args->seq_args, &hdr); 115 encode_sequence(xdr, &args->seq_args, &hdr);
111 encode_putfh(xdr, args->falloc_fh, &hdr); 116 encode_putfh(xdr, args->falloc_fh, &hdr);
112 encode_deallocate(xdr, args, &hdr); 117 encode_deallocate(xdr, args, &hdr);
118 encode_getfattr(xdr, args->falloc_bitmask, &hdr);
113 encode_nops(&hdr); 119 encode_nops(&hdr);
114} 120}
115 121
@@ -183,6 +189,9 @@ static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
183 if (status) 189 if (status)
184 goto out; 190 goto out;
185 status = decode_allocate(xdr, res); 191 status = decode_allocate(xdr, res);
192 if (status)
193 goto out;
194 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
186out: 195out:
187 return status; 196 return status;
188} 197}
@@ -207,6 +216,9 @@ static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
207 if (status) 216 if (status)
208 goto out; 217 goto out;
209 status = decode_deallocate(xdr, res); 218 status = decode_deallocate(xdr, res);
219 if (status)
220 goto out;
221 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
210out: 222out:
211 return status; 223 return status;
212} 224}
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index 866842b048ef..151ddff624d4 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -165,7 +165,6 @@ static long nfs42_fallocate(struct file *filep, int mode, loff_t offset, loff_t
165 ret = nfs42_proc_allocate(filep, offset, len); 165 ret = nfs42_proc_allocate(filep, offset, len);
166 mutex_unlock(&inode->i_mutex); 166 mutex_unlock(&inode->i_mutex);
167 167
168 nfs_zap_caches(inode);
169 return ret; 168 return ret;
170} 169}
171#endif /* CONFIG_NFS_V4_2 */ 170#endif /* CONFIG_NFS_V4_2 */