diff options
author | J.Bruce Fields <bfields@fieldses.org> | 2006-12-13 03:35:27 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-13 12:05:54 -0500 |
commit | ca3643171bc6e08b7c4d1f9a2ce659541a01a7fe (patch) | |
tree | 2128accc9584e7dd69f6b62c62ef6631f5da231f /fs/nfsd/nfs4proc.c | |
parent | 01f3bd1f03599470e4695392b6ae055ed8506978 (diff) |
[PATCH] knfsd: nfsd4: pass saved and current fh together into nfsd4 operations
Pass the saved and current filehandles together into all the nfsd4 compound
operations.
I want a unified interface to these operations so we can just call them by
pointer and throw out the huge switch statement.
Also I'll eventually want a structure like this--that holds the state used
during compound processing--for deferral.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/nfsd/nfs4proc.c')
-rw-r--r-- | fs/nfsd/nfs4proc.c | 348 |
1 files changed, 203 insertions, 145 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 793a0b0a6cdd..1b6756aa013c 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -162,7 +162,8 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ | |||
162 | 162 | ||
163 | 163 | ||
164 | static inline __be32 | 164 | static inline __be32 |
165 | nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, struct nfs4_stateowner **replay_owner) | 165 | nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
166 | struct nfsd4_open *open, struct nfs4_stateowner **replay_owner) | ||
166 | { | 167 | { |
167 | __be32 status; | 168 | __be32 status; |
168 | dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n", | 169 | dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n", |
@@ -179,11 +180,11 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open | |||
179 | status = nfsd4_process_open1(open); | 180 | status = nfsd4_process_open1(open); |
180 | if (status == nfserr_replay_me) { | 181 | if (status == nfserr_replay_me) { |
181 | struct nfs4_replay *rp = &open->op_stateowner->so_replay; | 182 | struct nfs4_replay *rp = &open->op_stateowner->so_replay; |
182 | fh_put(current_fh); | 183 | fh_put(&cstate->current_fh); |
183 | current_fh->fh_handle.fh_size = rp->rp_openfh_len; | 184 | cstate->current_fh.fh_handle.fh_size = rp->rp_openfh_len; |
184 | memcpy(¤t_fh->fh_handle.fh_base, rp->rp_openfh, | 185 | memcpy(&cstate->current_fh.fh_handle.fh_base, rp->rp_openfh, |
185 | rp->rp_openfh_len); | 186 | rp->rp_openfh_len); |
186 | status = fh_verify(rqstp, current_fh, 0, MAY_NOP); | 187 | status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); |
187 | if (status) | 188 | if (status) |
188 | dprintk("nfsd4_open: replay failed" | 189 | dprintk("nfsd4_open: replay failed" |
189 | " restoring previous filehandle\n"); | 190 | " restoring previous filehandle\n"); |
@@ -215,7 +216,8 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open | |||
215 | * (3) set open->op_truncate if the file is to be | 216 | * (3) set open->op_truncate if the file is to be |
216 | * truncated after opening, (4) do permission checking. | 217 | * truncated after opening, (4) do permission checking. |
217 | */ | 218 | */ |
218 | status = do_open_lookup(rqstp, current_fh, open); | 219 | status = do_open_lookup(rqstp, &cstate->current_fh, |
220 | open); | ||
219 | if (status) | 221 | if (status) |
220 | goto out; | 222 | goto out; |
221 | break; | 223 | break; |
@@ -227,7 +229,8 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open | |||
227 | * open->op_truncate if the file is to be truncated | 229 | * open->op_truncate if the file is to be truncated |
228 | * after opening, (3) do permission checking. | 230 | * after opening, (3) do permission checking. |
229 | */ | 231 | */ |
230 | status = do_open_fhandle(rqstp, current_fh, open); | 232 | status = do_open_fhandle(rqstp, &cstate->current_fh, |
233 | open); | ||
231 | if (status) | 234 | if (status) |
232 | goto out; | 235 | goto out; |
233 | break; | 236 | break; |
@@ -248,7 +251,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open | |||
248 | * successful, it (1) truncates the file if open->op_truncate was | 251 | * successful, it (1) truncates the file if open->op_truncate was |
249 | * set, (2) sets open->op_stateid, (3) sets open->op_delegation. | 252 | * set, (2) sets open->op_stateid, (3) sets open->op_delegation. |
250 | */ | 253 | */ |
251 | status = nfsd4_process_open2(rqstp, current_fh, open); | 254 | status = nfsd4_process_open2(rqstp, &cstate->current_fh, open); |
252 | out: | 255 | out: |
253 | if (open->op_stateowner) { | 256 | if (open->op_stateowner) { |
254 | nfs4_get_stateowner(open->op_stateowner); | 257 | nfs4_get_stateowner(open->op_stateowner); |
@@ -262,52 +265,54 @@ out: | |||
262 | * filehandle-manipulating ops. | 265 | * filehandle-manipulating ops. |
263 | */ | 266 | */ |
264 | static inline __be32 | 267 | static inline __be32 |
265 | nfsd4_getfh(struct svc_fh *current_fh, struct svc_fh **getfh) | 268 | nfsd4_getfh(struct nfsd4_compound_state *cstate, struct svc_fh **getfh) |
266 | { | 269 | { |
267 | if (!current_fh->fh_dentry) | 270 | if (!cstate->current_fh.fh_dentry) |
268 | return nfserr_nofilehandle; | 271 | return nfserr_nofilehandle; |
269 | 272 | ||
270 | *getfh = current_fh; | 273 | *getfh = &cstate->current_fh; |
271 | return nfs_ok; | 274 | return nfs_ok; |
272 | } | 275 | } |
273 | 276 | ||
274 | static inline __be32 | 277 | static inline __be32 |
275 | nfsd4_putfh(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_putfh *putfh) | 278 | nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
279 | struct nfsd4_putfh *putfh) | ||
276 | { | 280 | { |
277 | fh_put(current_fh); | 281 | fh_put(&cstate->current_fh); |
278 | current_fh->fh_handle.fh_size = putfh->pf_fhlen; | 282 | cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen; |
279 | memcpy(¤t_fh->fh_handle.fh_base, putfh->pf_fhval, putfh->pf_fhlen); | 283 | memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval, |
280 | return fh_verify(rqstp, current_fh, 0, MAY_NOP); | 284 | putfh->pf_fhlen); |
285 | return fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); | ||
281 | } | 286 | } |
282 | 287 | ||
283 | static inline __be32 | 288 | static inline __be32 |
284 | nfsd4_putrootfh(struct svc_rqst *rqstp, struct svc_fh *current_fh) | 289 | nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate) |
285 | { | 290 | { |
286 | __be32 status; | 291 | __be32 status; |
287 | 292 | ||
288 | fh_put(current_fh); | 293 | fh_put(&cstate->current_fh); |
289 | status = exp_pseudoroot(rqstp->rq_client, current_fh, | 294 | status = exp_pseudoroot(rqstp->rq_client, &cstate->current_fh, |
290 | &rqstp->rq_chandle); | 295 | &rqstp->rq_chandle); |
291 | return status; | 296 | return status; |
292 | } | 297 | } |
293 | 298 | ||
294 | static inline __be32 | 299 | static inline __be32 |
295 | nfsd4_restorefh(struct svc_fh *current_fh, struct svc_fh *save_fh) | 300 | nfsd4_restorefh(struct nfsd4_compound_state *cstate) |
296 | { | 301 | { |
297 | if (!save_fh->fh_dentry) | 302 | if (!cstate->save_fh.fh_dentry) |
298 | return nfserr_restorefh; | 303 | return nfserr_restorefh; |
299 | 304 | ||
300 | fh_dup2(current_fh, save_fh); | 305 | fh_dup2(&cstate->current_fh, &cstate->save_fh); |
301 | return nfs_ok; | 306 | return nfs_ok; |
302 | } | 307 | } |
303 | 308 | ||
304 | static inline __be32 | 309 | static inline __be32 |
305 | nfsd4_savefh(struct svc_fh *current_fh, struct svc_fh *save_fh) | 310 | nfsd4_savefh(struct nfsd4_compound_state *cstate) |
306 | { | 311 | { |
307 | if (!current_fh->fh_dentry) | 312 | if (!cstate->current_fh.fh_dentry) |
308 | return nfserr_nofilehandle; | 313 | return nfserr_nofilehandle; |
309 | 314 | ||
310 | fh_dup2(save_fh, current_fh); | 315 | fh_dup2(&cstate->save_fh, &cstate->current_fh); |
311 | return nfs_ok; | 316 | return nfs_ok; |
312 | } | 317 | } |
313 | 318 | ||
@@ -315,17 +320,20 @@ nfsd4_savefh(struct svc_fh *current_fh, struct svc_fh *save_fh) | |||
315 | * misc nfsv4 ops | 320 | * misc nfsv4 ops |
316 | */ | 321 | */ |
317 | static inline __be32 | 322 | static inline __be32 |
318 | nfsd4_access(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_access *access) | 323 | nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
324 | struct nfsd4_access *access) | ||
319 | { | 325 | { |
320 | if (access->ac_req_access & ~NFS3_ACCESS_FULL) | 326 | if (access->ac_req_access & ~NFS3_ACCESS_FULL) |
321 | return nfserr_inval; | 327 | return nfserr_inval; |
322 | 328 | ||
323 | access->ac_resp_access = access->ac_req_access; | 329 | access->ac_resp_access = access->ac_req_access; |
324 | return nfsd_access(rqstp, current_fh, &access->ac_resp_access, &access->ac_supported); | 330 | return nfsd_access(rqstp, &cstate->current_fh, &access->ac_resp_access, |
331 | &access->ac_supported); | ||
325 | } | 332 | } |
326 | 333 | ||
327 | static inline __be32 | 334 | static inline __be32 |
328 | nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_commit *commit) | 335 | nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
336 | struct nfsd4_commit *commit) | ||
329 | { | 337 | { |
330 | __be32 status; | 338 | __be32 status; |
331 | 339 | ||
@@ -333,14 +341,16 @@ nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_com | |||
333 | *p++ = nfssvc_boot.tv_sec; | 341 | *p++ = nfssvc_boot.tv_sec; |
334 | *p++ = nfssvc_boot.tv_usec; | 342 | *p++ = nfssvc_boot.tv_usec; |
335 | 343 | ||
336 | status = nfsd_commit(rqstp, current_fh, commit->co_offset, commit->co_count); | 344 | status = nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset, |
345 | commit->co_count); | ||
337 | if (status == nfserr_symlink) | 346 | if (status == nfserr_symlink) |
338 | status = nfserr_inval; | 347 | status = nfserr_inval; |
339 | return status; | 348 | return status; |
340 | } | 349 | } |
341 | 350 | ||
342 | static __be32 | 351 | static __be32 |
343 | nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_create *create) | 352 | nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
353 | struct nfsd4_create *create) | ||
344 | { | 354 | { |
345 | struct svc_fh resfh; | 355 | struct svc_fh resfh; |
346 | __be32 status; | 356 | __be32 status; |
@@ -348,7 +358,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre | |||
348 | 358 | ||
349 | fh_init(&resfh, NFS4_FHSIZE); | 359 | fh_init(&resfh, NFS4_FHSIZE); |
350 | 360 | ||
351 | status = fh_verify(rqstp, current_fh, S_IFDIR, MAY_CREATE); | 361 | status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, MAY_CREATE); |
352 | if (status == nfserr_symlink) | 362 | if (status == nfserr_symlink) |
353 | status = nfserr_notdir; | 363 | status = nfserr_notdir; |
354 | if (status) | 364 | if (status) |
@@ -365,9 +375,10 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre | |||
365 | */ | 375 | */ |
366 | create->cr_linkname[create->cr_linklen] = 0; | 376 | create->cr_linkname[create->cr_linklen] = 0; |
367 | 377 | ||
368 | status = nfsd_symlink(rqstp, current_fh, create->cr_name, | 378 | status = nfsd_symlink(rqstp, &cstate->current_fh, |
369 | create->cr_namelen, create->cr_linkname, | 379 | create->cr_name, create->cr_namelen, |
370 | create->cr_linklen, &resfh, &create->cr_iattr); | 380 | create->cr_linkname, create->cr_linklen, |
381 | &resfh, &create->cr_iattr); | ||
371 | break; | 382 | break; |
372 | 383 | ||
373 | case NF4BLK: | 384 | case NF4BLK: |
@@ -375,9 +386,9 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre | |||
375 | if (MAJOR(rdev) != create->cr_specdata1 || | 386 | if (MAJOR(rdev) != create->cr_specdata1 || |
376 | MINOR(rdev) != create->cr_specdata2) | 387 | MINOR(rdev) != create->cr_specdata2) |
377 | return nfserr_inval; | 388 | return nfserr_inval; |
378 | status = nfsd_create(rqstp, current_fh, create->cr_name, | 389 | status = nfsd_create(rqstp, &cstate->current_fh, |
379 | create->cr_namelen, &create->cr_iattr, | 390 | create->cr_name, create->cr_namelen, |
380 | S_IFBLK, rdev, &resfh); | 391 | &create->cr_iattr, S_IFBLK, rdev, &resfh); |
381 | break; | 392 | break; |
382 | 393 | ||
383 | case NF4CHR: | 394 | case NF4CHR: |
@@ -385,28 +396,28 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre | |||
385 | if (MAJOR(rdev) != create->cr_specdata1 || | 396 | if (MAJOR(rdev) != create->cr_specdata1 || |
386 | MINOR(rdev) != create->cr_specdata2) | 397 | MINOR(rdev) != create->cr_specdata2) |
387 | return nfserr_inval; | 398 | return nfserr_inval; |
388 | status = nfsd_create(rqstp, current_fh, create->cr_name, | 399 | status = nfsd_create(rqstp, &cstate->current_fh, |
389 | create->cr_namelen, &create->cr_iattr, | 400 | create->cr_name, create->cr_namelen, |
390 | S_IFCHR, rdev, &resfh); | 401 | &create->cr_iattr,S_IFCHR, rdev, &resfh); |
391 | break; | 402 | break; |
392 | 403 | ||
393 | case NF4SOCK: | 404 | case NF4SOCK: |
394 | status = nfsd_create(rqstp, current_fh, create->cr_name, | 405 | status = nfsd_create(rqstp, &cstate->current_fh, |
395 | create->cr_namelen, &create->cr_iattr, | 406 | create->cr_name, create->cr_namelen, |
396 | S_IFSOCK, 0, &resfh); | 407 | &create->cr_iattr, S_IFSOCK, 0, &resfh); |
397 | break; | 408 | break; |
398 | 409 | ||
399 | case NF4FIFO: | 410 | case NF4FIFO: |
400 | status = nfsd_create(rqstp, current_fh, create->cr_name, | 411 | status = nfsd_create(rqstp, &cstate->current_fh, |
401 | create->cr_namelen, &create->cr_iattr, | 412 | create->cr_name, create->cr_namelen, |
402 | S_IFIFO, 0, &resfh); | 413 | &create->cr_iattr, S_IFIFO, 0, &resfh); |
403 | break; | 414 | break; |
404 | 415 | ||
405 | case NF4DIR: | 416 | case NF4DIR: |
406 | create->cr_iattr.ia_valid &= ~ATTR_SIZE; | 417 | create->cr_iattr.ia_valid &= ~ATTR_SIZE; |
407 | status = nfsd_create(rqstp, current_fh, create->cr_name, | 418 | status = nfsd_create(rqstp, &cstate->current_fh, |
408 | create->cr_namelen, &create->cr_iattr, | 419 | create->cr_name, create->cr_namelen, |
409 | S_IFDIR, 0, &resfh); | 420 | &create->cr_iattr, S_IFDIR, 0, &resfh); |
410 | break; | 421 | break; |
411 | 422 | ||
412 | default: | 423 | default: |
@@ -414,9 +425,9 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre | |||
414 | } | 425 | } |
415 | 426 | ||
416 | if (!status) { | 427 | if (!status) { |
417 | fh_unlock(current_fh); | 428 | fh_unlock(&cstate->current_fh); |
418 | set_change_info(&create->cr_cinfo, current_fh); | 429 | set_change_info(&create->cr_cinfo, &cstate->current_fh); |
419 | fh_dup2(current_fh, &resfh); | 430 | fh_dup2(&cstate->current_fh, &resfh); |
420 | } | 431 | } |
421 | 432 | ||
422 | fh_put(&resfh); | 433 | fh_put(&resfh); |
@@ -424,11 +435,12 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre | |||
424 | } | 435 | } |
425 | 436 | ||
426 | static inline __be32 | 437 | static inline __be32 |
427 | nfsd4_getattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_getattr *getattr) | 438 | nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
439 | struct nfsd4_getattr *getattr) | ||
428 | { | 440 | { |
429 | __be32 status; | 441 | __be32 status; |
430 | 442 | ||
431 | status = fh_verify(rqstp, current_fh, 0, MAY_NOP); | 443 | status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); |
432 | if (status) | 444 | if (status) |
433 | return status; | 445 | return status; |
434 | 446 | ||
@@ -438,26 +450,27 @@ nfsd4_getattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ge | |||
438 | getattr->ga_bmval[0] &= NFSD_SUPPORTED_ATTRS_WORD0; | 450 | getattr->ga_bmval[0] &= NFSD_SUPPORTED_ATTRS_WORD0; |
439 | getattr->ga_bmval[1] &= NFSD_SUPPORTED_ATTRS_WORD1; | 451 | getattr->ga_bmval[1] &= NFSD_SUPPORTED_ATTRS_WORD1; |
440 | 452 | ||
441 | getattr->ga_fhp = current_fh; | 453 | getattr->ga_fhp = &cstate->current_fh; |
442 | return nfs_ok; | 454 | return nfs_ok; |
443 | } | 455 | } |
444 | 456 | ||
445 | static inline __be32 | 457 | static inline __be32 |
446 | nfsd4_link(struct svc_rqst *rqstp, struct svc_fh *current_fh, | 458 | nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
447 | struct svc_fh *save_fh, struct nfsd4_link *link) | 459 | struct nfsd4_link *link) |
448 | { | 460 | { |
449 | __be32 status = nfserr_nofilehandle; | 461 | __be32 status = nfserr_nofilehandle; |
450 | 462 | ||
451 | if (!save_fh->fh_dentry) | 463 | if (!cstate->save_fh.fh_dentry) |
452 | return status; | 464 | return status; |
453 | status = nfsd_link(rqstp, current_fh, link->li_name, link->li_namelen, save_fh); | 465 | status = nfsd_link(rqstp, &cstate->current_fh, |
466 | link->li_name, link->li_namelen, &cstate->save_fh); | ||
454 | if (!status) | 467 | if (!status) |
455 | set_change_info(&link->li_cinfo, current_fh); | 468 | set_change_info(&link->li_cinfo, &cstate->current_fh); |
456 | return status; | 469 | return status; |
457 | } | 470 | } |
458 | 471 | ||
459 | static __be32 | 472 | static __be32 |
460 | nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh) | 473 | nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate) |
461 | { | 474 | { |
462 | struct svc_fh tmp_fh; | 475 | struct svc_fh tmp_fh; |
463 | __be32 ret; | 476 | __be32 ret; |
@@ -466,22 +479,27 @@ nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh) | |||
466 | if((ret = exp_pseudoroot(rqstp->rq_client, &tmp_fh, | 479 | if((ret = exp_pseudoroot(rqstp->rq_client, &tmp_fh, |
467 | &rqstp->rq_chandle)) != 0) | 480 | &rqstp->rq_chandle)) != 0) |
468 | return ret; | 481 | return ret; |
469 | if (tmp_fh.fh_dentry == current_fh->fh_dentry) { | 482 | if (tmp_fh.fh_dentry == cstate->current_fh.fh_dentry) { |
470 | fh_put(&tmp_fh); | 483 | fh_put(&tmp_fh); |
471 | return nfserr_noent; | 484 | return nfserr_noent; |
472 | } | 485 | } |
473 | fh_put(&tmp_fh); | 486 | fh_put(&tmp_fh); |
474 | return nfsd_lookup(rqstp, current_fh, "..", 2, current_fh); | 487 | return nfsd_lookup(rqstp, &cstate->current_fh, |
488 | "..", 2, &cstate->current_fh); | ||
475 | } | 489 | } |
476 | 490 | ||
477 | static inline __be32 | 491 | static inline __be32 |
478 | nfsd4_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lookup *lookup) | 492 | nfsd4_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
493 | struct nfsd4_lookup *lookup) | ||
479 | { | 494 | { |
480 | return nfsd_lookup(rqstp, current_fh, lookup->lo_name, lookup->lo_len, current_fh); | 495 | return nfsd_lookup(rqstp, &cstate->current_fh, |
496 | lookup->lo_name, lookup->lo_len, | ||
497 | &cstate->current_fh); | ||
481 | } | 498 | } |
482 | 499 | ||
483 | static inline __be32 | 500 | static inline __be32 |
484 | nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read) | 501 | nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
502 | struct nfsd4_read *read) | ||
485 | { | 503 | { |
486 | __be32 status; | 504 | __be32 status; |
487 | 505 | ||
@@ -493,7 +511,8 @@ nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read | |||
493 | 511 | ||
494 | nfs4_lock_state(); | 512 | nfs4_lock_state(); |
495 | /* check stateid */ | 513 | /* check stateid */ |
496 | if ((status = nfs4_preprocess_stateid_op(current_fh, &read->rd_stateid, | 514 | if ((status = nfs4_preprocess_stateid_op(&cstate->current_fh, |
515 | &read->rd_stateid, | ||
497 | CHECK_FH | RD_STATE, &read->rd_filp))) { | 516 | CHECK_FH | RD_STATE, &read->rd_filp))) { |
498 | dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); | 517 | dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); |
499 | goto out; | 518 | goto out; |
@@ -504,12 +523,13 @@ nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read | |||
504 | out: | 523 | out: |
505 | nfs4_unlock_state(); | 524 | nfs4_unlock_state(); |
506 | read->rd_rqstp = rqstp; | 525 | read->rd_rqstp = rqstp; |
507 | read->rd_fhp = current_fh; | 526 | read->rd_fhp = &cstate->current_fh; |
508 | return status; | 527 | return status; |
509 | } | 528 | } |
510 | 529 | ||
511 | static inline __be32 | 530 | static inline __be32 |
512 | nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readdir *readdir) | 531 | nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
532 | struct nfsd4_readdir *readdir) | ||
513 | { | 533 | { |
514 | u64 cookie = readdir->rd_cookie; | 534 | u64 cookie = readdir->rd_cookie; |
515 | static const nfs4_verifier zeroverf; | 535 | static const nfs4_verifier zeroverf; |
@@ -527,48 +547,51 @@ nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_re | |||
527 | return nfserr_bad_cookie; | 547 | return nfserr_bad_cookie; |
528 | 548 | ||
529 | readdir->rd_rqstp = rqstp; | 549 | readdir->rd_rqstp = rqstp; |
530 | readdir->rd_fhp = current_fh; | 550 | readdir->rd_fhp = &cstate->current_fh; |
531 | return nfs_ok; | 551 | return nfs_ok; |
532 | } | 552 | } |
533 | 553 | ||
534 | static inline __be32 | 554 | static inline __be32 |
535 | nfsd4_readlink(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readlink *readlink) | 555 | nfsd4_readlink(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
556 | struct nfsd4_readlink *readlink) | ||
536 | { | 557 | { |
537 | readlink->rl_rqstp = rqstp; | 558 | readlink->rl_rqstp = rqstp; |
538 | readlink->rl_fhp = current_fh; | 559 | readlink->rl_fhp = &cstate->current_fh; |
539 | return nfs_ok; | 560 | return nfs_ok; |
540 | } | 561 | } |
541 | 562 | ||
542 | static inline __be32 | 563 | static inline __be32 |
543 | nfsd4_remove(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_remove *remove) | 564 | nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
565 | struct nfsd4_remove *remove) | ||
544 | { | 566 | { |
545 | __be32 status; | 567 | __be32 status; |
546 | 568 | ||
547 | if (nfs4_in_grace()) | 569 | if (nfs4_in_grace()) |
548 | return nfserr_grace; | 570 | return nfserr_grace; |
549 | status = nfsd_unlink(rqstp, current_fh, 0, remove->rm_name, remove->rm_namelen); | 571 | status = nfsd_unlink(rqstp, &cstate->current_fh, 0, |
572 | remove->rm_name, remove->rm_namelen); | ||
550 | if (status == nfserr_symlink) | 573 | if (status == nfserr_symlink) |
551 | return nfserr_notdir; | 574 | return nfserr_notdir; |
552 | if (!status) { | 575 | if (!status) { |
553 | fh_unlock(current_fh); | 576 | fh_unlock(&cstate->current_fh); |
554 | set_change_info(&remove->rm_cinfo, current_fh); | 577 | set_change_info(&remove->rm_cinfo, &cstate->current_fh); |
555 | } | 578 | } |
556 | return status; | 579 | return status; |
557 | } | 580 | } |
558 | 581 | ||
559 | static inline __be32 | 582 | static inline __be32 |
560 | nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh, | 583 | nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
561 | struct svc_fh *save_fh, struct nfsd4_rename *rename) | 584 | struct nfsd4_rename *rename) |
562 | { | 585 | { |
563 | __be32 status = nfserr_nofilehandle; | 586 | __be32 status = nfserr_nofilehandle; |
564 | 587 | ||
565 | if (!save_fh->fh_dentry) | 588 | if (!cstate->save_fh.fh_dentry) |
566 | return status; | 589 | return status; |
567 | if (nfs4_in_grace() && !(save_fh->fh_export->ex_flags | 590 | if (nfs4_in_grace() && !(cstate->save_fh.fh_export->ex_flags |
568 | & NFSEXP_NOSUBTREECHECK)) | 591 | & NFSEXP_NOSUBTREECHECK)) |
569 | return nfserr_grace; | 592 | return nfserr_grace; |
570 | status = nfsd_rename(rqstp, save_fh, rename->rn_sname, | 593 | status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname, |
571 | rename->rn_snamelen, current_fh, | 594 | rename->rn_snamelen, &cstate->current_fh, |
572 | rename->rn_tname, rename->rn_tnamelen); | 595 | rename->rn_tname, rename->rn_tnamelen); |
573 | 596 | ||
574 | /* the underlying filesystem returns different error's than required | 597 | /* the underlying filesystem returns different error's than required |
@@ -576,27 +599,28 @@ nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh, | |||
576 | if (status == nfserr_isdir) | 599 | if (status == nfserr_isdir) |
577 | status = nfserr_exist; | 600 | status = nfserr_exist; |
578 | else if ((status == nfserr_notdir) && | 601 | else if ((status == nfserr_notdir) && |
579 | (S_ISDIR(save_fh->fh_dentry->d_inode->i_mode) && | 602 | (S_ISDIR(cstate->save_fh.fh_dentry->d_inode->i_mode) && |
580 | S_ISDIR(current_fh->fh_dentry->d_inode->i_mode))) | 603 | S_ISDIR(cstate->current_fh.fh_dentry->d_inode->i_mode))) |
581 | status = nfserr_exist; | 604 | status = nfserr_exist; |
582 | else if (status == nfserr_symlink) | 605 | else if (status == nfserr_symlink) |
583 | status = nfserr_notdir; | 606 | status = nfserr_notdir; |
584 | 607 | ||
585 | if (!status) { | 608 | if (!status) { |
586 | set_change_info(&rename->rn_sinfo, current_fh); | 609 | set_change_info(&rename->rn_sinfo, &cstate->current_fh); |
587 | set_change_info(&rename->rn_tinfo, save_fh); | 610 | set_change_info(&rename->rn_tinfo, &cstate->save_fh); |
588 | } | 611 | } |
589 | return status; | 612 | return status; |
590 | } | 613 | } |
591 | 614 | ||
592 | static inline __be32 | 615 | static inline __be32 |
593 | nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr) | 616 | nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
617 | struct nfsd4_setattr *setattr) | ||
594 | { | 618 | { |
595 | __be32 status = nfs_ok; | 619 | __be32 status = nfs_ok; |
596 | 620 | ||
597 | if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { | 621 | if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { |
598 | nfs4_lock_state(); | 622 | nfs4_lock_state(); |
599 | status = nfs4_preprocess_stateid_op(current_fh, | 623 | status = nfs4_preprocess_stateid_op(&cstate->current_fh, |
600 | &setattr->sa_stateid, CHECK_FH | WR_STATE, NULL); | 624 | &setattr->sa_stateid, CHECK_FH | WR_STATE, NULL); |
601 | nfs4_unlock_state(); | 625 | nfs4_unlock_state(); |
602 | if (status) { | 626 | if (status) { |
@@ -606,16 +630,18 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se | |||
606 | } | 630 | } |
607 | status = nfs_ok; | 631 | status = nfs_ok; |
608 | if (setattr->sa_acl != NULL) | 632 | if (setattr->sa_acl != NULL) |
609 | status = nfsd4_set_nfs4_acl(rqstp, current_fh, setattr->sa_acl); | 633 | status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh, |
634 | setattr->sa_acl); | ||
610 | if (status) | 635 | if (status) |
611 | return status; | 636 | return status; |
612 | status = nfsd_setattr(rqstp, current_fh, &setattr->sa_iattr, | 637 | status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr, |
613 | 0, (time_t)0); | 638 | 0, (time_t)0); |
614 | return status; | 639 | return status; |
615 | } | 640 | } |
616 | 641 | ||
617 | static inline __be32 | 642 | static inline __be32 |
618 | nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_write *write) | 643 | nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
644 | struct nfsd4_write *write) | ||
619 | { | 645 | { |
620 | stateid_t *stateid = &write->wr_stateid; | 646 | stateid_t *stateid = &write->wr_stateid; |
621 | struct file *filp = NULL; | 647 | struct file *filp = NULL; |
@@ -628,7 +654,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ | |||
628 | return nfserr_inval; | 654 | return nfserr_inval; |
629 | 655 | ||
630 | nfs4_lock_state(); | 656 | nfs4_lock_state(); |
631 | status = nfs4_preprocess_stateid_op(current_fh, stateid, | 657 | status = nfs4_preprocess_stateid_op(&cstate->current_fh, stateid, |
632 | CHECK_FH | WR_STATE, &filp); | 658 | CHECK_FH | WR_STATE, &filp); |
633 | if (filp) | 659 | if (filp) |
634 | get_file(filp); | 660 | get_file(filp); |
@@ -645,9 +671,9 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ | |||
645 | *p++ = nfssvc_boot.tv_sec; | 671 | *p++ = nfssvc_boot.tv_sec; |
646 | *p++ = nfssvc_boot.tv_usec; | 672 | *p++ = nfssvc_boot.tv_usec; |
647 | 673 | ||
648 | status = nfsd_write(rqstp, current_fh, filp, write->wr_offset, | 674 | status = nfsd_write(rqstp, &cstate->current_fh, filp, |
649 | rqstp->rq_vec, write->wr_vlen, write->wr_buflen, | 675 | write->wr_offset, rqstp->rq_vec, write->wr_vlen, |
650 | &write->wr_how_written); | 676 | write->wr_buflen, &write->wr_how_written); |
651 | if (filp) | 677 | if (filp) |
652 | fput(filp); | 678 | fput(filp); |
653 | 679 | ||
@@ -662,13 +688,14 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ | |||
662 | * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK. | 688 | * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK. |
663 | */ | 689 | */ |
664 | static __be32 | 690 | static __be32 |
665 | nfsd4_verify(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_verify *verify) | 691 | nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
692 | struct nfsd4_verify *verify) | ||
666 | { | 693 | { |
667 | __be32 *buf, *p; | 694 | __be32 *buf, *p; |
668 | int count; | 695 | int count; |
669 | __be32 status; | 696 | __be32 status; |
670 | 697 | ||
671 | status = fh_verify(rqstp, current_fh, 0, MAY_NOP); | 698 | status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); |
672 | if (status) | 699 | if (status) |
673 | return status; | 700 | return status; |
674 | 701 | ||
@@ -689,8 +716,9 @@ nfsd4_verify(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ver | |||
689 | if (!buf) | 716 | if (!buf) |
690 | return nfserr_resource; | 717 | return nfserr_resource; |
691 | 718 | ||
692 | status = nfsd4_encode_fattr(current_fh, current_fh->fh_export, | 719 | status = nfsd4_encode_fattr(&cstate->current_fh, |
693 | current_fh->fh_dentry, buf, | 720 | cstate->current_fh.fh_export, |
721 | cstate->current_fh.fh_dentry, buf, | ||
694 | &count, verify->ve_bmval, | 722 | &count, verify->ve_bmval, |
695 | rqstp); | 723 | rqstp); |
696 | 724 | ||
@@ -727,6 +755,26 @@ static inline void nfsd4_increment_op_stats(u32 opnum) | |||
727 | nfsdstats.nfs4_opcount[opnum]++; | 755 | nfsdstats.nfs4_opcount[opnum]++; |
728 | } | 756 | } |
729 | 757 | ||
758 | static void cstate_free(struct nfsd4_compound_state *cstate) | ||
759 | { | ||
760 | if (cstate == NULL) | ||
761 | return; | ||
762 | fh_put(&cstate->current_fh); | ||
763 | fh_put(&cstate->save_fh); | ||
764 | kfree(cstate); | ||
765 | } | ||
766 | |||
767 | static struct nfsd4_compound_state *cstate_alloc(void) | ||
768 | { | ||
769 | struct nfsd4_compound_state *cstate; | ||
770 | |||
771 | cstate = kmalloc(sizeof(struct nfsd4_compound_state), GFP_KERNEL); | ||
772 | if (cstate == NULL) | ||
773 | return NULL; | ||
774 | fh_init(&cstate->current_fh, NFS4_FHSIZE); | ||
775 | fh_init(&cstate->save_fh, NFS4_FHSIZE); | ||
776 | return cstate; | ||
777 | } | ||
730 | 778 | ||
731 | /* | 779 | /* |
732 | * COMPOUND call. | 780 | * COMPOUND call. |
@@ -737,21 +785,15 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
737 | struct nfsd4_compoundres *resp) | 785 | struct nfsd4_compoundres *resp) |
738 | { | 786 | { |
739 | struct nfsd4_op *op; | 787 | struct nfsd4_op *op; |
740 | struct svc_fh *current_fh = NULL; | 788 | struct nfsd4_compound_state *cstate = NULL; |
741 | struct svc_fh *save_fh = NULL; | ||
742 | struct nfs4_stateowner *replay_owner = NULL; | 789 | struct nfs4_stateowner *replay_owner = NULL; |
743 | int slack_bytes; | 790 | int slack_bytes; |
744 | __be32 status; | 791 | __be32 status; |
745 | 792 | ||
746 | status = nfserr_resource; | 793 | status = nfserr_resource; |
747 | current_fh = kmalloc(sizeof(*current_fh), GFP_KERNEL); | 794 | cstate = cstate_alloc(); |
748 | if (current_fh == NULL) | 795 | if (cstate == NULL) |
749 | goto out; | ||
750 | fh_init(current_fh, NFS4_FHSIZE); | ||
751 | save_fh = kmalloc(sizeof(*save_fh), GFP_KERNEL); | ||
752 | if (save_fh == NULL) | ||
753 | goto out; | 796 | goto out; |
754 | fh_init(save_fh, NFS4_FHSIZE); | ||
755 | 797 | ||
756 | resp->xbuf = &rqstp->rq_res; | 798 | resp->xbuf = &rqstp->rq_res; |
757 | resp->p = rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len; | 799 | resp->p = rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len; |
@@ -802,7 +844,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
802 | * SETCLIENTID_CONFIRM, PUTFH and PUTROOTFH | 844 | * SETCLIENTID_CONFIRM, PUTFH and PUTROOTFH |
803 | * require a valid current filehandle | 845 | * require a valid current filehandle |
804 | */ | 846 | */ |
805 | if (!current_fh->fh_dentry) { | 847 | if (!cstate->current_fh.fh_dentry) { |
806 | if (!((op->opnum == OP_PUTFH) || | 848 | if (!((op->opnum == OP_PUTFH) || |
807 | (op->opnum == OP_PUTROOTFH) || | 849 | (op->opnum == OP_PUTROOTFH) || |
808 | (op->opnum == OP_SETCLIENTID) || | 850 | (op->opnum == OP_SETCLIENTID) || |
@@ -817,7 +859,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
817 | /* Check must be done at start of each operation, except | 859 | /* Check must be done at start of each operation, except |
818 | * for GETATTR and ops not listed as returning NFS4ERR_MOVED | 860 | * for GETATTR and ops not listed as returning NFS4ERR_MOVED |
819 | */ | 861 | */ |
820 | else if (current_fh->fh_export->ex_fslocs.migrated && | 862 | else if (cstate->current_fh.fh_export->ex_fslocs.migrated && |
821 | !((op->opnum == OP_GETATTR) || | 863 | !((op->opnum == OP_GETATTR) || |
822 | (op->opnum == OP_PUTROOTFH) || | 864 | (op->opnum == OP_PUTROOTFH) || |
823 | (op->opnum == OP_PUTPUBFH) || | 865 | (op->opnum == OP_PUTPUBFH) || |
@@ -829,90 +871,110 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
829 | } | 871 | } |
830 | switch (op->opnum) { | 872 | switch (op->opnum) { |
831 | case OP_ACCESS: | 873 | case OP_ACCESS: |
832 | op->status = nfsd4_access(rqstp, current_fh, &op->u.access); | 874 | op->status = nfsd4_access(rqstp, cstate, |
875 | &op->u.access); | ||
833 | break; | 876 | break; |
834 | case OP_CLOSE: | 877 | case OP_CLOSE: |
835 | op->status = nfsd4_close(rqstp, current_fh, &op->u.close, &replay_owner); | 878 | op->status = nfsd4_close(rqstp, cstate, |
879 | &op->u.close, &replay_owner); | ||
836 | break; | 880 | break; |
837 | case OP_COMMIT: | 881 | case OP_COMMIT: |
838 | op->status = nfsd4_commit(rqstp, current_fh, &op->u.commit); | 882 | op->status = nfsd4_commit(rqstp, cstate, |
883 | &op->u.commit); | ||
839 | break; | 884 | break; |
840 | case OP_CREATE: | 885 | case OP_CREATE: |
841 | op->status = nfsd4_create(rqstp, current_fh, &op->u.create); | 886 | op->status = nfsd4_create(rqstp, cstate, |
887 | &op->u.create); | ||
842 | break; | 888 | break; |
843 | case OP_DELEGRETURN: | 889 | case OP_DELEGRETURN: |
844 | op->status = nfsd4_delegreturn(rqstp, current_fh, &op->u.delegreturn); | 890 | op->status = nfsd4_delegreturn(rqstp, cstate, |
891 | &op->u.delegreturn); | ||
845 | break; | 892 | break; |
846 | case OP_GETATTR: | 893 | case OP_GETATTR: |
847 | op->status = nfsd4_getattr(rqstp, current_fh, &op->u.getattr); | 894 | op->status = nfsd4_getattr(rqstp, cstate, |
895 | &op->u.getattr); | ||
848 | break; | 896 | break; |
849 | case OP_GETFH: | 897 | case OP_GETFH: |
850 | op->status = nfsd4_getfh(current_fh, &op->u.getfh); | 898 | op->status = nfsd4_getfh(cstate, &op->u.getfh); |
851 | break; | 899 | break; |
852 | case OP_LINK: | 900 | case OP_LINK: |
853 | op->status = nfsd4_link(rqstp, current_fh, save_fh, &op->u.link); | 901 | op->status = nfsd4_link(rqstp, cstate, &op->u.link); |
854 | break; | 902 | break; |
855 | case OP_LOCK: | 903 | case OP_LOCK: |
856 | op->status = nfsd4_lock(rqstp, current_fh, &op->u.lock, &replay_owner); | 904 | op->status = nfsd4_lock(rqstp, cstate, &op->u.lock, |
905 | &replay_owner); | ||
857 | break; | 906 | break; |
858 | case OP_LOCKT: | 907 | case OP_LOCKT: |
859 | op->status = nfsd4_lockt(rqstp, current_fh, &op->u.lockt); | 908 | op->status = nfsd4_lockt(rqstp, cstate, &op->u.lockt); |
860 | break; | 909 | break; |
861 | case OP_LOCKU: | 910 | case OP_LOCKU: |
862 | op->status = nfsd4_locku(rqstp, current_fh, &op->u.locku, &replay_owner); | 911 | op->status = nfsd4_locku(rqstp, cstate, &op->u.locku, |
912 | &replay_owner); | ||
863 | break; | 913 | break; |
864 | case OP_LOOKUP: | 914 | case OP_LOOKUP: |
865 | op->status = nfsd4_lookup(rqstp, current_fh, &op->u.lookup); | 915 | op->status = nfsd4_lookup(rqstp, cstate, |
916 | &op->u.lookup); | ||
866 | break; | 917 | break; |
867 | case OP_LOOKUPP: | 918 | case OP_LOOKUPP: |
868 | op->status = nfsd4_lookupp(rqstp, current_fh); | 919 | op->status = nfsd4_lookupp(rqstp, cstate); |
869 | break; | 920 | break; |
870 | case OP_NVERIFY: | 921 | case OP_NVERIFY: |
871 | op->status = nfsd4_verify(rqstp, current_fh, &op->u.nverify); | 922 | op->status = nfsd4_verify(rqstp, cstate, |
923 | &op->u.nverify); | ||
872 | if (op->status == nfserr_not_same) | 924 | if (op->status == nfserr_not_same) |
873 | op->status = nfs_ok; | 925 | op->status = nfs_ok; |
874 | break; | 926 | break; |
875 | case OP_OPEN: | 927 | case OP_OPEN: |
876 | op->status = nfsd4_open(rqstp, current_fh, &op->u.open, &replay_owner); | 928 | op->status = nfsd4_open(rqstp, cstate, |
929 | &op->u.open, &replay_owner); | ||
877 | break; | 930 | break; |
878 | case OP_OPEN_CONFIRM: | 931 | case OP_OPEN_CONFIRM: |
879 | op->status = nfsd4_open_confirm(rqstp, current_fh, &op->u.open_confirm, &replay_owner); | 932 | op->status = nfsd4_open_confirm(rqstp, cstate, |
933 | &op->u.open_confirm, | ||
934 | &replay_owner); | ||
880 | break; | 935 | break; |
881 | case OP_OPEN_DOWNGRADE: | 936 | case OP_OPEN_DOWNGRADE: |
882 | op->status = nfsd4_open_downgrade(rqstp, current_fh, &op->u.open_downgrade, &replay_owner); | 937 | op->status = nfsd4_open_downgrade(rqstp, cstate, |
938 | &op->u.open_downgrade, | ||
939 | &replay_owner); | ||
883 | break; | 940 | break; |
884 | case OP_PUTFH: | 941 | case OP_PUTFH: |
885 | op->status = nfsd4_putfh(rqstp, current_fh, &op->u.putfh); | 942 | op->status = nfsd4_putfh(rqstp, cstate, &op->u.putfh); |
886 | break; | 943 | break; |
887 | case OP_PUTROOTFH: | 944 | case OP_PUTROOTFH: |
888 | op->status = nfsd4_putrootfh(rqstp, current_fh); | 945 | op->status = nfsd4_putrootfh(rqstp, cstate); |
889 | break; | 946 | break; |
890 | case OP_READ: | 947 | case OP_READ: |
891 | op->status = nfsd4_read(rqstp, current_fh, &op->u.read); | 948 | op->status = nfsd4_read(rqstp, cstate, &op->u.read); |
892 | break; | 949 | break; |
893 | case OP_READDIR: | 950 | case OP_READDIR: |
894 | op->status = nfsd4_readdir(rqstp, current_fh, &op->u.readdir); | 951 | op->status = nfsd4_readdir(rqstp, cstate, |
952 | &op->u.readdir); | ||
895 | break; | 953 | break; |
896 | case OP_READLINK: | 954 | case OP_READLINK: |
897 | op->status = nfsd4_readlink(rqstp, current_fh, &op->u.readlink); | 955 | op->status = nfsd4_readlink(rqstp, cstate, |
956 | &op->u.readlink); | ||
898 | break; | 957 | break; |
899 | case OP_REMOVE: | 958 | case OP_REMOVE: |
900 | op->status = nfsd4_remove(rqstp, current_fh, &op->u.remove); | 959 | op->status = nfsd4_remove(rqstp, cstate, |
960 | &op->u.remove); | ||
901 | break; | 961 | break; |
902 | case OP_RENAME: | 962 | case OP_RENAME: |
903 | op->status = nfsd4_rename(rqstp, current_fh, save_fh, &op->u.rename); | 963 | op->status = nfsd4_rename(rqstp, cstate, |
964 | &op->u.rename); | ||
904 | break; | 965 | break; |
905 | case OP_RENEW: | 966 | case OP_RENEW: |
906 | op->status = nfsd4_renew(&op->u.renew); | 967 | op->status = nfsd4_renew(&op->u.renew); |
907 | break; | 968 | break; |
908 | case OP_RESTOREFH: | 969 | case OP_RESTOREFH: |
909 | op->status = nfsd4_restorefh(current_fh, save_fh); | 970 | op->status = nfsd4_restorefh(cstate); |
910 | break; | 971 | break; |
911 | case OP_SAVEFH: | 972 | case OP_SAVEFH: |
912 | op->status = nfsd4_savefh(current_fh, save_fh); | 973 | op->status = nfsd4_savefh(cstate); |
913 | break; | 974 | break; |
914 | case OP_SETATTR: | 975 | case OP_SETATTR: |
915 | op->status = nfsd4_setattr(rqstp, current_fh, &op->u.setattr); | 976 | op->status = nfsd4_setattr(rqstp, cstate, |
977 | &op->u.setattr); | ||
916 | break; | 978 | break; |
917 | case OP_SETCLIENTID: | 979 | case OP_SETCLIENTID: |
918 | op->status = nfsd4_setclientid(rqstp, &op->u.setclientid); | 980 | op->status = nfsd4_setclientid(rqstp, &op->u.setclientid); |
@@ -921,12 +983,13 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
921 | op->status = nfsd4_setclientid_confirm(rqstp, &op->u.setclientid_confirm); | 983 | op->status = nfsd4_setclientid_confirm(rqstp, &op->u.setclientid_confirm); |
922 | break; | 984 | break; |
923 | case OP_VERIFY: | 985 | case OP_VERIFY: |
924 | op->status = nfsd4_verify(rqstp, current_fh, &op->u.verify); | 986 | op->status = nfsd4_verify(rqstp, cstate, |
987 | &op->u.verify); | ||
925 | if (op->status == nfserr_same) | 988 | if (op->status == nfserr_same) |
926 | op->status = nfs_ok; | 989 | op->status = nfs_ok; |
927 | break; | 990 | break; |
928 | case OP_WRITE: | 991 | case OP_WRITE: |
929 | op->status = nfsd4_write(rqstp, current_fh, &op->u.write); | 992 | op->status = nfsd4_write(rqstp, cstate, &op->u.write); |
930 | break; | 993 | break; |
931 | case OP_RELEASE_LOCKOWNER: | 994 | case OP_RELEASE_LOCKOWNER: |
932 | op->status = nfsd4_release_lockowner(rqstp, &op->u.release_lockowner); | 995 | op->status = nfsd4_release_lockowner(rqstp, &op->u.release_lockowner); |
@@ -958,12 +1021,7 @@ encode_op: | |||
958 | 1021 | ||
959 | out: | 1022 | out: |
960 | nfsd4_release_compoundargs(args); | 1023 | nfsd4_release_compoundargs(args); |
961 | if (current_fh) | 1024 | cstate_free(cstate); |
962 | fh_put(current_fh); | ||
963 | kfree(current_fh); | ||
964 | if (save_fh) | ||
965 | fh_put(save_fh); | ||
966 | kfree(save_fh); | ||
967 | return status; | 1025 | return status; |
968 | } | 1026 | } |
969 | 1027 | ||