aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c53
1 files changed, 27 insertions, 26 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index d5d070fbeb35..32b699bebb9c 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1078,6 +1078,18 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
1078 return NULL; 1078 return NULL;
1079 } 1079 }
1080 clp->cl_name.len = name.len; 1080 clp->cl_name.len = name.len;
1081 INIT_LIST_HEAD(&clp->cl_sessions);
1082 idr_init(&clp->cl_stateids);
1083 atomic_set(&clp->cl_refcount, 0);
1084 clp->cl_cb_state = NFSD4_CB_UNKNOWN;
1085 INIT_LIST_HEAD(&clp->cl_idhash);
1086 INIT_LIST_HEAD(&clp->cl_openowners);
1087 INIT_LIST_HEAD(&clp->cl_delegations);
1088 INIT_LIST_HEAD(&clp->cl_lru);
1089 INIT_LIST_HEAD(&clp->cl_callbacks);
1090 INIT_LIST_HEAD(&clp->cl_revoked);
1091 spin_lock_init(&clp->cl_lock);
1092 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");
1081 return clp; 1093 return clp;
1082} 1094}
1083 1095
@@ -1095,6 +1107,7 @@ free_client(struct nfs4_client *clp)
1095 WARN_ON_ONCE(atomic_read(&ses->se_ref)); 1107 WARN_ON_ONCE(atomic_read(&ses->se_ref));
1096 free_session(ses); 1108 free_session(ses);
1097 } 1109 }
1110 rpc_destroy_wait_queue(&clp->cl_cb_waitq);
1098 free_svc_cred(&clp->cl_cred); 1111 free_svc_cred(&clp->cl_cred);
1099 kfree(clp->cl_name.data); 1112 kfree(clp->cl_name.data);
1100 idr_destroy(&clp->cl_stateids); 1113 idr_destroy(&clp->cl_stateids);
@@ -1347,7 +1360,6 @@ static struct nfs4_client *create_client(struct xdr_netobj name,
1347 if (clp == NULL) 1360 if (clp == NULL)
1348 return NULL; 1361 return NULL;
1349 1362
1350 INIT_LIST_HEAD(&clp->cl_sessions);
1351 ret = copy_cred(&clp->cl_cred, &rqstp->rq_cred); 1363 ret = copy_cred(&clp->cl_cred, &rqstp->rq_cred);
1352 if (ret) { 1364 if (ret) {
1353 spin_lock(&nn->client_lock); 1365 spin_lock(&nn->client_lock);
@@ -1355,20 +1367,9 @@ static struct nfs4_client *create_client(struct xdr_netobj name,
1355 spin_unlock(&nn->client_lock); 1367 spin_unlock(&nn->client_lock);
1356 return NULL; 1368 return NULL;
1357 } 1369 }
1358 idr_init(&clp->cl_stateids);
1359 atomic_set(&clp->cl_refcount, 0);
1360 clp->cl_cb_state = NFSD4_CB_UNKNOWN;
1361 INIT_LIST_HEAD(&clp->cl_idhash);
1362 INIT_LIST_HEAD(&clp->cl_openowners);
1363 INIT_LIST_HEAD(&clp->cl_delegations);
1364 INIT_LIST_HEAD(&clp->cl_lru);
1365 INIT_LIST_HEAD(&clp->cl_callbacks);
1366 INIT_LIST_HEAD(&clp->cl_revoked);
1367 spin_lock_init(&clp->cl_lock);
1368 nfsd4_init_callback(&clp->cl_cb_null); 1370 nfsd4_init_callback(&clp->cl_cb_null);
1369 clp->cl_time = get_seconds(); 1371 clp->cl_time = get_seconds();
1370 clear_bit(0, &clp->cl_cb_slot_busy); 1372 clear_bit(0, &clp->cl_cb_slot_busy);
1371 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");
1372 copy_verf(clp, verf); 1373 copy_verf(clp, verf);
1373 rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa); 1374 rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa);
1374 gen_confirm(clp); 1375 gen_confirm(clp);
@@ -1538,7 +1539,7 @@ out_err:
1538} 1539}
1539 1540
1540/* 1541/*
1541 * Cache a reply. nfsd4_check_drc_limit() has bounded the cache size. 1542 * Cache a reply. nfsd4_check_resp_size() has bounded the cache size.
1542 */ 1543 */
1543void 1544void
1544nfsd4_store_cache_entry(struct nfsd4_compoundres *resp) 1545nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
@@ -1596,7 +1597,7 @@ nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args,
1596 * The sequence operation is not cached because we can use the slot and 1597 * The sequence operation is not cached because we can use the slot and
1597 * session values. 1598 * session values.
1598 */ 1599 */
1599__be32 1600static __be32
1600nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, 1601nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
1601 struct nfsd4_sequence *seq) 1602 struct nfsd4_sequence *seq)
1602{ 1603{
@@ -1605,9 +1606,8 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
1605 1606
1606 dprintk("--> %s slot %p\n", __func__, slot); 1607 dprintk("--> %s slot %p\n", __func__, slot);
1607 1608
1608 /* Either returns 0 or nfserr_retry_uncached */
1609 status = nfsd4_enc_sequence_replay(resp->rqstp->rq_argp, resp); 1609 status = nfsd4_enc_sequence_replay(resp->rqstp->rq_argp, resp);
1610 if (status == nfserr_retry_uncached_rep) 1610 if (status)
1611 return status; 1611 return status;
1612 1612
1613 /* The sequence operation has been encoded, cstate->datap set. */ 1613 /* The sequence operation has been encoded, cstate->datap set. */
@@ -2287,7 +2287,8 @@ out:
2287 if (!list_empty(&clp->cl_revoked)) 2287 if (!list_empty(&clp->cl_revoked))
2288 seq->status_flags |= SEQ4_STATUS_RECALLABLE_STATE_REVOKED; 2288 seq->status_flags |= SEQ4_STATUS_RECALLABLE_STATE_REVOKED;
2289out_no_session: 2289out_no_session:
2290 kfree(conn); 2290 if (conn)
2291 free_conn(conn);
2291 spin_unlock(&nn->client_lock); 2292 spin_unlock(&nn->client_lock);
2292 return status; 2293 return status;
2293out_put_session: 2294out_put_session:
@@ -3627,8 +3628,11 @@ static __be32 nfsd4_lookup_stateid(stateid_t *stateid, unsigned char typemask,
3627 return nfserr_bad_stateid; 3628 return nfserr_bad_stateid;
3628 status = lookup_clientid(&stateid->si_opaque.so_clid, sessions, 3629 status = lookup_clientid(&stateid->si_opaque.so_clid, sessions,
3629 nn, &cl); 3630 nn, &cl);
3630 if (status == nfserr_stale_clientid) 3631 if (status == nfserr_stale_clientid) {
3632 if (sessions)
3633 return nfserr_bad_stateid;
3631 return nfserr_stale_stateid; 3634 return nfserr_stale_stateid;
3635 }
3632 if (status) 3636 if (status)
3633 return status; 3637 return status;
3634 *s = find_stateid_by_type(cl, stateid, typemask); 3638 *s = find_stateid_by_type(cl, stateid, typemask);
@@ -5062,7 +5066,6 @@ nfs4_state_destroy_net(struct net *net)
5062 int i; 5066 int i;
5063 struct nfs4_client *clp = NULL; 5067 struct nfs4_client *clp = NULL;
5064 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 5068 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
5065 struct rb_node *node, *tmp;
5066 5069
5067 for (i = 0; i < CLIENT_HASH_SIZE; i++) { 5070 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
5068 while (!list_empty(&nn->conf_id_hashtbl[i])) { 5071 while (!list_empty(&nn->conf_id_hashtbl[i])) {
@@ -5071,13 +5074,11 @@ nfs4_state_destroy_net(struct net *net)
5071 } 5074 }
5072 } 5075 }
5073 5076
5074 node = rb_first(&nn->unconf_name_tree); 5077 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
5075 while (node != NULL) { 5078 while (!list_empty(&nn->unconf_id_hashtbl[i])) {
5076 tmp = node; 5079 clp = list_entry(nn->unconf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
5077 node = rb_next(tmp); 5080 destroy_client(clp);
5078 clp = rb_entry(tmp, struct nfs4_client, cl_namenode); 5081 }
5079 rb_erase(tmp, &nn->unconf_name_tree);
5080 destroy_client(clp);
5081 } 5082 }
5082 5083
5083 kfree(nn->sessionid_hashtbl); 5084 kfree(nn->sessionid_hashtbl);