On Fri, Sep 9, 2016 at 2:04 PM, Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> wrote: > As described in RFC5661, section 18.46, some of the status flags exist > in order to tell the client when it needs to acknowledge the existence of > revoked state on the server and/or to recover state. > Those flags will then remain set until the recovery procedure is done. > > In order to avoid looping, the client therefore needs to ignore > those particular flags while recovering. > > Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> > --- > fs/nfs/nfs4_fs.h | 2 +- > fs/nfs/nfs4proc.c | 5 ++++- > fs/nfs/nfs4session.h | 1 + > fs/nfs/nfs4state.c | 12 +++++++++++- > 4 files changed, 17 insertions(+), 3 deletions(-) > > diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h > index f230aa62ca59..4390d73a92e5 100644 > --- a/fs/nfs/nfs4_fs.h > +++ b/fs/nfs/nfs4_fs.h > @@ -439,7 +439,7 @@ extern void nfs4_schedule_path_down_recovery(struct nfs_client *clp); > extern int nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *); > extern int nfs4_schedule_migration_recovery(const struct nfs_server *); > extern void nfs4_schedule_lease_moved_recovery(struct nfs_client *); > -extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags); > +extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags, bool); > extern void nfs41_handle_server_scope(struct nfs_client *, > struct nfs41_server_scope **); > extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); > diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c > index 25a2af707233..bd33777f03c4 100644 > --- a/fs/nfs/nfs4proc.c > +++ b/fs/nfs/nfs4proc.c > @@ -616,6 +616,7 @@ int nfs40_setup_sequence(struct nfs4_slot_table *tbl, > } > spin_unlock(&tbl->slot_tbl_lock); > > + slot->privileged = args->sa_privileged ? 1 : 0; > args->sa_slot = slot; > res->sr_slot = slot; > > @@ -728,7 +729,8 @@ static int nfs41_sequence_process(struct rpc_task *task, > clp = session->clp; > do_renew_lease(clp, res->sr_timestamp); > /* Check sequence flags */ > - nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags); > + nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags, > + !!slot->privileged); Is this suppose to be "!!"? > nfs41_update_target_slotid(slot->table, slot, res); > break; > case 1: > @@ -875,6 +877,7 @@ int nfs41_setup_sequence(struct nfs4_session *session, > } > spin_unlock(&tbl->slot_tbl_lock); > > + slot->privileged = args->sa_privileged ? 1 : 0; > args->sa_slot = slot; > > dprintk("<-- %s slotid=%u seqid=%u\n", __func__, > diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h > index 3bb6af70973c..dae385500005 100644 > --- a/fs/nfs/nfs4session.h > +++ b/fs/nfs/nfs4session.h > @@ -23,6 +23,7 @@ struct nfs4_slot { > u32 slot_nr; > u32 seq_nr; > unsigned int interrupted : 1, > + privileged : 1, > seq_done : 1; > }; > > diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c > index cada00aa5096..9801b5bb5fac 100644 > --- a/fs/nfs/nfs4state.c > +++ b/fs/nfs/nfs4state.c > @@ -2227,13 +2227,22 @@ static void nfs41_handle_cb_path_down(struct nfs_client *clp) > nfs4_schedule_state_manager(clp); > } > > -void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags) > +void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags, > + bool recovery) > { > if (!flags) > return; > > dprintk("%s: \"%s\" (client ID %llx) flags=0x%08x\n", > __func__, clp->cl_hostname, clp->cl_clientid, flags); > + /* > + * If we're called from the state manager thread, then assume we're > + * already handling the RECLAIM_NEEDED and/or STATE_REVOKED. > + * Those flags are expected to remain set until we're done > + * recovering (see RFC5661, section 18.46.3). > + */ > + if (recovery) > + goto out_recovery; > > if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED) > nfs41_handle_server_reboot(clp); > @@ -2246,6 +2255,7 @@ void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags) > nfs4_schedule_lease_moved_recovery(clp); > if (flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED) > nfs41_handle_recallable_state_revoked(clp); > +out_recovery: > if (flags & SEQ4_STATUS_BACKCHANNEL_FAULT) > nfs41_handle_backchannel_fault(clp); > else if (flags & (SEQ4_STATUS_CB_PATH_DOWN | > -- > 2.7.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-nfs" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html