diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-03-09 02:42:01 +0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-03-09 07:38:55 +0400 |
commit | 4fc8796d23819da814ec25b7793bde8f104f1a2a (patch) | |
tree | d86513109dd792087091b6054a983271b2536f60 /fs/nfs/nfs4state.c | |
parent | 0032a7a749a49b2c044092a1d0af5cfd0077f35d (diff) | |
download | linux-4fc8796d23819da814ec25b7793bde8f104f1a2a.tar.xz |
NFSv4: Clean up nfs4_select_rw_stateid()
Ensure that we select delegation stateids first, then
lock stateids and then open stateids.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r-- | fs/nfs/nfs4state.c | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 7adc46b4c7f8..de44804d9864 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -886,28 +886,49 @@ int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl) return 0; } -/* - * Byte-range lock aware utility to initialize the stateid of read/write - * requests. - */ -void nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_pid) +static bool nfs4_copy_lock_stateid(nfs4_stateid *dst, struct nfs4_state *state, + fl_owner_t fl_owner, pid_t fl_pid) { struct nfs4_lock_state *lsp; - int seq; + bool ret = false; - do { - seq = read_seqbegin(&state->seqlock); - nfs4_stateid_copy(dst, &state->stateid); - } while (read_seqretry(&state->seqlock, seq)); if (test_bit(LK_STATE_IN_USE, &state->flags) == 0) - return; + goto out; spin_lock(&state->state_lock); lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE); - if (lsp != NULL && (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) + if (lsp != NULL && (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) { nfs4_stateid_copy(dst, &lsp->ls_stateid); + ret = true; + } spin_unlock(&state->state_lock); nfs4_put_lock_state(lsp); +out: + return ret; +} + +static void nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state) +{ + int seq; + + do { + seq = read_seqbegin(&state->seqlock); + nfs4_stateid_copy(dst, &state->stateid); + } while (read_seqretry(&state->seqlock, seq)); +} + +/* + * Byte-range lock aware utility to initialize the stateid of read/write + * requests. + */ +void nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state, + fmode_t fmode, fl_owner_t fl_owner, pid_t fl_pid) +{ + if (nfs4_copy_delegation_stateid(dst, state->inode, fmode)) + return; + if (nfs4_copy_lock_stateid(dst, state, fl_owner, fl_pid)) + return; + nfs4_copy_open_stateid(dst, state); } struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask) |