summaryrefslogtreecommitdiff
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2007-07-09 10:45:42 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-07-10 23:40:43 -0400
commit8bda4e4c98d14566fc1a354c62fb59d70cc49b97 (patch)
treed137e784db33d1347a6b03d22044e9a41e10967f /fs/nfs/nfs4state.c
parent1ac7e2fd35905f3d44df06568bca5f9d140369b3 (diff)
downloadlwn-8bda4e4c98d14566fc1a354c62fb59d70cc49b97.tar.gz
lwn-8bda4e4c98d14566fc1a354c62fb59d70cc49b97.zip
NFSv4: Fix up stateid locking...
We really don't need to grab both the state->so_owner and the inode->i_lock. 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, 6 insertions, 4 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 4fa4054cdf34..523cc2cbb5e1 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -307,6 +307,7 @@ nfs4_alloc_open_state(void)
atomic_set(&state->count, 1);
INIT_LIST_HEAD(&state->lock_states);
spin_lock_init(&state->state_lock);
+ seqlock_init(&state->seqlock);
return state;
}
@@ -411,7 +412,6 @@ void nfs4_put_open_state(struct nfs4_state *state)
*/
void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
{
- struct inode *inode = state->inode;
struct nfs4_state_owner *owner = state->owner;
int call_close = 0;
int newstate;
@@ -419,7 +419,6 @@ void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
atomic_inc(&owner->so_count);
/* Protect against nfs4_find_state() */
spin_lock(&owner->so_lock);
- spin_lock(&inode->i_lock);
switch (mode & (FMODE_READ | FMODE_WRITE)) {
case FMODE_READ:
state->n_rdonly--;
@@ -446,7 +445,6 @@ void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
clear_bit(NFS_DELEGATED_STATE, &state->flags);
}
nfs4_state_set_mode_locked(state, newstate);
- spin_unlock(&inode->i_lock);
spin_unlock(&owner->so_lock);
if (!call_close) {
@@ -599,8 +597,12 @@ int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl)
void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t fl_owner)
{
struct nfs4_lock_state *lsp;
+ int seq;
- memcpy(dst, &state->stateid, sizeof(*dst));
+ do {
+ seq = read_seqbegin(&state->seqlock);
+ memcpy(dst, &state->stateid, sizeof(*dst));
+ } while (read_seqretry(&state->seqlock, seq));
if (test_bit(LK_STATE_IN_USE, &state->flags) == 0)
return;