X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=fs%2Fnfs%2Fnfs4state.c;h=5ef4c57618fe8507da03dd4dbbd3d9de3aa84dca;hb=3d5271f9883cba7b54762bc4fe027d4172f06db7;hp=2d5a6a2b9dec780616ff5691258a86bc9cea45f6;hpb=d8762748cae4f85b3201c0304969d993b42d5258;p=powerpc.git diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 2d5a6a2b9d..5ef4c57618 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -69,10 +69,8 @@ init_nfsv4_state(struct nfs_server *server) void destroy_nfsv4_state(struct nfs_server *server) { - if (server->mnt_path) { - kfree(server->mnt_path); - server->mnt_path = NULL; - } + kfree(server->mnt_path); + server->mnt_path = NULL; if (server->nfs4_state) { nfs4_put_client(server->nfs4_state); server->nfs4_state = NULL; @@ -311,8 +309,7 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct new = NULL; } spin_unlock(&clp->cl_lock); - if (new) - kfree(new); + kfree(new); if (sp != NULL) return sp; put_rpccred(cred); @@ -366,30 +363,21 @@ nfs4_alloc_open_state(void) return state; } -static struct nfs4_state * -__nfs4_find_state(struct inode *inode, struct rpc_cred *cred, mode_t mode) +void +nfs4_state_set_mode_locked(struct nfs4_state *state, mode_t mode) { - struct nfs_inode *nfsi = NFS_I(inode); - struct nfs4_state *state; - - mode &= (FMODE_READ|FMODE_WRITE); - list_for_each_entry(state, &nfsi->open_states, inode_states) { - if (state->owner->so_cred != cred) - continue; - if ((mode & FMODE_READ) != 0 && state->nreaders == 0) - continue; - if ((mode & FMODE_WRITE) != 0 && state->nwriters == 0) - continue; - if ((state->state & mode) != mode) - continue; - atomic_inc(&state->count); - if (mode & FMODE_READ) - state->nreaders++; + if (state->state == mode) + return; + /* NB! List reordering - see the reclaim code for why. */ + if ((mode & FMODE_WRITE) != (state->state & FMODE_WRITE)) { if (mode & FMODE_WRITE) - state->nwriters++; - return state; + list_move(&state->open_states, &state->owner->so_states); + else + list_move_tail(&state->open_states, &state->owner->so_states); } - return NULL; + if (mode == 0) + list_del_init(&state->inode_states); + state->state = mode; } static struct nfs4_state * @@ -400,7 +388,7 @@ __nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner) list_for_each_entry(state, &nfsi->open_states, inode_states) { /* Is this in the process of being freed? */ - if (state->nreaders == 0 && state->nwriters == 0) + if (state->state == 0) continue; if (state->owner == owner) { atomic_inc(&state->count); @@ -410,17 +398,6 @@ __nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner) return NULL; } -struct nfs4_state * -nfs4_find_state(struct inode *inode, struct rpc_cred *cred, mode_t mode) -{ - struct nfs4_state *state; - - spin_lock(&inode->i_lock); - state = __nfs4_find_state(inode, cred, mode); - spin_unlock(&inode->i_lock); - return state; -} - static void nfs4_free_open_state(struct nfs4_state *state) { @@ -481,7 +458,6 @@ void nfs4_put_open_state(struct nfs4_state *state) spin_unlock(&inode->i_lock); spin_unlock(&owner->so_lock); iput(inode); - BUG_ON (state->state != 0); nfs4_free_open_state(state); nfs4_put_state_owner(owner); } @@ -493,7 +469,7 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode) { struct inode *inode = state->inode; struct nfs4_state_owner *owner = state->owner; - int newstate; + int oldstate, newstate = 0; atomic_inc(&owner->so_count); /* Protect against nfs4_find_state() */ @@ -503,30 +479,20 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode) state->nreaders--; if (mode & FMODE_WRITE) state->nwriters--; - if (state->nwriters == 0) { - if (state->nreaders == 0) - list_del_init(&state->inode_states); - /* See reclaim code */ - list_move_tail(&state->open_states, &owner->so_states); + oldstate = newstate = state->state; + if (state->nreaders == 0) + newstate &= ~FMODE_READ; + if (state->nwriters == 0) + newstate &= ~FMODE_WRITE; + if (test_bit(NFS_DELEGATED_STATE, &state->flags)) { + nfs4_state_set_mode_locked(state, newstate); + oldstate = newstate; } spin_unlock(&inode->i_lock); spin_unlock(&owner->so_lock); - newstate = 0; - if (state->state != 0) { - if (state->nreaders) - newstate |= FMODE_READ; - if (state->nwriters) - newstate |= FMODE_WRITE; - if (state->state == newstate) - goto out; - if (test_bit(NFS_DELEGATED_STATE, &state->flags)) { - state->state = newstate; - goto out; - } - if (nfs4_do_close(inode, state, newstate) == 0) - return; - } -out: + + if (oldstate != newstate && nfs4_do_close(inode, state) == 0) + return; nfs4_put_open_state(state); nfs4_put_state_owner(owner); } @@ -678,12 +644,15 @@ void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t f struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter) { + struct rpc_sequence *sequence = counter->sequence; struct nfs_seqid *new; new = kmalloc(sizeof(*new), GFP_KERNEL); if (new != NULL) { new->sequence = counter; - INIT_LIST_HEAD(&new->list); + spin_lock(&sequence->lock); + list_add_tail(&new->list, &sequence->list); + spin_unlock(&sequence->lock); } return new; } @@ -692,12 +661,10 @@ void nfs_free_seqid(struct nfs_seqid *seqid) { struct rpc_sequence *sequence = seqid->sequence->sequence; - if (!list_empty(&seqid->list)) { - spin_lock(&sequence->lock); - list_del(&seqid->list); - spin_unlock(&sequence->lock); - } - rpc_wake_up_next(&sequence->wait); + spin_lock(&sequence->lock); + list_del(&seqid->list); + spin_unlock(&sequence->lock); + rpc_wake_up(&sequence->wait); kfree(seqid); } @@ -756,11 +723,10 @@ int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task) if (sequence->list.next == &seqid->list) goto out; spin_lock(&sequence->lock); - if (!list_empty(&sequence->list)) { + if (sequence->list.next != &seqid->list) { rpc_sleep_on(&sequence->wait, task, NULL, NULL); status = -EAGAIN; - } else - list_add(&seqid->list, &sequence->list); + } spin_unlock(&sequence->lock); out: return status; @@ -815,7 +781,7 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s int status = 0; for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) { - if (!(fl->fl_flags & FL_POSIX)) + if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) continue; if (((struct nfs_open_context *)fl->fl_file->private_data)->state != state) continue; @@ -830,7 +796,7 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s case -NFS4ERR_NO_GRACE: case -NFS4ERR_RECLAIM_BAD: case -NFS4ERR_RECLAIM_CONFLICT: - /* kill_proc(fl->fl_owner, SIGLOST, 1); */ + /* kill_proc(fl->fl_pid, SIGLOST, 1); */ break; case -NFS4ERR_STALE_CLIENTID: goto out_err;