aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2011-10-17 15:57:47 -0400
committerJ. Bruce Fields <bfields@redhat.com>2011-10-17 17:50:07 -0400
commit4cdc951b8611de4ce25e35c9fb8c0656150c9245 (patch)
treebd5fafca3ae02390d2f096c631ffd34eb98b4913 /fs/nfsd/nfs4state.c
parent996e09385c364f97a89648b401409521e2a3a094 (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/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c49
1 files changed, 20 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
271static struct nfs4_ol_stateid * nfs4_alloc_stateid(struct nfs4_client *clp)
272{
273 return openlockstateid(nfs4_alloc_stid(clp, stateid_slab));
274}
275
271static struct nfs4_delegation * 276static struct nfs4_delegation *
272alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh, u32 type) 277alloc_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;
2542new_owner: 2552new_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;
2557alloc_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
2619static struct nfs4_ol_stateid * nfs4_alloc_stateid(struct nfs4_client *clp)
2620{
2621 return openlockstateid(nfs4_alloc_stid(clp, stateid_slab));
2622}
2623
2624static void nfs4_free_stateid(struct nfs4_ol_stateid *s) 2633static 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
2664static __be32
2665nfs4_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
2686static inline __be32 2673static inline __be32
2687nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh, 2674nfsd4_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