From d089cc03cd1c42c80633c52d393f8f20248e1df5 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Thu, 13 Oct 2011 16:00:16 -0400 Subject: [PATCH] --- yaml --- r: 267193 b: refs/heads/master c: 32513b40efdc693b3675f1c691ab901518fbcb6a h: refs/heads/master i: 267191: b5a2d06b0444e7b8924cd8d4595cff6c8969783a v: v3 --- [refs] | 2 +- trunk/fs/nfsd/nfs4state.c | 60 +++++++++++++++++++++++---------------- trunk/fs/nfsd/xdr4.h | 1 + 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/[refs] b/[refs] index 77f0b5812e43..675f7bcaf1e6 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d29b20cd589128a599e5045d4effc2d7dbc388f5 +refs/heads/master: 32513b40efdc693b3675f1c691ab901518fbcb6a diff --git a/trunk/fs/nfsd/nfs4state.c b/trunk/fs/nfsd/nfs4state.c index 2c9a1a20e014..ae5d25075f67 100644 --- a/trunk/fs/nfsd/nfs4state.c +++ b/trunk/fs/nfsd/nfs4state.c @@ -104,6 +104,11 @@ opaque_hashval(const void *ptr, int nbytes) static struct list_head del_recall_lru; +static void nfsd4_free_file(struct nfs4_file *f) +{ + kmem_cache_free(file_slab, f); +} + static inline void put_nfs4_file(struct nfs4_file *fi) { @@ -111,7 +116,7 @@ put_nfs4_file(struct nfs4_file *fi) list_del(&fi->fi_hash); spin_unlock(&recall_lock); iput(fi->fi_inode); - kmem_cache_free(file_slab, fi); + nfsd4_free_file(fi); } } @@ -2190,30 +2195,28 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, return status; } +static struct nfs4_file *nfsd4_alloc_file(void) +{ + return kmem_cache_alloc(file_slab, GFP_KERNEL); +} + /* OPEN Share state helper functions */ -static inline struct nfs4_file * -alloc_init_file(struct inode *ino) +static void nfsd4_init_file(struct nfs4_file *fp, struct inode *ino) { - struct nfs4_file *fp; unsigned int hashval = file_hashval(ino); - fp = kmem_cache_alloc(file_slab, GFP_KERNEL); - if (fp) { - atomic_set(&fp->fi_ref, 1); - INIT_LIST_HEAD(&fp->fi_hash); - INIT_LIST_HEAD(&fp->fi_stateids); - INIT_LIST_HEAD(&fp->fi_delegations); - fp->fi_inode = igrab(ino); - fp->fi_had_conflict = false; - fp->fi_lease = NULL; - memset(fp->fi_fds, 0, sizeof(fp->fi_fds)); - memset(fp->fi_access, 0, sizeof(fp->fi_access)); - spin_lock(&recall_lock); - list_add(&fp->fi_hash, &file_hashtbl[hashval]); - spin_unlock(&recall_lock); - return fp; - } - return NULL; + atomic_set(&fp->fi_ref, 1); + INIT_LIST_HEAD(&fp->fi_hash); + INIT_LIST_HEAD(&fp->fi_stateids); + INIT_LIST_HEAD(&fp->fi_delegations); + fp->fi_inode = igrab(ino); + fp->fi_had_conflict = false; + fp->fi_lease = NULL; + memset(fp->fi_fds, 0, sizeof(fp->fi_fds)); + memset(fp->fi_access, 0, sizeof(fp->fi_access)); + spin_lock(&recall_lock); + list_add(&fp->fi_hash, &file_hashtbl[hashval]); + spin_unlock(&recall_lock); } static void @@ -2509,6 +2512,13 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate, if (STALE_CLIENTID(&open->op_clientid)) return nfserr_stale_clientid; + /* + * In case we need it later, after we've already created the + * file and don't want to risk a further failure: + */ + open->op_file = nfsd4_alloc_file(); + if (open->op_file == NULL) + return nfserr_jukebox; strhashval = open_ownerstr_hashval(clientid->cl_id, &open->op_owner); oo = find_openstateowner_str(strhashval, open); @@ -2884,9 +2894,9 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR) goto out; status = nfserr_jukebox; - fp = alloc_init_file(ino); - if (fp == NULL) - goto out; + fp = open->op_file; + open->op_file = NULL; + nfsd4_init_file(fp, ino); } /* @@ -2960,6 +2970,8 @@ void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status) oo->oo_flags &= ~NFS4_OO_NEW; } } + if (open->op_file) + nfsd4_free_file(open->op_file); } __be32 diff --git a/trunk/fs/nfsd/xdr4.h b/trunk/fs/nfsd/xdr4.h index 32e6fd8d9768..502dd43634f9 100644 --- a/trunk/fs/nfsd/xdr4.h +++ b/trunk/fs/nfsd/xdr4.h @@ -228,6 +228,7 @@ struct nfsd4_open { u32 op_rflags; /* response */ int op_truncate; /* used during processing */ struct nfs4_openowner *op_openowner; /* used during processing */ + struct nfs4_file *op_file; /* used during processing */ struct nfs4_acl *op_acl; }; #define op_iattr iattr