diff options
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 53 |
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 | */ |
1543 | void | 1544 | void |
1544 | nfsd4_store_cache_entry(struct nfsd4_compoundres *resp) | 1545 | nfsd4_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 | 1600 | static __be32 |
1600 | nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, | 1601 | nfsd4_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; |
2289 | out_no_session: | 2289 | out_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; |
2293 | out_put_session: | 2294 | out_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); |