diff options
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r-- | fs/nfs/nfs4state.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 9448c579d41a..6ace365c6334 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -136,16 +136,11 @@ int nfs40_discover_server_trunking(struct nfs_client *clp, | |||
136 | clp->cl_confirm = clid.confirm; | 136 | clp->cl_confirm = clid.confirm; |
137 | 137 | ||
138 | status = nfs40_walk_client_list(clp, result, cred); | 138 | status = nfs40_walk_client_list(clp, result, cred); |
139 | switch (status) { | 139 | if (status == 0) { |
140 | case -NFS4ERR_STALE_CLIENTID: | ||
141 | set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); | ||
142 | case 0: | ||
143 | /* Sustain the lease, even if it's empty. If the clientid4 | 140 | /* Sustain the lease, even if it's empty. If the clientid4 |
144 | * goes stale it's of no use for trunking discovery. */ | 141 | * goes stale it's of no use for trunking discovery. */ |
145 | nfs4_schedule_state_renewal(*result); | 142 | nfs4_schedule_state_renewal(*result); |
146 | break; | ||
147 | } | 143 | } |
148 | |||
149 | out: | 144 | out: |
150 | return status; | 145 | return status; |
151 | } | 146 | } |
@@ -523,6 +518,8 @@ nfs4_alloc_state_owner(struct nfs_server *server, | |||
523 | nfs4_init_seqid_counter(&sp->so_seqid); | 518 | nfs4_init_seqid_counter(&sp->so_seqid); |
524 | atomic_set(&sp->so_count, 1); | 519 | atomic_set(&sp->so_count, 1); |
525 | INIT_LIST_HEAD(&sp->so_lru); | 520 | INIT_LIST_HEAD(&sp->so_lru); |
521 | seqcount_init(&sp->so_reclaim_seqcount); | ||
522 | mutex_init(&sp->so_delegreturn_mutex); | ||
526 | return sp; | 523 | return sp; |
527 | } | 524 | } |
528 | 525 | ||
@@ -1395,8 +1392,9 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs | |||
1395 | * recovering after a network partition or a reboot from a | 1392 | * recovering after a network partition or a reboot from a |
1396 | * server that doesn't support a grace period. | 1393 | * server that doesn't support a grace period. |
1397 | */ | 1394 | */ |
1398 | restart: | ||
1399 | spin_lock(&sp->so_lock); | 1395 | spin_lock(&sp->so_lock); |
1396 | write_seqcount_begin(&sp->so_reclaim_seqcount); | ||
1397 | restart: | ||
1400 | list_for_each_entry(state, &sp->so_states, open_states) { | 1398 | list_for_each_entry(state, &sp->so_states, open_states) { |
1401 | if (!test_and_clear_bit(ops->state_flag_bit, &state->flags)) | 1399 | if (!test_and_clear_bit(ops->state_flag_bit, &state->flags)) |
1402 | continue; | 1400 | continue; |
@@ -1417,6 +1415,7 @@ restart: | |||
1417 | } | 1415 | } |
1418 | spin_unlock(&state->state_lock); | 1416 | spin_unlock(&state->state_lock); |
1419 | nfs4_put_open_state(state); | 1417 | nfs4_put_open_state(state); |
1418 | spin_lock(&sp->so_lock); | ||
1420 | goto restart; | 1419 | goto restart; |
1421 | } | 1420 | } |
1422 | } | 1421 | } |
@@ -1454,12 +1453,17 @@ restart: | |||
1454 | goto out_err; | 1453 | goto out_err; |
1455 | } | 1454 | } |
1456 | nfs4_put_open_state(state); | 1455 | nfs4_put_open_state(state); |
1456 | spin_lock(&sp->so_lock); | ||
1457 | goto restart; | 1457 | goto restart; |
1458 | } | 1458 | } |
1459 | write_seqcount_end(&sp->so_reclaim_seqcount); | ||
1459 | spin_unlock(&sp->so_lock); | 1460 | spin_unlock(&sp->so_lock); |
1460 | return 0; | 1461 | return 0; |
1461 | out_err: | 1462 | out_err: |
1462 | nfs4_put_open_state(state); | 1463 | nfs4_put_open_state(state); |
1464 | spin_lock(&sp->so_lock); | ||
1465 | write_seqcount_end(&sp->so_reclaim_seqcount); | ||
1466 | spin_unlock(&sp->so_lock); | ||
1463 | return status; | 1467 | return status; |
1464 | } | 1468 | } |
1465 | 1469 | ||
@@ -1863,6 +1867,7 @@ again: | |||
1863 | case -ETIMEDOUT: | 1867 | case -ETIMEDOUT: |
1864 | case -EAGAIN: | 1868 | case -EAGAIN: |
1865 | ssleep(1); | 1869 | ssleep(1); |
1870 | case -NFS4ERR_STALE_CLIENTID: | ||
1866 | dprintk("NFS: %s after status %d, retrying\n", | 1871 | dprintk("NFS: %s after status %d, retrying\n", |
1867 | __func__, status); | 1872 | __func__, status); |
1868 | goto again; | 1873 | goto again; |
@@ -2022,8 +2027,18 @@ static int nfs4_reset_session(struct nfs_client *clp) | |||
2022 | nfs4_begin_drain_session(clp); | 2027 | nfs4_begin_drain_session(clp); |
2023 | cred = nfs4_get_exchange_id_cred(clp); | 2028 | cred = nfs4_get_exchange_id_cred(clp); |
2024 | status = nfs4_proc_destroy_session(clp->cl_session, cred); | 2029 | status = nfs4_proc_destroy_session(clp->cl_session, cred); |
2025 | if (status && status != -NFS4ERR_BADSESSION && | 2030 | switch (status) { |
2026 | status != -NFS4ERR_DEADSESSION) { | 2031 | case 0: |
2032 | case -NFS4ERR_BADSESSION: | ||
2033 | case -NFS4ERR_DEADSESSION: | ||
2034 | break; | ||
2035 | case -NFS4ERR_BACK_CHAN_BUSY: | ||
2036 | case -NFS4ERR_DELAY: | ||
2037 | set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); | ||
2038 | status = 0; | ||
2039 | ssleep(1); | ||
2040 | goto out; | ||
2041 | default: | ||
2027 | status = nfs4_recovery_handle_error(clp, status); | 2042 | status = nfs4_recovery_handle_error(clp, status); |
2028 | goto out; | 2043 | goto out; |
2029 | } | 2044 | } |