ceph: queue MDS requests to REJECTED sessions when CLEANRECOVER is set
[linux-2.6-microblaze.git] / fs / ceph / mds_client.c
index 8f1d750..aab8485 100644 (file)
@@ -1595,7 +1595,7 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
                struct ceph_cap_flush *cf;
                struct ceph_mds_client *mdsc = fsc->mdsc;
 
-               if (READ_ONCE(fsc->mount_state) == CEPH_MOUNT_SHUTDOWN) {
+               if (READ_ONCE(fsc->mount_state) >= CEPH_MOUNT_SHUTDOWN) {
                        if (inode->i_data.nrpages > 0)
                                invalidate = true;
                        if (ci->i_wrbuffer_ref > 0)
@@ -2818,10 +2818,6 @@ static void __do_request(struct ceph_mds_client *mdsc,
             ceph_session_state_name(session->s_state));
        if (session->s_state != CEPH_MDS_SESSION_OPEN &&
            session->s_state != CEPH_MDS_SESSION_HUNG) {
-               if (session->s_state == CEPH_MDS_SESSION_REJECTED) {
-                       err = -EACCES;
-                       goto out_session;
-               }
                /*
                 * We cannot queue async requests since the caps and delegated
                 * inodes are bound to the session. Just return -EJUKEBOX and
@@ -2831,6 +2827,20 @@ static void __do_request(struct ceph_mds_client *mdsc,
                        err = -EJUKEBOX;
                        goto out_session;
                }
+
+               /*
+                * If the session has been REJECTED, then return a hard error,
+                * unless it's a CLEANRECOVER mount, in which case we'll queue
+                * it to the mdsc queue.
+                */
+               if (session->s_state == CEPH_MDS_SESSION_REJECTED) {
+                       if (ceph_test_mount_opt(mdsc->fsc, CLEANRECOVER))
+                               list_add(&req->r_wait, &mdsc->waiting_for_map);
+                       else
+                               err = -EACCES;
+                       goto out_session;
+               }
+
                if (session->s_state == CEPH_MDS_SESSION_NEW ||
                    session->s_state == CEPH_MDS_SESSION_CLOSING) {
                        err = __open_session(mdsc, session);
@@ -4374,12 +4384,7 @@ static void maybe_recover_session(struct ceph_mds_client *mdsc)
        if (!READ_ONCE(fsc->blocklisted))
                return;
 
-       if (fsc->last_auto_reconnect &&
-           time_before(jiffies, fsc->last_auto_reconnect + HZ * 60 * 30))
-               return;
-
        pr_info("auto reconnect after blocklisted\n");
-       fsc->last_auto_reconnect = jiffies;
        ceph_force_reconnect(fsc->sb);
 }
 
@@ -4678,7 +4683,7 @@ void ceph_mdsc_sync(struct ceph_mds_client *mdsc)
 {
        u64 want_tid, want_flush;
 
-       if (READ_ONCE(mdsc->fsc->mount_state) == CEPH_MOUNT_SHUTDOWN)
+       if (READ_ONCE(mdsc->fsc->mount_state) >= CEPH_MOUNT_SHUTDOWN)
                return;
 
        dout("sync\n");