Whamcloud - gitweb
LU-11656 llite: fetch default layout for a directory 09/36609/11
authorJian Yu <yujian@whamcloud.com>
Tue, 19 Nov 2019 22:19:24 +0000 (14:19 -0800)
committerOleg Drokin <green@whamcloud.com>
Fri, 20 Dec 2019 03:27:10 +0000 (03:27 +0000)
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 <yujian@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/36609
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
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/llite/dir.c
lustre/llite/llite_internal.h
lustre/llite/xattr.c
lustre/tests/sanity.sh

index 328cf4c..e013f1b 100644 (file)
@@ -679,16 +679,10 @@ end:
        RETURN(rc);
 }
 
        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;
 {
        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 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);
        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;
                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) {
        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);
        }
 
                GOTO(out, rc);
        }
 
@@ -775,6 +778,72 @@ out:
        return rc;
 }
 
        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;
 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 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;
                union lmv_mds_md        *lmm = NULL;
                int                     lmmsize;
                u64                     valid = 0;
@@ -1532,8 +1602,8 @@ out:
                else
                        RETURN(-EINVAL);
 
                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);
 
                if (rc != 0)
                        GOTO(finish_req, rc);
 
@@ -1623,6 +1693,7 @@ out_tmp:
                OBD_FREE(tmp, lum_size);
 finish_req:
                ptlrpc_req_finished(request);
                OBD_FREE(tmp, lum_size);
 finish_req:
                ptlrpc_req_finished(request);
+               ptlrpc_req_finished(root_request);
                return rc;
        }
 
                return rc;
        }
 
@@ -1667,6 +1738,7 @@ out_rmdir:
        case IOC_MDC_GETFILEINFO_OLD:
        case IOC_MDC_GETFILESTRIPE: {
                struct ptlrpc_request *request = NULL;
        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;
                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_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) {
                }
 
                if (request) {
@@ -1828,6 +1901,7 @@ out_rmdir:
                EXIT;
 out_req:
                ptlrpc_req_finished(request);
                EXIT;
 out_req:
                ptlrpc_req_finished(request);
+               ptlrpc_req_finished(root_request);
                if (filename)
                        ll_putname(filename);
                return rc;
                if (filename)
                        ll_putname(filename);
                return rc;
index 6e71a31..1649f11 100644 (file)
@@ -849,6 +849,10 @@ enum {
 };
 
 /* llite/dir.c */
 };
 
 /* llite/dir.c */
+enum get_default_layout_type {
+       GET_DEFAULT_LAYOUT_ROOT = 1,
+};
+
 struct ll_dir_chain {
 };
 
 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);
                              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);
 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);
index 6cfad04..0c50a59 100644 (file)
@@ -545,11 +545,12 @@ out_env:
                RETURN(rc);
        } else if (S_ISDIR(inode->i_mode)) {
                struct ptlrpc_request *req = NULL;
                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;
 
                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);
 
                if (rc < 0)
                        GOTO(out_req, rc);
 
@@ -564,6 +565,8 @@ out_env:
 out_req:
                if (req)
                        ptlrpc_req_finished(req);
 out_req:
                if (req)
                        ptlrpc_req_finished(req);
+               if (root_req)
+                       ptlrpc_req_finished(root_req);
 
                RETURN(rc);
        } else {
 
                RETURN(rc);
        } else {
index 3d7cfbe..2afc8ef 100644 (file)
@@ -7881,8 +7881,13 @@ test_65n() {
 
        local dir3=$MOUNT/$tdir-3
        mkdir $dir3 || error "mkdir $dir3 failed"
 
        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
 
        # 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"
 
        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
 
        # 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 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"
        local dir5_layout=$(get_layout_param $dir5)
        [[ "$dir4_layout" = "$dir5_layout" ]] ||
                error "$dir5 should inherit the default layout from $dir4"