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);
 
        }
        spin_unlock(&tbl->slot_tbl_lock);
 
+       slot->privileged = args->sa_privileged ? 1 : 0;
        args->sa_slot = slot;
        res->sr_slot = slot;
 
                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);
                nfs41_update_target_slotid(slot->table, slot, res);
                break;
        case 1:
        }
        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__,
 
        u32                     slot_nr;
        u32                     seq_nr;
        unsigned int            interrupted : 1,
+                               privileged : 1,
                                seq_done : 1;
 };
 
 
                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);
                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 |