aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/nfs4_fs.h3
-rw-r--r--fs/nfs/nfs4state.c10
2 files changed, 12 insertions, 1 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index a3f488b074a2..b12b73472020 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -13,6 +13,8 @@
13 13
14#define NFS4_MAX_LOOP_ON_RECOVER (10) 14#define NFS4_MAX_LOOP_ON_RECOVER (10)
15 15
16#include <linux/seqlock.h>
17
16struct idmap; 18struct idmap;
17 19
18enum nfs4_client_state { 20enum nfs4_client_state {
@@ -90,6 +92,7 @@ struct nfs4_state_owner {
90 unsigned long so_flags; 92 unsigned long so_flags;
91 struct list_head so_states; 93 struct list_head so_states;
92 struct nfs_seqid_counter so_seqid; 94 struct nfs_seqid_counter so_seqid;
95 seqcount_t so_reclaim_seqcount;
93}; 96};
94 97
95enum { 98enum {
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index e61f68d5ef21..fff97228cdec 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -518,6 +518,7 @@ nfs4_alloc_state_owner(struct nfs_server *server,
518 nfs4_init_seqid_counter(&sp->so_seqid); 518 nfs4_init_seqid_counter(&sp->so_seqid);
519 atomic_set(&sp->so_count, 1); 519 atomic_set(&sp->so_count, 1);
520 INIT_LIST_HEAD(&sp->so_lru); 520 INIT_LIST_HEAD(&sp->so_lru);
521 seqcount_init(&sp->so_reclaim_seqcount);
521 return sp; 522 return sp;
522} 523}
523 524
@@ -1390,8 +1391,9 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs
1390 * recovering after a network partition or a reboot from a 1391 * recovering after a network partition or a reboot from a
1391 * server that doesn't support a grace period. 1392 * server that doesn't support a grace period.
1392 */ 1393 */
1393restart:
1394 spin_lock(&sp->so_lock); 1394 spin_lock(&sp->so_lock);
1395 write_seqcount_begin(&sp->so_reclaim_seqcount);
1396restart:
1395 list_for_each_entry(state, &sp->so_states, open_states) { 1397 list_for_each_entry(state, &sp->so_states, open_states) {
1396 if (!test_and_clear_bit(ops->state_flag_bit, &state->flags)) 1398 if (!test_and_clear_bit(ops->state_flag_bit, &state->flags))
1397 continue; 1399 continue;
@@ -1412,6 +1414,7 @@ restart:
1412 } 1414 }
1413 spin_unlock(&state->state_lock); 1415 spin_unlock(&state->state_lock);
1414 nfs4_put_open_state(state); 1416 nfs4_put_open_state(state);
1417 spin_lock(&sp->so_lock);
1415 goto restart; 1418 goto restart;
1416 } 1419 }
1417 } 1420 }
@@ -1449,12 +1452,17 @@ restart:
1449 goto out_err; 1452 goto out_err;
1450 } 1453 }
1451 nfs4_put_open_state(state); 1454 nfs4_put_open_state(state);
1455 spin_lock(&sp->so_lock);
1452 goto restart; 1456 goto restart;
1453 } 1457 }
1458 write_seqcount_end(&sp->so_reclaim_seqcount);
1454 spin_unlock(&sp->so_lock); 1459 spin_unlock(&sp->so_lock);
1455 return 0; 1460 return 0;
1456out_err: 1461out_err:
1457 nfs4_put_open_state(state); 1462 nfs4_put_open_state(state);
1463 spin_lock(&sp->so_lock);
1464 write_seqcount_end(&sp->so_reclaim_seqcount);
1465 spin_unlock(&sp->so_lock);
1458 return status; 1466 return status;
1459} 1467}
1460 1468