inode.c | 4 ++-- nfs4state.c | 22 +++++++++++++++------- 2 files changed, 17 insertions(+), 9 deletions(-) diff -u --recursive --new-file --show-c-function linux-2.6.4-rc1/fs/nfs/inode.c linux-2.6.4-patch/fs/nfs/inode.c --- linux-2.6.4-rc1/fs/nfs/inode.c 2004-03-01 19:29:35.000000000 -0500 +++ linux-2.6.4-patch/fs/nfs/inode.c 2004-03-03 13:17:10.000000000 -0500 @@ -1391,8 +1391,8 @@ static void nfs4_clear_inode(struct inod 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); diff -u --recursive --new-file --show-c-function linux-2.6.4-rc1/fs/nfs/nfs4state.c linux-2.6.4-patch/fs/nfs/nfs4state.c --- linux-2.6.4-rc1/fs/nfs/nfs4state.c 2004-03-01 19:11:56.000000000 -0500 +++ linux-2.6.4-patch/fs/nfs/nfs4state.c 2004-03-03 13:24:06.000000000 -0500 @@ -411,18 +411,20 @@ out: 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 { @@ -440,6 +442,13 @@ nfs4_put_open_state(struct nfs4_state *s } 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) { struct inode *inode = state->inode; @@ -479,8 +488,7 @@ nfs4_close_state(struct nfs4_state *stat 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); } /*