]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
ceph: add flag to designate that a request is asynchronous
authorJeff Layton <jlayton@kernel.org>
Mon, 2 Dec 2019 18:47:57 +0000 (13:47 -0500)
committerIlya Dryomov <idryomov@gmail.com>
Mon, 30 Mar 2020 10:42:41 +0000 (12:42 +0200)
...and ensure that such requests are never queued. The MDS has need to
know that a request is asynchronous so add flags and proper
infrastructure for that.

Also, delegated inode numbers and directory caps are associated with the
session, so ensure that async requests are always transmitted on the
first attempt and are never queued to wait for session reestablishment.

If it does end up looking like we'll need to queue the request, then
have it return -EJUKEBOX so the caller can reattempt with a synchronous
request.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/mds_client.h
include/linux/ceph/ceph_fs.h

index 094b8fc377878c6c8066fa7d34ff754d6095946b..9869ec101e8898a3545c960779610ae5b9b8c4a1 100644 (file)
@@ -1311,6 +1311,7 @@ retry_lookup:
                err = fill_inode(in, req->r_locked_page, &rinfo->targeti, NULL,
                                session,
                                (!test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags) &&
+                                !test_bit(CEPH_MDS_R_ASYNC, &req->r_req_flags) &&
                                 rinfo->head->result == 0) ?  req->r_fmode : -1,
                                &req->r_caps_reservation);
                if (err < 0) {
index 2da98b6cc064737264c5973b0a3f9239a73384be..9e8b2099e63f58f63443838e2f1c09ea7d0c94ee 100644 (file)
@@ -2528,6 +2528,8 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc,
        rhead->oldest_client_tid = cpu_to_le64(__get_oldest_tid(mdsc));
        if (test_bit(CEPH_MDS_R_GOT_UNSAFE, &req->r_req_flags))
                flags |= CEPH_MDS_FLAG_REPLAY;
+       if (test_bit(CEPH_MDS_R_ASYNC, &req->r_req_flags))
+               flags |= CEPH_MDS_FLAG_ASYNC;
        if (req->r_parent)
                flags |= CEPH_MDS_FLAG_WANT_DENTRY;
        rhead->flags = cpu_to_le32(flags);
@@ -2611,6 +2613,10 @@ static void __do_request(struct ceph_mds_client *mdsc,
        mds = __choose_mds(mdsc, req, &random);
        if (mds < 0 ||
            ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) {
+               if (test_bit(CEPH_MDS_R_ASYNC, &req->r_req_flags)) {
+                       err = -EJUKEBOX;
+                       goto finish;
+               }
                dout("do_request no mds or not active, waiting for map\n");
                list_add(&req->r_wait, &mdsc->waiting_for_map);
                return;
@@ -2635,6 +2641,15 @@ static void __do_request(struct ceph_mds_client *mdsc,
                        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
+                * let the caller retry a sync request in that case.
+                */
+               if (test_bit(CEPH_MDS_R_ASYNC, &req->r_req_flags)) {
+                       err = -EJUKEBOX;
+                       goto out_session;
+               }
                if (session->s_state == CEPH_MDS_SESSION_NEW ||
                    session->s_state == CEPH_MDS_SESSION_CLOSING) {
                        __open_session(mdsc, session);
index a0918d00117ce011c8ee430b912fdceeaefa2b38..95ac00e59e66a54e025db6fa5512cd1ef294d5ea 100644 (file)
@@ -255,6 +255,7 @@ struct ceph_mds_request {
 #define CEPH_MDS_R_GOT_RESULT          (5) /* got a result */
 #define CEPH_MDS_R_DID_PREPOPULATE     (6) /* prepopulated readdir */
 #define CEPH_MDS_R_PARENT_LOCKED       (7) /* is r_parent->i_rwsem wlocked? */
+#define CEPH_MDS_R_ASYNC               (8) /* async request */
        unsigned long   r_req_flags;
 
        struct mutex r_fill_mutex;
index cb21c5cf12c33ccb0316b3ab54a34df746a383e7..9f747a1b8788ba7ee589300376b00a5cca66d5c9 100644 (file)
@@ -444,8 +444,9 @@ union ceph_mds_request_args {
        } __attribute__ ((packed)) lookupino;
 } __attribute__ ((packed));
 
-#define CEPH_MDS_FLAG_REPLAY        1  /* this is a replayed op */
-#define CEPH_MDS_FLAG_WANT_DENTRY   2  /* want dentry in reply */
+#define CEPH_MDS_FLAG_REPLAY           1 /* this is a replayed op */
+#define CEPH_MDS_FLAG_WANT_DENTRY      2 /* want dentry in reply */
+#define CEPH_MDS_FLAG_ASYNC            4 /* request is asynchronous */
 
 struct ceph_mds_request_head {
        __le64 oldest_client_tid;