From 5552eba1451d47ce1ba6c7ca112aa4b9b2f87292 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Wed, 17 Nov 2021 15:01:51 -0500 Subject: [PATCH] LU-15245 mdc: GET(X)ATTR to READPAGE portal Send the MDS_GETATTR and MDS_GETXATTR RPCs to the MDS_READPAGE_PORTAL instead of the default portal to avoid deadlocks with other MDS_REINT RPCs that may block all of the MDS service threads on that portal. This deadlock occurs with MDS_GETXATTR when selinux is enabled, because getxattr becomes part of lookup, so it takes a reference on a lock used for lookup. However, all of the MDS service threads on the default portal can be consumed by threads waiting for that lock, resulting in a deadlock when the getxattr can't be processed. Signed-off-by: Andreas Dilger Signed-off-by: Patrick Farrell Change-Id: I4fbae266022ee9fa38f3196acb1443df5056fe5e Reviewed-on: https://review.whamcloud.com/45593 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Lai Siyao Reviewed-by: Oleg Drokin --- lustre/mdc/mdc_request.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index af9cd83..bc79122 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -220,14 +220,17 @@ static int mdc_getattr(struct obd_export *exp, struct md_op_data *op_data, *request = NULL; req = ptlrpc_request_alloc(imp, &RQF_MDS_GETATTR); - if (req == NULL) - RETURN(-ENOMEM); + if (req == NULL) + RETURN(-ENOMEM); - rc = ptlrpc_request_pack(req, LUSTRE_MDS_VERSION, MDS_GETATTR); - if (rc) { - ptlrpc_request_free(req); - RETURN(rc); - } + rc = ptlrpc_request_pack(req, LUSTRE_MDS_VERSION, MDS_GETATTR); + if (rc) { + ptlrpc_request_free(req); + RETURN(rc); + } + + /* LU-15245: avoid deadlock with modifying RPCs on MDS_REQUEST_PORTAL */ + req->rq_request_portal = MDS_READPAGE_PORTAL; again: mdc_pack_body(&req->rq_pill, &op_data->op_fid1, op_data->op_valid, @@ -396,15 +399,19 @@ static int mdc_xattr_common(struct obd_export *exp,const struct req_format *fmt, rec->sx_fsgid = from_kgid(&init_user_ns, current_fsgid()); rec->sx_cap = current_cap().cap[0]; rec->sx_suppgid1 = suppgid; - rec->sx_suppgid2 = -1; - rec->sx_fid = *fid; - rec->sx_valid = valid | OBD_MD_FLCTIME; + rec->sx_suppgid2 = -1; + rec->sx_fid = *fid; + rec->sx_valid = valid | OBD_MD_FLCTIME; rec->sx_time = ktime_get_real_seconds(); - rec->sx_size = output_size; - rec->sx_flags = flags; + rec->sx_size = output_size; + rec->sx_flags = flags; } else { mdc_pack_body(&req->rq_pill, fid, valid, output_size, suppgid, flags); + /* Avoid deadlock with modifying RPCs on MDS_REQUEST_PORTAL. + * See LU-15245. + */ + req->rq_request_portal = MDS_READPAGE_PORTAL; } if (xattr_name) { -- 1.8.3.1