Commit a5210eec authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: Fix a list corruption in the NFSv4 state engine.

parent 8d2a4538
......@@ -1407,8 +1407,8 @@ static void nfs4_clear_inode(struct inode *inode)
inode->i_sb->s_id,
(long long)NFS_FILEID(inode),
state);
list_del(&state->inode_states);
nfs4_put_open_state(state);
BUG_ON(atomic_read(&state->count) != 1);
nfs4_close_state(state, state->state);
}
/* Now call standard NFS clear_inode() code */
nfs_clear_inode(inode);
......
......@@ -411,18 +411,20 @@ nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner)
return state;
}
void
nfs4_put_open_state(struct nfs4_state *state)
static void
__nfs4_put_open_state(struct nfs4_state *state)
{
struct inode *inode = state->inode;
struct nfs4_state_owner *owner = state->owner;
int status = 0;
if (!atomic_dec_and_lock(&state->count, &inode->i_lock))
if (!atomic_dec_and_lock(&state->count, &inode->i_lock)) {
up(&owner->so_sema);
return;
list_del(&state->inode_states);
}
if (!list_empty(&state->inode_states))
list_del(&state->inode_states);
spin_unlock(&inode->i_lock);
down(&owner->so_sema);
list_del(&state->open_states);
if (state->state != 0) {
do {
......@@ -439,6 +441,13 @@ nfs4_put_open_state(struct nfs4_state *state)
nfs4_put_state_owner(owner);
}
void
nfs4_put_open_state(struct nfs4_state *state)
{
down(&state->owner->so_sema);
__nfs4_put_open_state(state);
}
void
nfs4_close_state(struct nfs4_state *state, mode_t mode)
{
......@@ -479,8 +488,7 @@ nfs4_close_state(struct nfs4_state *state, mode_t mode)
status = nfs4_handle_error(NFS_SERVER(inode), status);
down(&owner->so_sema);
} while (!status);
up(&owner->so_sema);
nfs4_put_open_state(state);
__nfs4_put_open_state(state);
}
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment