The logic was becoming difficult to follow. Add some comments and local variables to clarify the behavior. Signed-off-by: Benjamin Coddington <bcodding@xxxxxxxxxx> --- fs/nfs/nfs4proc.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 9ced7a62c05e..827659ee1fad 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1568,22 +1568,25 @@ static void nfs_test_and_clear_all_open_stateid(struct nfs4_state *state) static bool nfs_need_update_open_stateid(struct nfs4_state *state, const nfs4_stateid *stateid) { - if (test_bit(NFS_OPEN_STATE, &state->flags) == 0 || - !nfs4_stateid_match_other(stateid, &state->open_stateid)) { - if (stateid->seqid == cpu_to_be32(1)) { + bool state_matches_other = nfs4_stateid_match_other(stateid, &state->open_stateid); + bool seqid_one = stateid->seqid == cpu_to_be32(1); + + if (test_bit(NFS_OPEN_STATE, &state->flags)) { + /* The common case - we're updating to a new sequence number */ + if (state_matches_other && nfs4_stateid_is_newer(stateid, &state->open_stateid)) { + nfs_state_log_out_of_order_open_stateid(state, stateid); + return true; + } + } else { + /* This is the first OPEN */ + if (!state_matches_other && seqid_one) { nfs_state_log_update_open_stateid(state); - } else { - if (!nfs4_stateid_match_other(stateid, &state->open_stateid)) - return false; - else - set_bit(NFS_STATE_CHANGE_WAIT, &state->flags); + return true; + } + if (!state_matches_other && !seqid_one) { + set_bit(NFS_STATE_CHANGE_WAIT, &state->flags); + return true; } - return true; - } - - if (nfs4_stateid_is_newer(stateid, &state->open_stateid)) { - nfs_state_log_out_of_order_open_stateid(state, stateid); - return true; } return false; } -- 2.20.1