summaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4state.c
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/nfs/nfs4state.c
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/nfs/nfs4state.c')
-rw-r--r--fs/nfs/nfs4state.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index e61f68d5ef2..fff97228cde 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -518,6 +518,7 @@ nfs4_alloc_state_owner(struct nfs_server *server,
nfs4_init_seqid_counter(&sp->so_seqid);
atomic_set(&sp->so_count, 1);
INIT_LIST_HEAD(&sp->so_lru);
+ seqcount_init(&sp->so_reclaim_seqcount);
return sp;
}
@@ -1390,8 +1391,9 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs
* recovering after a network partition or a reboot from a
* server that doesn't support a grace period.
*/
-restart:
spin_lock(&sp->so_lock);
+ write_seqcount_begin(&sp->so_reclaim_seqcount);
+restart:
list_for_each_entry(state, &sp->so_states, open_states) {
if (!test_and_clear_bit(ops->state_flag_bit, &state->flags))
continue;
@@ -1412,6 +1414,7 @@ restart:
}
spin_unlock(&state->state_lock);
nfs4_put_open_state(state);
+ spin_lock(&sp->so_lock);
goto restart;
}
}
@@ -1449,12 +1452,17 @@ restart:
goto out_err;
}
nfs4_put_open_state(state);
+ spin_lock(&sp->so_lock);
goto restart;
}
+ write_seqcount_end(&sp->so_reclaim_seqcount);
spin_unlock(&sp->so_lock);
return 0;
out_err:
nfs4_put_open_state(state);
+ spin_lock(&sp->so_lock);
+ write_seqcount_end(&sp->so_reclaim_seqcount);
+ spin_unlock(&sp->so_lock);
return status;
}