From 855f3d03c21752c8d7136a8a9e48223ee3302512 Mon Sep 17 00:00:00 2001 From: Etienne AUJAMES Date: Wed, 27 Sep 2023 13:51:36 +0200 Subject: [PATCH] LU-17149 tbf: nrs_tbf_id_cli_set should not modify the fmt 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 Change-Id: Ia762936262e8cde891ae2a9daf4ce691c6a6f616 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52528 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Feng Lei Reviewed-by: Oleg Drokin --- lustre/ptlrpc/nrs_tbf.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lustre/ptlrpc/nrs_tbf.c b/lustre/ptlrpc/nrs_tbf.c index 13afda2..e4a9875 100644 --- a/lustre/ptlrpc/nrs_tbf.c +++ b/lustre/ptlrpc/nrs_tbf.c @@ -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; } -- 1.8.3.1