Commit 4ae3713f authored by Jeff Layton's avatar Jeff Layton Committed by Ilya Dryomov

ceph: queue MDS requests to REJECTED sessions when CLEANRECOVER is set

Ilya noticed that the first access to a blacklisted mount would often
get back -EACCES, but then subsequent calls would be OK. The problem is
in __do_request. If the session is marked as REJECTED, a hard error is
returned instead of waiting for a new session to come into being.

When the session is REJECTED and the mount was done with
recover_session=clean, queue the request to the waiting_for_map queue,
which will be awoken after tearing down the old session. We can only
do this for sync requests though, so check for async ones first and
just let the callers redrive a sync request.

URL: https://tracker.ceph.com/issues/47385Reported-by: default avatarIlya Dryomov <idryomov@gmail.com>
Signed-off-by: default avatarJeff Layton <jlayton@kernel.org>
Reviewed-by: default avatarXiubo Li <xiubli@redhat.com>
Reviewed-by: default avatar"Yan, Zheng" <zyan@redhat.com>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent dbeec07b
...@@ -2818,10 +2818,6 @@ static void __do_request(struct ceph_mds_client *mdsc, ...@@ -2818,10 +2818,6 @@ static void __do_request(struct ceph_mds_client *mdsc,
ceph_session_state_name(session->s_state)); ceph_session_state_name(session->s_state));
if (session->s_state != CEPH_MDS_SESSION_OPEN && if (session->s_state != CEPH_MDS_SESSION_OPEN &&
session->s_state != CEPH_MDS_SESSION_HUNG) { 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 * We cannot queue async requests since the caps and delegated
* inodes are bound to the session. Just return -EJUKEBOX and * inodes are bound to the session. Just return -EJUKEBOX and
...@@ -2831,6 +2827,20 @@ static void __do_request(struct ceph_mds_client *mdsc, ...@@ -2831,6 +2827,20 @@ static void __do_request(struct ceph_mds_client *mdsc,
err = -EJUKEBOX; err = -EJUKEBOX;
goto out_session; 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 || if (session->s_state == CEPH_MDS_SESSION_NEW ||
session->s_state == CEPH_MDS_SESSION_CLOSING) { session->s_state == CEPH_MDS_SESSION_CLOSING) {
err = __open_session(mdsc, session); err = __open_session(mdsc, session);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment