From a162e24d2da5e4bd64a79d6dcc128bd0d50e8517 Mon Sep 17 00:00:00 2001 From: Lai Siyao Date: Fri, 20 May 2022 22:21:38 -0400 Subject: [PATCH] LU-15910 llite: enforce ROOT default on subdir mount In subdirectory mount, the filesystem-wide default LMV doesn't take effect. This fix includes the following changes: * enforce the filesystem-wide default LMV on subdirectory mount if it's not set separately. * "lfs getdirstripe -D " should print the filesystem-wide default LMV. Add sanity test_413g. Signed-off-by: Lai Siyao Change-Id: I26de9d02872f0df8918b4ef0765b6b18b84794e6 Reviewed-on: https://review.whamcloud.com/47518 Tested-by: jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Jian Yu Reviewed-by: Oleg Drokin --- lustre/llite/dir.c | 71 +++++++++++++++++++++++++++---------------- lustre/llite/llite_internal.h | 3 ++ lustre/llite/llite_lib.c | 48 +++++++++++++++++++++++++++-- lustre/tests/sanity.sh | 66 +++++++++++++++++++++++++++++++--------- 4 files changed, 145 insertions(+), 43 deletions(-) diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index f3f9eaa..f6e4779 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -687,10 +687,9 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, RETURN(rc); } -static int ll_dir_get_default_layout(struct inode *inode, void **plmm, - int *plmm_size, - struct ptlrpc_request **request, u64 valid, - enum get_default_layout_type type) +int ll_dir_get_default_layout(struct inode *inode, void **plmm, int *plmm_size, + struct ptlrpc_request **request, u64 valid, + enum get_default_layout_type type) { struct ll_sb_info *sbi = ll_i2sbi(inode); struct mdt_body *body; @@ -1651,33 +1650,51 @@ out: lum = (struct lmv_user_md *)lmm; lli = ll_i2info(inode); - if (lum->lum_max_inherit == LMV_INHERIT_NONE || - (lum->lum_max_inherit > 0 && - lum->lum_max_inherit < lli->lli_dir_depth)) - GOTO(finish_req, rc = -ENODATA); - - if (lum->lum_max_inherit == - lli->lli_dir_depth) { - lum->lum_max_inherit = LMV_INHERIT_NONE; - lum->lum_max_inherit_rr = - LMV_INHERIT_RR_NONE; - goto out_copy; - } - if (lum->lum_max_inherit > lli->lli_dir_depth && - lum->lum_max_inherit <= LMV_INHERIT_MAX) + if (lum->lum_max_inherit != + LMV_INHERIT_UNLIMITED) { + if (lum->lum_max_inherit == + LMV_INHERIT_NONE || + lum->lum_max_inherit < + LMV_INHERIT_END || + lum->lum_max_inherit > + LMV_INHERIT_MAX || + lum->lum_max_inherit < + lli->lli_dir_depth) + GOTO(finish_req, rc = -ENODATA); + + if (lum->lum_max_inherit == + lli->lli_dir_depth) { + lum->lum_max_inherit = + LMV_INHERIT_NONE; + lum->lum_max_inherit_rr = + LMV_INHERIT_RR_NONE; + goto out_copy; + } + lum->lum_max_inherit -= lli->lli_dir_depth; + } - if (lum->lum_max_inherit_rr > - lli->lli_dir_depth && - lum->lum_max_inherit_rr <= - LMV_INHERIT_RR_MAX) - lum->lum_max_inherit_rr -= - lli->lli_dir_depth; - else if (lum->lum_max_inherit_rr == + if (lum->lum_max_inherit_rr != + LMV_INHERIT_RR_UNLIMITED) { + if (lum->lum_max_inherit_rr == + LMV_INHERIT_NONE || + lum->lum_max_inherit_rr < + LMV_INHERIT_RR_END || + lum->lum_max_inherit_rr > + LMV_INHERIT_RR_MAX || + lum->lum_max_inherit_rr <= + lli->lli_dir_depth) { + lum->lum_max_inherit_rr = + LMV_INHERIT_RR_NONE; + goto out_copy; + } + + if (lum->lum_max_inherit_rr > lli->lli_dir_depth) - lum->lum_max_inherit_rr = - LMV_INHERIT_RR_NONE; + lum->lum_max_inherit_rr -= + lli->lli_dir_depth; + } } out_copy: if (copy_to_user(ulmv, lmm, lmmsize)) diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index a7bac0e..1616f05 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -1167,6 +1167,9 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename, struct ptlrpc_request **request); int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, int set_default); +int ll_dir_get_default_layout(struct inode *inode, void **plmm, int *plmm_size, + struct ptlrpc_request **request, u64 valid, + enum get_default_layout_type type); int ll_dir_getstripe_default(struct inode *inode, void **lmmp, int *lmm_size, struct ptlrpc_request **request, struct ptlrpc_request **root_request, u64 valid); diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 99f436d..d6da421 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -3089,6 +3089,41 @@ void ll_open_cleanup(struct super_block *sb, struct req_capsule *pill) EXIT; } +/* set filesystem-wide default LMV for subdir mount if it's enabled on ROOT. */ +static int ll_fileset_default_lmv_fixup(struct inode *inode, + struct lustre_md *md) +{ + struct ll_sb_info *sbi = ll_i2sbi(inode); + struct ptlrpc_request *req = NULL; + union lmv_mds_md *lmm = NULL; + int size = 0; + int rc; + + LASSERT(is_root_inode(inode)); + LASSERT(!fid_is_root(&sbi->ll_root_fid)); + LASSERT(!md->default_lmv); + + rc = ll_dir_get_default_layout(inode, (void **)&lmm, &size, &req, + OBD_MD_DEFAULT_MEA, + GET_DEFAULT_LAYOUT_ROOT); + if (rc && rc != -ENODATA) + GOTO(out, rc); + + rc = 0; + if (lmm && size) { + rc = md_unpackmd(sbi->ll_md_exp, &md->default_lmv, lmm, size); + if (rc < 0) + GOTO(out, rc); + + rc = 0; + } + EXIT; +out: + if (req) + ptlrpc_req_finished(req); + return rc; +} + int ll_prep_inode(struct inode **inode, struct req_capsule *pill, struct super_block *sb, struct lookup_intent *it) { @@ -3112,8 +3147,17 @@ int ll_prep_inode(struct inode **inode, struct req_capsule *pill, * ll_update_lsm_md() may change md. */ if (it && (it->it_op & (IT_LOOKUP | IT_GETATTR)) && - S_ISDIR(md.body->mbo_mode) && !md.default_lmv) - default_lmv_deleted = true; + S_ISDIR(md.body->mbo_mode) && !md.default_lmv) { + if (unlikely(*inode && is_root_inode(*inode) && + !fid_is_root(&sbi->ll_root_fid))) { + rc = ll_fileset_default_lmv_fixup(*inode, &md); + if (rc) + GOTO(out, rc); + } + + if (!md.default_lmv) + default_lmv_deleted = true; + } if (*inode) { rc = ll_update_inode(*inode, &md); diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index b821de4..7b15f55 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -25829,26 +25829,15 @@ test_413e() { } run_test 413e "check default max-inherit value" -test_413f() { - (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test" - - (( MDS1_VERSION >= $(version_code 2.14.55) )) || - skip "Need server version at least 2.14.55" - - getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea || - error "dump $DIR default LMV failed" - stack_trap "setfattr --restore=$TMP/dmv.ea" - - $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR || - error "set $DIR default LMV failed" - +test_fs_dmv_inherit() +{ local testdir=$DIR/$tdir local count local inherit local inherit_rr - for i in $(seq 3); do + for i in 1 2 3; do mkdir $testdir || error "mkdir $testdir failed" count=$($LFS getdirstripe -D -c $testdir) (( count == 1 )) || @@ -25867,8 +25856,57 @@ test_413f() { (( count == 0 )) || error "$testdir default LMV count not zero: $count" } + +test_413f() { + (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test" + + (( MDS1_VERSION >= $(version_code 2.14.55) )) || + skip "Need server version at least 2.14.55" + + getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea || + error "dump $DIR default LMV failed" + stack_trap "setfattr --restore=$TMP/dmv.ea" + + $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR || + error "set $DIR default LMV failed" + + test_fs_dmv_inherit +} run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir" +test_413g() { + (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test" + + mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed" + getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea || + error "dump $DIR default LMV failed" + stack_trap "setfattr --restore=$TMP/dmv.ea" + + $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR || + error "set $DIR default LMV failed" + + FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 || + error "mount $MOUNT2 failed" + stack_trap "umount_client $MOUNT2" + + local saved_DIR=$DIR + + export DIR=$MOUNT2 + + stack_trap "export DIR=$saved_DIR" + + # first check filesystem-wide default LMV inheritance + test_fs_dmv_inherit || error "incorrect fs default LMV inheritance" + + # then check subdirs are spread to all MDTs + createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed" + + local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l) + + (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs" +} +run_test 413g "enforce ROOT default LMV on subdir mount" + test_413z() { local pids="" local subdir -- 1.8.3.1