aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2013-02-07 14:41:11 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-02-11 15:33:11 -0500
commitc137afabe330f64eddcd4dd281258807e27fd430 (patch)
tree01731471a78543c769e73e03148ade6b5cb73518 /fs
parentc5f5e9c5d2e9178fb0bfe4f44f0afcc8ad6488ef (diff)
NFSv4: Allow the state manager to mark an open_owner as being recovered
This patch adds a seqcount_t lock for use by the state manager to signal that an open owner has been recovered. This mechanism will be used by the delegation, open and byte range lock code in order to figure out if they need to replay requests due to collisions with lock recovery. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-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