diff options
-rw-r--r-- | fs/nfs/nfs4_fs.h | 3 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 10 |
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 | |||
16 | struct idmap; | 18 | struct idmap; |
17 | 19 | ||
18 | enum nfs4_client_state { | 20 | enum 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 | ||
95 | enum { | 98 | enum { |
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 | */ |
1393 | restart: | ||
1394 | spin_lock(&sp->so_lock); | 1394 | spin_lock(&sp->so_lock); |
1395 | write_seqcount_begin(&sp->so_reclaim_seqcount); | ||
1396 | restart: | ||
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; |
1456 | out_err: | 1461 | out_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 | ||