diff options
author | J. Bruce Fields <bfields@redhat.com> | 2011-10-17 15:57:47 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2011-10-17 17:50:07 -0400 |
commit | 4cdc951b8611de4ce25e35c9fb8c0656150c9245 (patch) | |
tree | bd5fafca3ae02390d2f096c631ffd34eb98b4913 /fs/nfsd | |
parent | 996e09385c364f97a89648b401409521e2a3a094 (diff) |
nfsd4: preallocate open stateid in process_open1()
As with the nfs4_file, we'd prefer to find out about any failure before
creating a new file rather than after.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfs4state.c | 49 | ||||
-rw-r--r-- | fs/nfsd/xdr4.h | 1 |
2 files changed, 21 insertions, 29 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 1f8c781c2a28..3e1d4e08dfad 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -268,6 +268,11 @@ static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cac | |||
268 | return kmem_cache_alloc(slab, GFP_KERNEL); | 268 | return kmem_cache_alloc(slab, GFP_KERNEL); |
269 | } | 269 | } |
270 | 270 | ||
271 | static struct nfs4_ol_stateid * nfs4_alloc_stateid(struct nfs4_client *clp) | ||
272 | { | ||
273 | return openlockstateid(nfs4_alloc_stid(clp, stateid_slab)); | ||
274 | } | ||
275 | |||
271 | static struct nfs4_delegation * | 276 | static struct nfs4_delegation * |
272 | alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh, u32 type) | 277 | alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh, u32 type) |
273 | { | 278 | { |
@@ -2511,6 +2516,7 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate, | |||
2511 | struct nfs4_client *clp = NULL; | 2516 | struct nfs4_client *clp = NULL; |
2512 | unsigned int strhashval; | 2517 | unsigned int strhashval; |
2513 | struct nfs4_openowner *oo = NULL; | 2518 | struct nfs4_openowner *oo = NULL; |
2519 | __be32 status; | ||
2514 | 2520 | ||
2515 | if (STALE_CLIENTID(&open->op_clientid)) | 2521 | if (STALE_CLIENTID(&open->op_clientid)) |
2516 | return nfserr_stale_clientid; | 2522 | return nfserr_stale_clientid; |
@@ -2538,12 +2544,20 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate, | |||
2538 | open->op_openowner = NULL; | 2544 | open->op_openowner = NULL; |
2539 | goto new_owner; | 2545 | goto new_owner; |
2540 | } | 2546 | } |
2541 | return nfsd4_check_seqid(cstate, &oo->oo_owner, open->op_seqid); | 2547 | status = nfsd4_check_seqid(cstate, &oo->oo_owner, open->op_seqid); |
2548 | if (status) | ||
2549 | return status; | ||
2550 | clp = oo->oo_owner.so_client; | ||
2551 | goto alloc_stateid; | ||
2542 | new_owner: | 2552 | new_owner: |
2543 | oo = alloc_init_open_stateowner(strhashval, clp, open); | 2553 | oo = alloc_init_open_stateowner(strhashval, clp, open); |
2544 | if (oo == NULL) | 2554 | if (oo == NULL) |
2545 | return nfserr_jukebox; | 2555 | return nfserr_jukebox; |
2546 | open->op_openowner = oo; | 2556 | open->op_openowner = oo; |
2557 | alloc_stateid: | ||
2558 | open->op_stp = nfs4_alloc_stateid(clp); | ||
2559 | if (!open->op_stp) | ||
2560 | return nfserr_jukebox; | ||
2547 | return nfs_ok; | 2561 | return nfs_ok; |
2548 | } | 2562 | } |
2549 | 2563 | ||
@@ -2616,11 +2630,6 @@ nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_ol_st | |||
2616 | return nfs_ok; | 2630 | return nfs_ok; |
2617 | } | 2631 | } |
2618 | 2632 | ||
2619 | static struct nfs4_ol_stateid * nfs4_alloc_stateid(struct nfs4_client *clp) | ||
2620 | { | ||
2621 | return openlockstateid(nfs4_alloc_stid(clp, stateid_slab)); | ||
2622 | } | ||
2623 | |||
2624 | static void nfs4_free_stateid(struct nfs4_ol_stateid *s) | 2633 | static void nfs4_free_stateid(struct nfs4_ol_stateid *s) |
2625 | { | 2634 | { |
2626 | kmem_cache_free(stateid_slab, s); | 2635 | kmem_cache_free(stateid_slab, s); |
@@ -2661,28 +2670,6 @@ static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp, | |||
2661 | return nfs_ok; | 2670 | return nfs_ok; |
2662 | } | 2671 | } |
2663 | 2672 | ||
2664 | static __be32 | ||
2665 | nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_ol_stateid **stpp, | ||
2666 | struct nfs4_file *fp, struct svc_fh *cur_fh, | ||
2667 | struct nfsd4_open *open) | ||
2668 | { | ||
2669 | struct nfs4_ol_stateid *stp; | ||
2670 | struct nfs4_client *cl = open->op_openowner->oo_owner.so_client; | ||
2671 | __be32 status; | ||
2672 | |||
2673 | stp = nfs4_alloc_stateid(cl); | ||
2674 | if (stp == NULL) | ||
2675 | return nfserr_jukebox; | ||
2676 | |||
2677 | status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open); | ||
2678 | if (status) { | ||
2679 | nfs4_free_stateid(stp); | ||
2680 | return status; | ||
2681 | } | ||
2682 | *stpp = stp; | ||
2683 | return 0; | ||
2684 | } | ||
2685 | |||
2686 | static inline __be32 | 2673 | static inline __be32 |
2687 | nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh, | 2674 | nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh, |
2688 | struct nfsd4_open *open) | 2675 | struct nfsd4_open *open) |
@@ -2916,9 +2903,11 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf | |||
2916 | if (status) | 2903 | if (status) |
2917 | goto out; | 2904 | goto out; |
2918 | } else { | 2905 | } else { |
2919 | status = nfs4_new_open(rqstp, &stp, fp, current_fh, open); | 2906 | status = nfs4_get_vfs_file(rqstp, fp, current_fh, open); |
2920 | if (status) | 2907 | if (status) |
2921 | goto out; | 2908 | goto out; |
2909 | stp = open->op_stp; | ||
2910 | open->op_stp = NULL; | ||
2922 | init_open_stateid(stp, fp, open); | 2911 | init_open_stateid(stp, fp, open); |
2923 | status = nfsd4_truncate(rqstp, current_fh, open); | 2912 | status = nfsd4_truncate(rqstp, current_fh, open); |
2924 | if (status) { | 2913 | if (status) { |
@@ -2975,6 +2964,8 @@ void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status) | |||
2975 | } | 2964 | } |
2976 | if (open->op_file) | 2965 | if (open->op_file) |
2977 | nfsd4_free_file(open->op_file); | 2966 | nfsd4_free_file(open->op_file); |
2967 | if (open->op_stp) | ||
2968 | nfs4_free_stateid(open->op_stp); | ||
2978 | } | 2969 | } |
2979 | 2970 | ||
2980 | __be32 | 2971 | __be32 |
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 502dd43634f9..ce8c59196b4e 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h | |||
@@ -229,6 +229,7 @@ struct nfsd4_open { | |||
229 | int op_truncate; /* used during processing */ | 229 | int op_truncate; /* used during processing */ |
230 | struct nfs4_openowner *op_openowner; /* used during processing */ | 230 | struct nfs4_openowner *op_openowner; /* used during processing */ |
231 | struct nfs4_file *op_file; /* used during processing */ | 231 | struct nfs4_file *op_file; /* used during processing */ |
232 | struct nfs4_ol_stateid *op_stp; /* used during processing */ | ||
232 | struct nfs4_acl *op_acl; | 233 | struct nfs4_acl *op_acl; |
233 | }; | 234 | }; |
234 | #define op_iattr iattr | 235 | #define op_iattr iattr |