aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/nfs4state.c60
-rw-r--r--fs/nfsd/xdr4.h1
2 files changed, 37 insertions, 24 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 2c9a1a20e014..ae5d25075f67 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -104,6 +104,11 @@ opaque_hashval(const void *ptr, int nbytes)
104 104
105static struct list_head del_recall_lru; 105static struct list_head del_recall_lru;
106 106
107static void nfsd4_free_file(struct nfs4_file *f)
108{
109 kmem_cache_free(file_slab, f);
110}
111
107static inline void 112static inline void
108put_nfs4_file(struct nfs4_file *fi) 113put_nfs4_file(struct nfs4_file *fi)
109{ 114{
@@ -111,7 +116,7 @@ put_nfs4_file(struct nfs4_file *fi)
111 list_del(&fi->fi_hash); 116 list_del(&fi->fi_hash);
112 spin_unlock(&recall_lock); 117 spin_unlock(&recall_lock);
113 iput(fi->fi_inode); 118 iput(fi->fi_inode);
114 kmem_cache_free(file_slab, fi); 119 nfsd4_free_file(fi);
115 } 120 }
116} 121}
117 122
@@ -2190,30 +2195,28 @@ out:
2190 return status; 2195 return status;
2191} 2196}
2192 2197
2198static struct nfs4_file *nfsd4_alloc_file(void)
2199{
2200 return kmem_cache_alloc(file_slab, GFP_KERNEL);
2201}
2202
2193/* OPEN Share state helper functions */ 2203/* OPEN Share state helper functions */
2194static inline struct nfs4_file * 2204static void nfsd4_init_file(struct nfs4_file *fp, struct inode *ino)
2195alloc_init_file(struct inode *ino)
2196{ 2205{
2197 struct nfs4_file *fp;
2198 unsigned int hashval = file_hashval(ino); 2206 unsigned int hashval = file_hashval(ino);
2199 2207
2200 fp = kmem_cache_alloc(file_slab, GFP_KERNEL); 2208 atomic_set(&fp->fi_ref, 1);
2201 if (fp) { 2209 INIT_LIST_HEAD(&fp->fi_hash);
2202 atomic_set(&fp->fi_ref, 1); 2210 INIT_LIST_HEAD(&fp->fi_stateids);
2203 INIT_LIST_HEAD(&fp->fi_hash); 2211 INIT_LIST_HEAD(&fp->fi_delegations);
2204 INIT_LIST_HEAD(&fp->fi_stateids); 2212 fp->fi_inode = igrab(ino);
2205 INIT_LIST_HEAD(&fp->fi_delegations); 2213 fp->fi_had_conflict = false;
2206 fp->fi_inode = igrab(ino); 2214 fp->fi_lease = NULL;
2207 fp->fi_had_conflict = false; 2215 memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
2208 fp->fi_lease = NULL; 2216 memset(fp->fi_access, 0, sizeof(fp->fi_access));
2209 memset(fp->fi_fds, 0, sizeof(fp->fi_fds)); 2217 spin_lock(&recall_lock);
2210 memset(fp->fi_access, 0, sizeof(fp->fi_access)); 2218 list_add(&fp->fi_hash, &file_hashtbl[hashval]);
2211 spin_lock(&recall_lock); 2219 spin_unlock(&recall_lock);
2212 list_add(&fp->fi_hash, &file_hashtbl[hashval]);
2213 spin_unlock(&recall_lock);
2214 return fp;
2215 }
2216 return NULL;
2217} 2220}
2218 2221
2219static void 2222static void
@@ -2509,6 +2512,13 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate,
2509 2512
2510 if (STALE_CLIENTID(&open->op_clientid)) 2513 if (STALE_CLIENTID(&open->op_clientid))
2511 return nfserr_stale_clientid; 2514 return nfserr_stale_clientid;
2515 /*
2516 * In case we need it later, after we've already created the
2517 * file and don't want to risk a further failure:
2518 */
2519 open->op_file = nfsd4_alloc_file();
2520 if (open->op_file == NULL)
2521 return nfserr_jukebox;
2512 2522
2513 strhashval = open_ownerstr_hashval(clientid->cl_id, &open->op_owner); 2523 strhashval = open_ownerstr_hashval(clientid->cl_id, &open->op_owner);
2514 oo = find_openstateowner_str(strhashval, open); 2524 oo = find_openstateowner_str(strhashval, open);
@@ -2884,9 +2894,9 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
2884 if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR) 2894 if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR)
2885 goto out; 2895 goto out;
2886 status = nfserr_jukebox; 2896 status = nfserr_jukebox;
2887 fp = alloc_init_file(ino); 2897 fp = open->op_file;
2888 if (fp == NULL) 2898 open->op_file = NULL;
2889 goto out; 2899 nfsd4_init_file(fp, ino);
2890 } 2900 }
2891 2901
2892 /* 2902 /*
@@ -2960,6 +2970,8 @@ void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status)
2960 oo->oo_flags &= ~NFS4_OO_NEW; 2970 oo->oo_flags &= ~NFS4_OO_NEW;
2961 } 2971 }
2962 } 2972 }
2973 if (open->op_file)
2974 nfsd4_free_file(open->op_file);
2963} 2975}
2964 2976
2965__be32 2977__be32
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 32e6fd8d9768..502dd43634f9 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -228,6 +228,7 @@ struct nfsd4_open {
228 u32 op_rflags; /* response */ 228 u32 op_rflags; /* response */
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_acl *op_acl; 232 struct nfs4_acl *op_acl;
232}; 233};
233#define op_iattr iattr 234#define op_iattr iattr