Whamcloud - gitweb
LU-15245 mdc: GET(X)ATTR to READPAGE portal 93/45593/7
authorAndreas Dilger <adilger@whamcloud.com>
Wed, 17 Nov 2021 20:01:51 +0000 (15:01 -0500)
committerOleg Drokin <green@whamcloud.com>
Thu, 6 Jan 2022 23:25:13 +0000 (23:25 +0000)
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 <adilger@whamcloud.com>
Signed-off-by: Patrick Farrell <pfarrell@whamcloud.com>
Change-Id: I4fbae266022ee9fa38f3196acb1443df5056fe5e
Reviewed-on: https://review.whamcloud.com/45593
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Lai Siyao <lai.siyao@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/mdc/mdc_request.c

index af9cd83..bc79122 100644 (file)
@@ -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) {