aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-03-08 17:42:01 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-03-08 22:38:55 -0500
commit4fc8796d23819da814ec25b7793bde8f104f1a2a (patch)
treed86513109dd792087091b6054a983271b2536f60 /fs/nfs/nfs4state.c
parent0032a7a749a49b2c044092a1d0af5cfd0077f35d (diff)
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.c45
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)
886 return 0; 886 return 0;
887} 887}
888 888
889/* 889static bool nfs4_copy_lock_stateid(nfs4_stateid *dst, struct nfs4_state *state,
890 * Byte-range lock aware utility to initialize the stateid of read/write 890 fl_owner_t fl_owner, pid_t fl_pid)
891 * requests.
892 */
893void nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_pid)
894{ 891{
895 struct nfs4_lock_state *lsp; 892 struct nfs4_lock_state *lsp;
896 int seq; 893 bool ret = false;
897 894
898 do {
899 seq = read_seqbegin(&state->seqlock);
900 nfs4_stateid_copy(dst, &state->stateid);
901 } while (read_seqretry(&state->seqlock, seq));
902 if (test_bit(LK_STATE_IN_USE, &state->flags) == 0) 895 if (test_bit(LK_STATE_IN_USE, &state->flags) == 0)
903 return; 896 goto out;
904 897
905 spin_lock(&state->state_lock); 898 spin_lock(&state->state_lock);
906 lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE); 899 lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE);
907 if (lsp != NULL && (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) 900 if (lsp != NULL && (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) {
908 nfs4_stateid_copy(dst, &lsp->ls_stateid); 901 nfs4_stateid_copy(dst, &lsp->ls_stateid);
902 ret = true;
903 }
909 spin_unlock(&state->state_lock); 904 spin_unlock(&state->state_lock);
910 nfs4_put_lock_state(lsp); 905 nfs4_put_lock_state(lsp);
906out:
907 return ret;
908}
909
910static void nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
911{
912 int seq;
913
914 do {
915 seq = read_seqbegin(&state->seqlock);
916 nfs4_stateid_copy(dst, &state->stateid);
917 } while (read_seqretry(&state->seqlock, seq));
918}
919
920/*
921 * Byte-range lock aware utility to initialize the stateid of read/write
922 * requests.
923 */
924void nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state,
925 fmode_t fmode, fl_owner_t fl_owner, pid_t fl_pid)
926{
927 if (nfs4_copy_delegation_stateid(dst, state->inode, fmode))
928 return;
929 if (nfs4_copy_lock_stateid(dst, state, fl_owner, fl_pid))
930 return;
931 nfs4_copy_open_stateid(dst, state);
911} 932}
912 933
913struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask) 934struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask)