diff options
-rw-r--r-- | fs/nfsd/nfs4state.c | 60 | ||||
-rw-r--r-- | fs/nfsd/xdr4.h | 1 |
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 | ||
105 | static struct list_head del_recall_lru; | 105 | static struct list_head del_recall_lru; |
106 | 106 | ||
107 | static void nfsd4_free_file(struct nfs4_file *f) | ||
108 | { | ||
109 | kmem_cache_free(file_slab, f); | ||
110 | } | ||
111 | |||
107 | static inline void | 112 | static inline void |
108 | put_nfs4_file(struct nfs4_file *fi) | 113 | put_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 | ||
2198 | static 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 */ |
2194 | static inline struct nfs4_file * | 2204 | static void nfsd4_init_file(struct nfs4_file *fp, struct inode *ino) |
2195 | alloc_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 | ||
2219 | static void | 2222 | static 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 |