aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/nfs4proc.c6
-rw-r--r--fs/nfsd/nfs4state.c23
-rw-r--r--fs/nfsd/nfs4xdr.c11
-rw-r--r--fs/nfsd/state.h15
-rw-r--r--fs/nfsd/xdr4.h2
5 files changed, 22 insertions, 35 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 50063a85f505..ce151f0ed4b9 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -405,10 +405,9 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
405 */ 405 */
406 status = nfsd4_process_open2(rqstp, &cstate->current_fh, open); 406 status = nfsd4_process_open2(rqstp, &cstate->current_fh, open);
407out: 407out:
408 if (open->op_stateowner) { 408 if (open->op_stateowner)
409 nfs4_get_stateowner(open->op_stateowner);
410 cstate->replay_owner = open->op_stateowner; 409 cstate->replay_owner = open->op_stateowner;
411 } else 410 else
412 nfs4_unlock_state(); 411 nfs4_unlock_state();
413 return status; 412 return status;
414} 413}
@@ -1228,7 +1227,6 @@ encode_op:
1228 1227
1229 if (cstate->replay_owner) { 1228 if (cstate->replay_owner) {
1230 nfs4_unlock_state(); 1229 nfs4_unlock_state();
1231 nfs4_put_stateowner(cstate->replay_owner);
1232 cstate->replay_owner = NULL; 1230 cstate->replay_owner = NULL;
1233 } 1231 }
1234 /* XXX Ugh, we need to get rid of this kind of special case: */ 1232 /* XXX Ugh, we need to get rid of this kind of special case: */
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 26b0c75aa93b..834a5f844f42 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -453,7 +453,7 @@ static void unhash_lockowner(struct nfs4_stateowner *sop)
453static void release_lockowner(struct nfs4_stateowner *sop) 453static void release_lockowner(struct nfs4_stateowner *sop)
454{ 454{
455 unhash_lockowner(sop); 455 unhash_lockowner(sop);
456 nfs4_put_stateowner(sop); 456 nfs4_free_stateowner(sop);
457} 457}
458 458
459static void 459static void
@@ -496,7 +496,7 @@ static void release_openowner(struct nfs4_stateowner *sop)
496{ 496{
497 unhash_openowner(sop); 497 unhash_openowner(sop);
498 list_del(&sop->so_close_lru); 498 list_del(&sop->so_close_lru);
499 nfs4_put_stateowner(sop); 499 nfs4_free_stateowner(sop);
500} 500}
501 501
502#define SESSION_HASH_SIZE 512 502#define SESSION_HASH_SIZE 512
@@ -2206,10 +2206,8 @@ out_nomem:
2206} 2206}
2207 2207
2208void 2208void
2209nfs4_free_stateowner(struct kref *kref) 2209nfs4_free_stateowner(struct nfs4_stateowner *sop)
2210{ 2210{
2211 struct nfs4_stateowner *sop =
2212 container_of(kref, struct nfs4_stateowner, so_ref);
2213 kfree(sop->so_owner.data); 2211 kfree(sop->so_owner.data);
2214 kmem_cache_free(stateowner_slab, sop); 2212 kmem_cache_free(stateowner_slab, sop);
2215} 2213}
@@ -2236,7 +2234,6 @@ static inline struct nfs4_stateowner *alloc_stateowner(struct xdr_netobj *owner,
2236 } 2234 }
2237 sop->so_owner.len = owner->len; 2235 sop->so_owner.len = owner->len;
2238 2236
2239 kref_init(&sop->so_ref);
2240 INIT_LIST_HEAD(&sop->so_perclient); 2237 INIT_LIST_HEAD(&sop->so_perclient);
2241 INIT_LIST_HEAD(&sop->so_stateids); 2238 INIT_LIST_HEAD(&sop->so_stateids);
2242 INIT_LIST_HEAD(&sop->so_perstateid); 2239 INIT_LIST_HEAD(&sop->so_perstateid);
@@ -3413,14 +3410,12 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
3413 /* It's not stale; let's assume it's expired: */ 3410 /* It's not stale; let's assume it's expired: */
3414 if (sop == NULL) 3411 if (sop == NULL)
3415 return nfserr_expired; 3412 return nfserr_expired;
3416 nfs4_get_stateowner(sop);
3417 cstate->replay_owner = sop; 3413 cstate->replay_owner = sop;
3418 goto check_replay; 3414 goto check_replay;
3419 } 3415 }
3420 3416
3421 *stpp = stp; 3417 *stpp = stp;
3422 sop = stp->st_stateowner; 3418 sop = stp->st_stateowner;
3423 nfs4_get_stateowner(sop);
3424 cstate->replay_owner = sop; 3419 cstate->replay_owner = sop;
3425 3420
3426 if (nfs4_check_fh(current_fh, stp)) { 3421 if (nfs4_check_fh(current_fh, stp)) {
@@ -3783,11 +3778,17 @@ nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
3783 3778
3784 if (fl->fl_lmops == &nfsd_posix_mng_ops) { 3779 if (fl->fl_lmops == &nfsd_posix_mng_ops) {
3785 sop = (struct nfs4_stateowner *) fl->fl_owner; 3780 sop = (struct nfs4_stateowner *) fl->fl_owner;
3786 kref_get(&sop->so_ref); 3781 deny->ld_owner.data = kmemdup(sop->so_owner.data,
3787 deny->ld_sop = sop; 3782 sop->so_owner.len, GFP_KERNEL);
3783 if (!deny->ld_owner.data)
3784 /* We just don't care that much */
3785 goto nevermind;
3786 deny->ld_owner.len = sop->so_owner.len;
3788 deny->ld_clientid = sop->so_client->cl_clientid; 3787 deny->ld_clientid = sop->so_client->cl_clientid;
3789 } else { 3788 } else {
3790 deny->ld_sop = NULL; 3789nevermind:
3790 deny->ld_owner.len = 0;
3791 deny->ld_owner.data = NULL;
3791 deny->ld_clientid.cl_boot = 0; 3792 deny->ld_clientid.cl_boot = 0;
3792 deny->ld_clientid.cl_id = 0; 3793 deny->ld_clientid.cl_id = 0;
3793 } 3794 }
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 462c6eff8471..c4dcba3aac1f 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2570,17 +2570,18 @@ nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh
2570static void 2570static void
2571nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld) 2571nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld)
2572{ 2572{
2573 struct xdr_netobj *conf = &ld->ld_owner;
2573 __be32 *p; 2574 __be32 *p;
2574 2575
2575 RESERVE_SPACE(32 + XDR_LEN(ld->ld_sop ? ld->ld_sop->so_owner.len : 0)); 2576 RESERVE_SPACE(32 + XDR_LEN(conf->len));
2576 WRITE64(ld->ld_start); 2577 WRITE64(ld->ld_start);
2577 WRITE64(ld->ld_length); 2578 WRITE64(ld->ld_length);
2578 WRITE32(ld->ld_type); 2579 WRITE32(ld->ld_type);
2579 if (ld->ld_sop) { 2580 if (conf->len) {
2580 WRITEMEM(&ld->ld_clientid, 8); 2581 WRITEMEM(&ld->ld_clientid, 8);
2581 WRITE32(ld->ld_sop->so_owner.len); 2582 WRITE32(conf->len);
2582 WRITEMEM(ld->ld_sop->so_owner.data, ld->ld_sop->so_owner.len); 2583 WRITEMEM(conf->data, conf->len);
2583 kref_put(&ld->ld_sop->so_ref, nfs4_free_stateowner); 2584 kfree(conf->data);
2584 } else { /* non - nfsv4 lock in conflict, no clientid nor owner */ 2585 } else { /* non - nfsv4 lock in conflict, no clientid nor owner */
2585 WRITE64((u64)0); /* clientid */ 2586 WRITE64((u64)0); /* clientid */
2586 WRITE32(0); /* length of owner name */ 2587 WRITE32(0); /* length of owner name */
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index c425717715f6..f7114fc21dee 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -338,7 +338,6 @@ struct nfs4_replay {
338* reaped by laundramat thread after lease period. 338* reaped by laundramat thread after lease period.
339*/ 339*/
340struct nfs4_stateowner { 340struct nfs4_stateowner {
341 struct kref so_ref;
342 struct list_head so_idhash; /* hash by so_id */ 341 struct list_head so_idhash; /* hash by so_id */
343 struct list_head so_strhash; /* hash by op_name */ 342 struct list_head so_strhash; /* hash by op_name */
344 struct list_head so_perclient; 343 struct list_head so_perclient;
@@ -459,7 +458,7 @@ extern void nfs4_lock_state(void);
459extern void nfs4_unlock_state(void); 458extern void nfs4_unlock_state(void);
460extern int nfs4_in_grace(void); 459extern int nfs4_in_grace(void);
461extern __be32 nfs4_check_open_reclaim(clientid_t *clid); 460extern __be32 nfs4_check_open_reclaim(clientid_t *clid);
462extern void nfs4_free_stateowner(struct kref *kref); 461extern void nfs4_free_stateowner(struct nfs4_stateowner *sop);
463extern int set_callback_cred(void); 462extern int set_callback_cred(void);
464extern void nfsd4_probe_callback(struct nfs4_client *clp); 463extern void nfsd4_probe_callback(struct nfs4_client *clp);
465extern void nfsd4_probe_callback_sync(struct nfs4_client *clp); 464extern void nfsd4_probe_callback_sync(struct nfs4_client *clp);
@@ -482,16 +481,4 @@ extern void nfsd4_remove_clid_dir(struct nfs4_client *clp);
482extern void release_session_client(struct nfsd4_session *); 481extern void release_session_client(struct nfsd4_session *);
483extern __be32 nfs4_validate_stateid(stateid_t *, bool); 482extern __be32 nfs4_validate_stateid(stateid_t *, bool);
484 483
485static inline void
486nfs4_put_stateowner(struct nfs4_stateowner *so)
487{
488 kref_put(&so->so_ref, nfs4_free_stateowner);
489}
490
491static inline void
492nfs4_get_stateowner(struct nfs4_stateowner *so)
493{
494 kref_get(&so->so_ref);
495}
496
497#endif /* NFSD4_STATE_H */ 484#endif /* NFSD4_STATE_H */
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 341f0a17d217..de236fb89e74 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -130,7 +130,7 @@ struct nfsd4_link {
130 130
131struct nfsd4_lock_denied { 131struct nfsd4_lock_denied {
132 clientid_t ld_clientid; 132 clientid_t ld_clientid;
133 struct nfs4_stateowner *ld_sop; 133 struct xdr_netobj ld_owner;
134 u64 ld_start; 134 u64 ld_start;
135 u64 ld_length; 135 u64 ld_length;
136 u32 ld_type; 136 u32 ld_type;