aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2012-01-27 16:49:55 -0500
committerJ. Bruce Fields <bfields@redhat.com>2012-03-06 18:13:37 -0500
commit59deeb9e5a2b535b95327c0d29bb3c2c4c3e8234 (patch)
treedf61459adb758aef2d1cf4da812ad0f750412bbd /fs/nfsd
parent41fd1e42f861e50e49f3d44127596344f2505f01 (diff)
nfsd4: reduce do_open_lookup() stack usage
I get 320 bytes for struct svc_fh on x86_64, really a little large to be putting on the stack; kmalloc() instead. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4proc.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index bdb71a57c94e..abe808a52d97 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -193,10 +193,13 @@ static __be32 nfsd_check_obj_isreg(struct svc_fh *fh)
193static __be32 193static __be32
194do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) 194do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
195{ 195{
196 struct svc_fh resfh; 196 struct svc_fh *resfh;
197 __be32 status; 197 __be32 status;
198 198
199 fh_init(&resfh, NFS4_FHSIZE); 199 resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
200 if (!resfh)
201 return nfserr_jukebox;
202 fh_init(resfh, NFS4_FHSIZE);
200 open->op_truncate = 0; 203 open->op_truncate = 0;
201 204
202 if (open->op_create) { 205 if (open->op_create) {
@@ -221,7 +224,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
221 */ 224 */
222 status = do_nfsd_create(rqstp, current_fh, open->op_fname.data, 225 status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
223 open->op_fname.len, &open->op_iattr, 226 open->op_fname.len, &open->op_iattr,
224 &resfh, open->op_createmode, 227 resfh, open->op_createmode,
225 (u32 *)open->op_verf.data, 228 (u32 *)open->op_verf.data,
226 &open->op_truncate, &open->op_created); 229 &open->op_truncate, &open->op_created);
227 230
@@ -235,28 +238,29 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
235 FATTR4_WORD1_TIME_MODIFY); 238 FATTR4_WORD1_TIME_MODIFY);
236 } else { 239 } else {
237 status = nfsd_lookup(rqstp, current_fh, 240 status = nfsd_lookup(rqstp, current_fh,
238 open->op_fname.data, open->op_fname.len, &resfh); 241 open->op_fname.data, open->op_fname.len, resfh);
239 fh_unlock(current_fh); 242 fh_unlock(current_fh);
240 if (status) 243 if (status)
241 goto out; 244 goto out;
242 status = nfsd_check_obj_isreg(&resfh); 245 status = nfsd_check_obj_isreg(resfh);
243 } 246 }
244 if (status) 247 if (status)
245 goto out; 248 goto out;
246 249
247 if (is_create_with_attrs(open) && open->op_acl != NULL) 250 if (is_create_with_attrs(open) && open->op_acl != NULL)
248 do_set_nfs4_acl(rqstp, &resfh, open->op_acl, open->op_bmval); 251 do_set_nfs4_acl(rqstp, resfh, open->op_acl, open->op_bmval);
249 252
250 /* set reply cache */ 253 /* set reply cache */
251 fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh, 254 fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh,
252 &resfh.fh_handle); 255 &resfh->fh_handle);
253 if (!open->op_created) 256 if (!open->op_created)
254 status = do_open_permission(rqstp, &resfh, open, 257 status = do_open_permission(rqstp, resfh, open,
255 NFSD_MAY_NOP); 258 NFSD_MAY_NOP);
256 set_change_info(&open->op_cinfo, current_fh); 259 set_change_info(&open->op_cinfo, current_fh);
257 fh_dup2(current_fh, &resfh); 260 fh_dup2(current_fh, resfh);
258out: 261out:
259 fh_put(&resfh); 262 fh_put(resfh);
263 kfree(resfh);
260 return status; 264 return status;
261} 265}
262 266