Whamcloud - gitweb
LU-17149 tbf: nrs_tbf_id_cli_set should not modify the fmt 28/52528/3
authorEtienne AUJAMES <etienne.aujames@cea.fr>
Wed, 27 Sep 2023 11:51:36 +0000 (13:51 +0200)
committerOleg Drokin <green@whamcloud.com>
Fri, 3 Nov 2023 04:05:37 +0000 (04:05 +0000)
nrs_tbf_id_cli_set() needs to parse LDLM_ENQUEUE request to find
uid/gid.

It calls req_capsule_extend() that change the request format (rc_fmt).
If rc_fmt was not null, the function will not restore the initial
request format.

The following crash will occur the 2sd time that nrs_tbf_id_cli_set()
is called (1st: o_cli_find(), 2sd: o_cli_init()):

LustreError: 8949:0:(req_capsule_extend())
ASSERTION( fmt->rf_fields[i].nr >= old->rf_fields[i].nr ) failed:
Call Trace TBD:
[<0>] libcfs_call_trace+0x6f/0xa0 [libcfs]
[<0>] lbug_with_loc+0x3f/0x70 [libcfs]
[<0>] req_capsule_extend+0x174/0x1b0 [ptlrpc]
[<0>] nrs_tbf_id_cli_set+0x1ee/0x2a0 [ptlrpc]
[<0>] nrs_tbf_generic_cli_init+0x50/0x180 [ptlrpc]
[<0>] nrs_tbf_res_get+0x1fe/0x430 [ptlrpc]
[<0>] nrs_resource_get+0x6c/0xe0 [ptlrpc]
[<0>] nrs_resource_get_safe+0x87/0xe0 [ptlrpc]
[<0>] ptlrpc_nrs_req_initialize+0x58/0xb0 [ptlrpc]
[<0>] ptlrpc_server_request_add+0x248/0xa20 [ptlrpc]
[<0>] ptlrpc_server_handle_req_in+0x36a/0x8c0 [ptlrpc]
[<0>] ptlrpc_main+0xb97/0x1530 [ptlrpc]
[<0>] kthread+0x134/0x150
[<0>] ret_from_fork+0x1f/0x40

Test-Parameters: testlist=sanityn env=ONLY=77
Test-Parameters: testlist=sanityn env=ONLY=77
Test-Parameters: testlist=sanityn env=ONLY=77
Signed-off-by: Etienne AUJAMES <eaujames@ddn.com>
Change-Id: Ia762936262e8cde891ae2a9daf4ce691c6a6f616
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52528
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Feng Lei <flei@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/ptlrpc/nrs_tbf.c

index 13afda2..e4a9875 100644 (file)
@@ -1589,9 +1589,9 @@ static int ldlm_tbf_id_cli_set(struct ptlrpc_request *req,
 static int nrs_tbf_id_cli_set(struct ptlrpc_request *req, struct tbf_id *id,
                              enum nrs_tbf_flag ti_type)
 {
-       u32 opc = lustre_msg_get_opc(req->rq_reqmsg);
-       struct req_format *fmt = req_fmt(opc);
-       bool fmt_unset = false;
+       u32 opc;
+       struct req_format *fmt;
+       const struct req_format *old_fmt;
        int rc;
 
        memset(id, 0, sizeof(struct tbf_id));
@@ -1604,13 +1604,15 @@ static int nrs_tbf_id_cli_set(struct ptlrpc_request *req, struct tbf_id *id,
        /* client req doesn't have uid/gid pack in ptlrpc_body
         * --> fallback to the old method
         */
+       opc = lustre_msg_get_opc(req->rq_reqmsg);
+       fmt = req_fmt(opc);
        if (fmt == NULL)
                return -EINVAL;
+
        req_capsule_init(&req->rq_pill, req, RCL_SERVER);
-       if (req->rq_pill.rc_fmt == NULL) {
+       old_fmt = req->rq_pill.rc_fmt;
+       if (old_fmt == NULL)
                req_capsule_set(&req->rq_pill, fmt);
-               fmt_unset = true;
-       }
 
        if (opc < OST_LAST_OPC)
                rc = ost_tbf_id_cli_set(req, id);
@@ -1621,9 +1623,9 @@ static int nrs_tbf_id_cli_set(struct ptlrpc_request *req, struct tbf_id *id,
        else
                rc = -EINVAL;
 
-       /* restore it to the initialized state */
-       if (fmt_unset)
-               req->rq_pill.rc_fmt = NULL;
+       /* restore it to the original state */
+       if (req->rq_pill.rc_fmt != old_fmt)
+               req->rq_pill.rc_fmt = old_fmt;
        return rc;
 }