Whamcloud - gitweb
LU-18599 mdc: assign mod_close_req when RPC is ready 87/57587/2
authorAlex Zhuravlev <bzzz@whamcloud.com>
Tue, 24 Dec 2024 15:37:30 +0000 (18:37 +0300)
committerOleg Drokin <green@whamcloud.com>
Fri, 14 Feb 2025 02:55:43 +0000 (02:55 +0000)
we shouldn't assign mod_close_req before the corresponding close RPC
is fully populated, otherwise mdc_replay_open() can be accessing RPC
with no rq_reqmsg set.

Signed-off-by: Alex Zhuravlev <bzzz@whamcloud.com>
Change-Id: I78f7ba2b18c7e9c431accce591cd4a921e25f4da
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/57587
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Feng Lei <flei@ddn.com>
Reviewed-by: Nikitas Angelinas <nikitas.angelinas@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/mdc/mdc_request.c

index 2e4c8d0..9708ad2 100644 (file)
@@ -898,23 +898,6 @@ static int mdc_close(struct obd_export *exp, struct md_op_data *op_data,
        else
                req = ptlrpc_request_alloc(class_exp2cliimp(exp), req_fmt);
 
-       /* Ensure that this close's handle is fixed up during replay. */
-       if (likely(mod != NULL)) {
-               LASSERTF(mod->mod_open_req != NULL &&
-                        mod->mod_open_req->rq_type != LI_POISON,
-                        "POISONED open %px!\n", mod->mod_open_req);
-
-               mod->mod_close_req = req;
-
-               DEBUG_REQ(D_RPCTRACE, mod->mod_open_req, "matched open");
-               /* We no longer want to preserve this open for replay even
-                * though the open was committed. b=3632, b=3633 */
-               spin_lock(&mod->mod_open_req->rq_lock);
-               mod->mod_open_req->rq_replay = 0;
-               spin_unlock(&mod->mod_open_req->rq_lock);
-       } else {
-               CDEBUG(D_HA, "couldn't find open req; expecting close error\n");
-       }
        if (req == NULL) {
                /**
                 * TODO: repeat close after errors
@@ -954,6 +937,26 @@ static int mdc_close(struct obd_export *exp, struct md_op_data *op_data,
 
         ptlrpc_request_set_replen(req);
 
+       /* Ensure that this close's handle is fixed up during replay. */
+       if (likely(mod != NULL)) {
+               LASSERTF(mod->mod_open_req != NULL &&
+                        mod->mod_open_req->rq_type != LI_POISON,
+                        "POISONED open %px!\n", mod->mod_open_req);
+
+               /* Set only when the close RPC has been filled, otherwise
+                * mdc_replay_open() can access RPC with no rq_reqmsg */
+               mod->mod_close_req = req;
+
+               DEBUG_REQ(D_RPCTRACE, mod->mod_open_req, "matched open");
+               /* We no longer want to preserve this open for replay even
+                * though the open was committed. b=3632, b=3633 */
+               spin_lock(&mod->mod_open_req->rq_lock);
+               mod->mod_open_req->rq_replay = 0;
+               spin_unlock(&mod->mod_open_req->rq_lock);
+       } else {
+               CDEBUG(D_HA, "couldn't find open req; expecting close error\n");
+       }
+
        ptlrpc_get_mod_rpc_slot(req);
        rc = ptlrpc_queue_wait(req);
        ptlrpc_put_mod_rpc_slot(req);