From 9189dbcd10bced3e2acb12b4393f5d3e849a9649 Mon Sep 17 00:00:00 2001 From: Andriy Skulysh Date: Tue, 12 Dec 2017 15:39:14 +0200 Subject: [PATCH] LU-10582 out: can't obtain remote acl xattr 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 Reviewed-on: https://review.whamcloud.com/31088 Reviewed-by: Alexandr Boyko Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andrew Perepechko Reviewed-by: Oleg Drokin --- lustre/mdd/mdd_permission.c | 18 ++++++++++++++++-- lustre/osd-ldiskfs/osd_handler.c | 6 ++++++ lustre/osp/osp_trans.c | 4 ++-- lustre/target/out_lib.c | 2 +- lustre/tests/sanity.sh | 13 +++++++++++++ 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/lustre/mdd/mdd_permission.c b/lustre/mdd/mdd_permission.c index 505fb31..0065a61 100644 --- a/lustre/mdd/mdd_permission.c +++ b/lustre/mdd/mdd_permission.c @@ -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); diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 09a6be4..7bcf863 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -77,6 +77,9 @@ #include +/* 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. */ diff --git a/lustre/osp/osp_trans.c b/lustre/osp/osp_trans.c index c7eb681..9b92c45 100644 --- a/lustre/osp/osp_trans.c +++ b/lustre/osp/osp_trans.c @@ -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); diff --git a/lustre/target/out_lib.c b/lustre/target/out_lib.c index 1f55422..d1fcffd 100644 --- a/lustre/target/out_lib.c +++ b/lustre/target/out_lib.c @@ -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 */ diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 6a92729..623c72b 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -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 -- 1.8.3.1