Whamcloud - gitweb
LU-10582 out: can't obtain remote acl xattr 88/31088/5
authorAndriy Skulysh <c17819@cray.com>
Tue, 12 Dec 2017 13:39:14 +0000 (15:39 +0200)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 6 Mar 2018 19:14:05 +0000 (19:14 +0000)
osp_xattr_get() fails due to hardcoded
reply size limitation.

With large_xattr enabled ddp_max_ea_size can be
almost 1MB and out_handles fails to send such big
reply.

Limit maximum ACL buffer size by XATTR_SIZE_MAX.
Limit ddp_max_ea_size to fit resulting reply
request into LNET_MTU.

Cray-bug-id: MRP-4724
Change-Id: I6405330605809911c3f814fe5cb9d476d7ac40ed
Signed-off-by: Andriy Skulysh <c17819@cray.com>
Reviewed-on: https://review.whamcloud.com/31088
Reviewed-by: Alexandr Boyko <c17825@cray.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andrew Perepechko <c17827@cray.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/mdd/mdd_permission.c
lustre/osd-ldiskfs/osd_handler.c
lustre/osp/osp_trans.c
lustre/target/out_lib.c
lustre/tests/sanity.sh

index 505fb31..0065a61 100644 (file)
@@ -62,8 +62,15 @@ int mdd_acl_chmod(const struct lu_env *env, struct mdd_object *o, __u32 mode,
        ENTRY;
 
        lu_buf_check_and_alloc(&mdd_env_info(env)->mti_xattr_buf,
-                       mdd_obj2mdd_dev(o)->mdd_dt_conf.ddp_max_ea_size);
+                       MIN(mdd_obj2mdd_dev(o)->mdd_dt_conf.ddp_max_ea_size,
+                           XATTR_SIZE_MAX));
        buf = mdd_env_info(env)->mti_xattr_buf;
+       if (buf.lb_buf == NULL)
+               RETURN(-ENOMEM);
+
+       if (buf.lb_len > XATTR_SIZE_MAX)
+               buf.lb_len  = XATTR_SIZE_MAX;
+
        rc = mdo_xattr_get(env, o, &buf, XATTR_NAME_ACL_ACCESS);
        if ((rc == -EOPNOTSUPP) || (rc == -ENODATA))
                RETURN(0);
@@ -210,8 +217,15 @@ static int mdd_check_acl(const struct lu_env *env, struct mdd_object *obj,
        ENTRY;
 
        lu_buf_check_and_alloc(&mdd_env_info(env)->mti_xattr_buf,
-                       mdd_obj2mdd_dev(obj)->mdd_dt_conf.ddp_max_ea_size);
+                       MIN(mdd_obj2mdd_dev(obj)->mdd_dt_conf.ddp_max_ea_size,
+                           XATTR_SIZE_MAX));
        buf = mdd_env_info(env)->mti_xattr_buf;
+       if (buf.lb_buf == NULL)
+               RETURN(-ENOMEM);
+
+       if (buf.lb_len > XATTR_SIZE_MAX)
+               buf.lb_len  = XATTR_SIZE_MAX;
+
        rc = mdo_xattr_get(env, obj, &buf, XATTR_NAME_ACL_ACCESS);
        if (rc <= 0)
                RETURN(rc ? : -EACCES);
index 09a6be4..7bcf863 100644 (file)
@@ -77,6 +77,9 @@
 
 #include <lustre_linkea.h>
 
+/* Maximum EA size is limited by LNET_MTU for remote objects */
+#define OSD_MAX_EA_SIZE 1048364
+
 int ldiskfs_pdo = 1;
 module_param(ldiskfs_pdo, int, 0644);
 MODULE_PARM_DESC(ldiskfs_pdo, "ldiskfs with parallel directory operations");
@@ -2174,6 +2177,9 @@ static void osd_conf_get(const struct lu_env *env,
 #endif
                param->ddp_max_ea_size = sb->s_blocksize - ea_overhead;
 
+       if (param->ddp_max_ea_size > OSD_MAX_EA_SIZE)
+               param->ddp_max_ea_size = OSD_MAX_EA_SIZE;
+
        /* Preferred RPC size for efficient disk IO.  4MB shows good
         * all-around performance for ldiskfs, but use bigalloc chunk size
         * by default if larger. */
index c7eb681..9b92c45 100644 (file)
@@ -376,8 +376,8 @@ int osp_prep_update_req(const struct lu_env *env, struct obd_import *imp,
                buf_count++;
        }
        repsize += sizeof(*reply);
-       repsize = (repsize + OUT_UPDATE_REPLY_SIZE - 1) &
-                       ~(OUT_UPDATE_REPLY_SIZE - 1);
+       if (repsize < OUT_UPDATE_REPLY_SIZE)
+               repsize = OUT_UPDATE_REPLY_SIZE;
        LASSERT(buf_count > 0);
 
        req = ptlrpc_request_alloc(imp, &RQF_OUT_UPDATE);
index 1f55422..d1fcffd 100644 (file)
@@ -102,7 +102,7 @@ int out_update_header_pack(const struct lu_env *env,
        unsigned int                    i;
        size_t                          update_size;
 
-       if (((reply_size + 7) >> 3) >= 1ULL << 16)
+       if (reply_size  >= LNET_MTU)
                return -EINVAL;
 
        /* Check whether the packing exceeding the maxima update length */
index 6a92729..623c72b 100755 (executable)
@@ -17230,6 +17230,19 @@ test_315() { # LU-618
 }
 run_test 315 "read should be accounted"
 
+test_316() {
+       [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
+       large_xattr_enabled || { skip "large_xattr disabled" && return; }
+
+       rm -rf $DIR/$tdir/d
+       mkdir -p $DIR/$tdir/d
+       chown nobody $DIR/$tdir/d
+       touch $DIR/$tdir/d/file
+
+       $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
+}
+run_test 316 "lfs mv"
+
 test_fake_rw() {
        local read_write=$1
        if [ "$read_write" = "write" ]; then