From 3e8fa8a7396cd029cb0d7714a324343eed7f535e Mon Sep 17 00:00:00 2001 From: Jian Yu Date: Tue, 19 Nov 2019 14:19:24 -0800 Subject: [PATCH] LU-11656 llite: fetch default layout for a directory For a directory that does not have trusted.lov xattr, the current "lfs getstripe" will only print the stripe_count, stripe_size, and stripe_index that are fetched from the /sys/fs/lustre/lov values. It doesn't show the actual default layout that will be used when new files will be created in that directory. This patch fixes the above issue in ll_dir_getstripe_default() by fetching the layout from root FID after ll_dir_get_default_layout() returns -ENODATA from a directory that does not have trusted.lov xattr. Change-Id: Icbf1f8f4fa5e5b8788217fcb0cfd24a3b80a27d9 Signed-off-by: Jian Yu Reviewed-on: https://review.whamcloud.com/36609 Reviewed-by: Andreas Dilger Tested-by: jenkins Tested-by: Maloo Reviewed-by: Lai Siyao Reviewed-by: Oleg Drokin --- lustre/llite/dir.c | 106 +++++++++++++++++++++++++++++++++++------- lustre/llite/llite_internal.h | 12 +++-- lustre/llite/xattr.c | 7 ++- lustre/tests/sanity.sh | 21 +++++++-- 4 files changed, 120 insertions(+), 26 deletions(-) diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 328cf4c..e013f1b 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -679,16 +679,10 @@ end: RETURN(rc); } -/** - * This function will be used to get default LOV/LMV/Default LMV - * @valid will be used to indicate which stripe it will retrieve - * OBD_MD_MEA LMV stripe EA - * OBD_MD_DEFAULT_MEA Default LMV stripe EA - * otherwise Default LOV EA. - * Each time, it can only retrieve 1 stripe EA - **/ -int ll_dir_getstripe(struct inode *inode, void **plmm, int *plmm_size, - struct ptlrpc_request **request, u64 valid) +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) { struct ll_sb_info *sbi = ll_i2sbi(inode); struct mdt_body *body; @@ -696,6 +690,7 @@ int ll_dir_getstripe(struct inode *inode, void **plmm, int *plmm_size, struct ptlrpc_request *req = NULL; int rc, lmm_size; struct md_op_data *op_data; + struct lu_fid fid; ENTRY; rc = ll_get_default_mdsize(sbi, &lmm_size); @@ -709,11 +704,19 @@ int ll_dir_getstripe(struct inode *inode, void **plmm, int *plmm_size, RETURN(PTR_ERR(op_data)); op_data->op_valid = valid | OBD_MD_FLEASIZE | OBD_MD_FLDIREA; + + if (type == GET_DEFAULT_LAYOUT_ROOT) { + lu_root_fid(&op_data->op_fid1); + fid = op_data->op_fid1; + } else { + fid = *ll_inode2fid(inode); + } + rc = md_getattr(sbi->ll_md_exp, op_data, &req); ll_finish_md_op_data(op_data); if (rc < 0) { - CDEBUG(D_INFO, "md_getattr failed on inode " - DFID": rc %d\n", PFID(ll_inode2fid(inode)), rc); + CDEBUG(D_INFO, "md_getattr failed on inode "DFID": rc %d\n", + PFID(&fid), rc); GOTO(out, rc); } @@ -775,6 +778,72 @@ out: return rc; } +/** + * This function will be used to get default LOV/LMV/Default LMV + * @valid will be used to indicate which stripe it will retrieve. + * If the directory does not have its own default layout, then the + * function will request the default layout from root FID. + * OBD_MD_MEA LMV stripe EA + * OBD_MD_DEFAULT_MEA Default LMV stripe EA + * otherwise Default LOV EA. + * Each time, it can only retrieve 1 stripe EA + **/ +int ll_dir_getstripe_default(struct inode *inode, void **plmm, int *plmm_size, + struct ptlrpc_request **request, + struct ptlrpc_request **root_request, + u64 valid) +{ + struct ptlrpc_request *req = NULL; + struct ptlrpc_request *root_req = NULL; + struct lov_mds_md *lmm = NULL; + int lmm_size = 0; + int rc = 0; + ENTRY; + + rc = ll_dir_get_default_layout(inode, (void **)&lmm, &lmm_size, + &req, valid, 0); + if (rc == -ENODATA && !fid_is_root(ll_inode2fid(inode)) && + !(valid & (OBD_MD_MEA|OBD_MD_DEFAULT_MEA)) && root_request != NULL) + rc = ll_dir_get_default_layout(inode, (void **)&lmm, &lmm_size, + &root_req, valid, + GET_DEFAULT_LAYOUT_ROOT); + + *plmm = lmm; + *plmm_size = lmm_size; + *request = req; + if (root_request != NULL) + *root_request = root_req; + + RETURN(rc); +} + +/** + * This function will be used to get default LOV/LMV/Default LMV + * @valid will be used to indicate which stripe it will retrieve + * OBD_MD_MEA LMV stripe EA + * OBD_MD_DEFAULT_MEA Default LMV stripe EA + * otherwise Default LOV EA. + * Each time, it can only retrieve 1 stripe EA + **/ +int ll_dir_getstripe(struct inode *inode, void **plmm, int *plmm_size, + struct ptlrpc_request **request, u64 valid) +{ + struct ptlrpc_request *req = NULL; + struct lov_mds_md *lmm = NULL; + int lmm_size = 0; + int rc = 0; + ENTRY; + + rc = ll_dir_get_default_layout(inode, (void **)&lmm, &lmm_size, + &req, valid, 0); + + *plmm = lmm; + *plmm_size = lmm_size; + *request = req; + + RETURN(rc); +} + int ll_get_mdt_idx_by_fid(struct ll_sb_info *sbi, const struct lu_fid *fid) { struct md_op_data *op_data; @@ -1507,6 +1576,7 @@ out: (struct lmv_user_md __user *)arg; struct lmv_user_md lum; struct ptlrpc_request *request = NULL; + struct ptlrpc_request *root_request = NULL; union lmv_mds_md *lmm = NULL; int lmmsize; u64 valid = 0; @@ -1532,8 +1602,8 @@ out: else RETURN(-EINVAL); - rc = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize, &request, - valid); + rc = ll_dir_getstripe_default(inode, (void **)&lmm, &lmmsize, + &request, &root_request, valid); if (rc != 0) GOTO(finish_req, rc); @@ -1623,6 +1693,7 @@ out_tmp: OBD_FREE(tmp, lum_size); finish_req: ptlrpc_req_finished(request); + ptlrpc_req_finished(root_request); return rc; } @@ -1667,6 +1738,7 @@ out_rmdir: case IOC_MDC_GETFILEINFO_OLD: case IOC_MDC_GETFILESTRIPE: { struct ptlrpc_request *request = NULL; + struct ptlrpc_request *root_request = NULL; struct lov_user_md __user *lump; struct lov_mds_md *lmm = NULL; struct mdt_body *body; @@ -1688,8 +1760,9 @@ out_rmdir: rc = ll_lov_getstripe_ea_info(inode, filename, &lmm, &lmmsize, &request); } else { - rc = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize, - &request, 0); + rc = ll_dir_getstripe_default(inode, (void **)&lmm, + &lmmsize, &request, + &root_request, 0); } if (request) { @@ -1828,6 +1901,7 @@ out_rmdir: EXIT; out_req: ptlrpc_req_finished(request); + ptlrpc_req_finished(root_request); if (filename) ll_putname(filename); return rc; diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 6e71a31..1649f11 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -849,6 +849,10 @@ enum { }; /* llite/dir.c */ +enum get_default_layout_type { + GET_DEFAULT_LAYOUT_ROOT = 1, +}; + struct ll_dir_chain { }; @@ -957,9 +961,11 @@ 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_getstripe(struct inode *inode, void **lmmp, - int *lmm_size, struct ptlrpc_request **request, - u64 valid); +int ll_dir_getstripe_default(struct inode *inode, void **lmmp, + int *lmm_size, struct ptlrpc_request **request, + struct ptlrpc_request **root_request, u64 valid); +int ll_dir_getstripe(struct inode *inode, void **plmm, int *plmm_size, + struct ptlrpc_request **request, u64 valid); int ll_fsync(struct file *file, loff_t start, loff_t end, int data); int ll_merge_attr(const struct lu_env *env, struct inode *inode); int ll_fid2path(struct inode *inode, void __user *arg); diff --git a/lustre/llite/xattr.c b/lustre/llite/xattr.c index 6cfad04..0c50a59 100644 --- a/lustre/llite/xattr.c +++ b/lustre/llite/xattr.c @@ -545,11 +545,12 @@ out_env: RETURN(rc); } else if (S_ISDIR(inode->i_mode)) { struct ptlrpc_request *req = NULL; + struct ptlrpc_request *root_req = NULL; struct lov_mds_md *lmm = NULL; int lmm_size = 0; - rc = ll_dir_getstripe(inode, (void **)&lmm, &lmm_size, - &req, 0); + rc = ll_dir_getstripe_default(inode, (void **)&lmm, &lmm_size, + &req, &root_req, 0); if (rc < 0) GOTO(out_req, rc); @@ -564,6 +565,8 @@ out_env: out_req: if (req) ptlrpc_req_finished(req); + if (root_req) + ptlrpc_req_finished(root_req); RETURN(rc); } else { diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 3d7cfbe..2afc8ef 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -7881,8 +7881,13 @@ test_65n() { local dir3=$MOUNT/$tdir-3 mkdir $dir3 || error "mkdir $dir3 failed" - ! getfattr -n trusted.lov $dir3 &> /dev/null || - error "$dir3 shouldn't have LOV EA" + # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show + # the root layout, which is the actual default layout that will be used + # when new files are created in $dir3. + local dir3_layout=$(get_layout_param $dir3) + local root_dir_layout=$(get_layout_param $MOUNT) + [[ "$dir3_layout" = "$root_dir_layout" ]] || + error "$dir3 should show the default layout from $MOUNT" # set OST pool on root directory local pool=$TESTNAME @@ -7904,8 +7909,14 @@ test_65n() { local dir4=$MOUNT/$tdir-4 mkdir $dir4 || error "mkdir $dir4 failed" - ! getfattr -n trusted.lov $dir4 &> /dev/null || - error "$dir4 shouldn't have LOV EA" + local dir4_layout=$(get_layout_param $dir4) + root_dir_layout=$(get_layout_param $MOUNT) + echo "$LFS getstripe -d $dir4" + $LFS getstripe -d $dir4 + echo "$LFS getstripe -d $MOUNT" + $LFS getstripe -d $MOUNT + [[ "$dir4_layout" = "$root_dir_layout" ]] || + error "$dir4 should show the default layout from $MOUNT" # new file created in $dir4 should inherit the pool from # the filesystem default @@ -7924,7 +7935,7 @@ test_65n() { local dir5=$dir4/$tdir-5 mkdir $dir5 || error "mkdir $dir5 failed" - local dir4_layout=$(get_layout_param $dir4) + dir4_layout=$(get_layout_param $dir4) local dir5_layout=$(get_layout_param $dir5) [[ "$dir4_layout" = "$dir5_layout" ]] || error "$dir5 should inherit the default layout from $dir4" -- 1.8.3.1