Whamcloud - gitweb
LU-3531 llite: fix "lfs getdirstripe" to show stripe info 28/7228/42
authorwang di <di.wang@intel.com>
Wed, 31 Jul 2013 17:46:09 +0000 (10:46 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Sat, 22 Feb 2014 06:31:14 +0000 (06:31 +0000)
Fix "lfs getdirstripe", so it can show layout information
of striped directory

[root@testnode tests]# ../utils/lfs getdirstripe /mnt/lustre/test1
/mnt/lustre/test1
lmv_stripe_count: 2
lmv_stripe_offset: 0
mdtidx  FID[seq:oid:ver]
     0  [0x280000400:0x1:0x0]
     1  [0x2c0000400:0x1:0x0]

Signed-off-by: wang di <di.wang@intel.com>
Change-Id: I586f78ee2e0c35d8c3ed10726d5f5e12a4b543e7
Reviewed-on: http://review.whamcloud.com/7228
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: John L. Hammond <john.hammond@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
16 files changed:
lustre/include/lustre/lustre_idl.h
lustre/include/lustre/lustre_user.h
lustre/include/lustre/lustreapi.h
lustre/include/md_object.h
lustre/llite/dir.c
lustre/llite/llite_internal.h
lustre/llite/xattr.c
lustre/lod/lod_internal.h
lustre/lod/lod_object.c
lustre/mdt/mdt_handler.c
lustre/mdt/mdt_internal.h
lustre/mdt/mdt_lib.c
lustre/mdt/mdt_reint.c
lustre/ptlrpc/pack_generic.c
lustre/utils/lfs.c
lustre/utils/liblustreapi.c

index 0bee2f3..0f0bf41 100644 (file)
@@ -1688,7 +1688,7 @@ static inline void lmm_oi_cpu_to_le(struct ost_id *dst_oi,
 #define XATTR_NAME_LOV          "trusted.lov"
 #define XATTR_NAME_LMA          "trusted.lma"
 #define XATTR_NAME_LMV          "trusted.lmv"
-#define XATTR_NAME_DEFALT_LMV  "trusted.dmv"
+#define XATTR_NAME_DEFAULT_LMV "trusted.dmv"
 #define XATTR_NAME_LINK         "trusted.link"
 #define XATTR_NAME_FID          "trusted.fid"
 #define XATTR_NAME_VERSION      "trusted.version"
@@ -1780,6 +1780,8 @@ static inline __u32 lov_mds_md_size(__u16 stripes, __u32 lmm_magic)
 #define OBD_MD_FLDATAVERSION (0x0010000000000000ULL) /* iversion sum */
 #define OBD_MD_FLRELEASED    (0x0020000000000000ULL) /* file released */
 
+#define OBD_MD_DEFAULT_MEA   (0x0040000000000000ULL) /* default MEA */
+
 #define OBD_MD_FLGETATTR (OBD_MD_FLID    | OBD_MD_FLATIME | OBD_MD_FLMTIME | \
                           OBD_MD_FLCTIME | OBD_MD_FLSIZE  | OBD_MD_FLBLKSZ | \
                           OBD_MD_FLMODE  | OBD_MD_FLTYPE  | OBD_MD_FLUID   | \
@@ -2735,6 +2737,8 @@ union lmv_mds_md {
        struct lmv_user_md       lmv_user_md;
 };
 
+extern void lustre_swab_lmv_mds_md(union lmv_mds_md *lmm);
+
 static inline int lmv_mds_md_size(int stripe_count, unsigned int lmm_magic)
 {
        switch (lmm_magic) {
index 3a02c4e..4aa218d 100644 (file)
@@ -266,6 +266,7 @@ struct ost_id {
 #define LL_IOC_SET_LEASE               _IOWR('f', 243, long)
 #define LL_IOC_GET_LEASE               _IO('f', 244)
 #define LL_IOC_HSM_IMPORT              _IOWR('f', 245, struct hsm_user_import)
+#define LL_IOC_LMV_SET_DEFAULT_STRIPE  _IOWR('f', 246, struct lmv_user_md)
 
 #define LL_STATFS_LMV          1
 #define LL_STATFS_LOV          2
index 9426014..8f7d103 100644 (file)
@@ -160,7 +160,8 @@ struct find_param {
                                 check_stripecount:1,   /* LOV stripe count */
                                 exclude_stripecount:1,
                                 check_layout:1,
-                                exclude_layout:1;
+                                exclude_layout:1,
+                                get_default_lmv:1; /* Get default LMV */
 
        int                      verbose;
        int                      quiet;
@@ -214,6 +215,9 @@ extern int llapi_getstripe(char *path, struct find_param *param);
 extern int llapi_find(char *path, struct find_param *param);
 
 extern int llapi_file_fget_mdtidx(int fd, int *mdtidx);
+extern int llapi_dir_set_default_lmv_stripe(const char *name, int stripe_offset,
+                                          int stripe_count, int stripe_pattern,
+                                           const char *pool_name);
 extern int llapi_dir_create_pool(const char *name, int flags, int stripe_offset,
                                 int stripe_count, int stripe_pattern,
                                 const char *poolname);
index 5839517..e85d956 100644 (file)
@@ -71,17 +71,18 @@ struct md_quota *md_quota(const struct lu_env *env);
 
 /** metadata attributes */
 enum ma_valid {
-        MA_INODE     = (1 << 0),
-        MA_LOV       = (1 << 1),
-        MA_COOKIE    = (1 << 2),
-        MA_FLAGS     = (1 << 3),
-        MA_LMV       = (1 << 4),
-        MA_ACL_DEF   = (1 << 5),
-        MA_LOV_DEF   = (1 << 6),
-        MA_LAY_GEN   = (1 << 7),
-        MA_HSM       = (1 << 8),
-        MA_SOM       = (1 << 9),
-        MA_PFID      = (1 << 10)
+       MA_INODE     = (1 << 0),
+       MA_LOV       = (1 << 1),
+       MA_COOKIE    = (1 << 2),
+       MA_FLAGS     = (1 << 3),
+       MA_LMV       = (1 << 4),
+       MA_ACL_DEF   = (1 << 5),
+       MA_LOV_DEF   = (1 << 6),
+       MA_LAY_GEN   = (1 << 7),
+       MA_HSM       = (1 << 8),
+       MA_SOM       = (1 << 9),
+       MA_PFID      = (1 << 10),
+       MA_LMV_DEF   = (1 << 11)
 };
 
 typedef enum {
index b97edda..c579304 100644 (file)
@@ -443,6 +443,13 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
                         lum_size = sizeof(struct lov_user_md_v3);
                         break;
                 }
+               case LMV_USER_MAGIC: {
+                       if (lump->lmm_magic != cpu_to_le32(LMV_USER_MAGIC))
+                               lustre_swab_lmv_user_md(
+                                       (struct lmv_user_md *)lump);
+                       lum_size = sizeof(struct lmv_user_md);
+                       break;
+               }
                 default: {
                         CDEBUG(D_IOCTL, "bad userland LOV MAGIC:"
                                         " %#08x != %#08x nor %#08x\n",
@@ -514,73 +521,113 @@ end:
        RETURN(rc);
 }
 
-int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp,
-                     int *lmm_size, struct ptlrpc_request **request)
+/**
+ * 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, obd_valid valid)
 {
-        struct ll_sb_info *sbi = ll_i2sbi(inode);
-        struct mdt_body   *body;
-        struct lov_mds_md *lmm = NULL;
-        struct ptlrpc_request *req = NULL;
-        int rc, lmmsize;
-        struct md_op_data *op_data;
+       struct ll_sb_info *sbi = ll_i2sbi(inode);
+       struct mdt_body   *body;
+       struct lov_mds_md *lmm = NULL;
+       struct ptlrpc_request *req = NULL;
+       int rc, lmm_size;
+       struct md_op_data *op_data;
+       ENTRY;
 
-        rc = ll_get_max_mdsize(sbi, &lmmsize);
-        if (rc)
-                RETURN(rc);
+       rc = ll_get_max_mdsize(sbi, &lmm_size);
+       if (rc)
+               RETURN(rc);
 
-        op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL,
-                                     0, lmmsize, LUSTRE_OPC_ANY,
-                                     NULL);
-        if (IS_ERR(op_data))
-                RETURN(PTR_ERR(op_data));
+       op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL,
+                                    0, lmm_size, LUSTRE_OPC_ANY,
+                                    NULL);
+       if (IS_ERR(op_data))
+               RETURN(PTR_ERR(op_data));
 
-        op_data->op_valid = OBD_MD_FLEASIZE | OBD_MD_FLDIREA;
-        rc = md_getattr(sbi->ll_md_exp, op_data, &req);
-        ll_finish_md_op_data(op_data);
-        if (rc < 0) {
+       op_data->op_valid = valid | OBD_MD_FLEASIZE | OBD_MD_FLDIREA;
+       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);
-                GOTO(out, rc);
-        }
+               GOTO(out, rc);
+       }
 
-        body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
-        LASSERT(body != NULL);
+       body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
+       LASSERT(body != NULL);
 
-        lmmsize = body->eadatasize;
+       lmm_size = body->eadatasize;
 
-        if (!(body->valid & (OBD_MD_FLEASIZE | OBD_MD_FLDIREA)) ||
-            lmmsize == 0) {
-                GOTO(out, rc = -ENODATA);
-        }
+       if (!(body->valid & (OBD_MD_FLEASIZE | OBD_MD_FLDIREA)) ||
+           lmm_size == 0) {
+               GOTO(out, rc = -ENODATA);
+       }
 
-        lmm = req_capsule_server_sized_get(&req->rq_pill,
-                                           &RMF_MDT_MD, lmmsize);
-        LASSERT(lmm != NULL);
-
-        /*
-         * This is coming from the MDS, so is probably in
-         * little endian.  We convert it to host endian before
-         * passing it to userspace.
-         */
-        /* We don't swab objects for directories */
-        switch (le32_to_cpu(lmm->lmm_magic)) {
-        case LOV_MAGIC_V1:
-                if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
-                        lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm);
-                break;
-        case LOV_MAGIC_V3:
-                if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
-                        lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
-                break;
-        default:
-                CERROR("unknown magic: %lX\n", (unsigned long)lmm->lmm_magic);
-                rc = -EPROTO;
-        }
+       lmm = req_capsule_server_sized_get(&req->rq_pill,
+                                          &RMF_MDT_MD, lmm_size);
+       LASSERT(lmm != NULL);
+
+       /*
+        * This is coming from the MDS, so is probably in
+        * little endian.  We convert it to host endian before
+        * passing it to userspace.
+        */
+       /* We don't swab objects for directories */
+       switch (le32_to_cpu(lmm->lmm_magic)) {
+       case LOV_MAGIC_V1:
+               if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
+                       lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm);
+               break;
+       case LOV_MAGIC_V3:
+               if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
+                       lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
+               break;
+       case LMV_MAGIC:
+               if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
+                       lustre_swab_lmv_mds_md((union lmv_mds_md *)lmm);
+               break;
+       case LMV_USER_MAGIC:
+               if (LMV_USER_MAGIC != cpu_to_le32(LMV_USER_MAGIC))
+                       lustre_swab_lmv_user_md((struct lmv_user_md *)lmm);
+               break;
+       default:
+               CERROR("unknown magic: %lX\n", (unsigned long)lmm->lmm_magic);
+               rc = -EPROTO;
+       }
 out:
-        *lmmp = lmm;
-        *lmm_size = lmmsize;
-        *request = req;
-        return rc;
+       *plmm = lmm;
+       *plmm_size = lmm_size;
+       *request = req;
+       return rc;
+}
+
+static int ll_get_mdt_idx_by_fid(struct ll_sb_info *sbi,
+                                const struct lu_fid *fid)
+{
+       struct md_op_data       *op_data;
+       int                     rc;
+       int                     mdt_index;
+       ENTRY;
+
+       OBD_ALLOC_PTR(op_data);
+       if (op_data == NULL)
+               RETURN(-ENOMEM);
+
+       op_data->op_flags |= MF_GET_MDT_IDX;
+       op_data->op_fid1 = *fid;
+       rc = md_getattr(sbi->ll_md_exp, op_data, NULL);
+       mdt_index = op_data->op_mds;
+       OBD_FREE_PTR(op_data);
+       if (rc < 0)
+               RETURN(rc);
+
+       RETURN(mdt_index);
 }
 
 /*
@@ -588,25 +635,7 @@ out:
  */
 int ll_get_mdt_idx(struct inode *inode)
 {
-        struct ll_sb_info *sbi = ll_i2sbi(inode);
-        struct md_op_data *op_data;
-        int rc, mdtidx;
-        ENTRY;
-
-        op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0,
-                                     0, LUSTRE_OPC_ANY, NULL);
-        if (IS_ERR(op_data))
-                RETURN(PTR_ERR(op_data));
-
-       op_data->op_flags |= MF_GET_MDT_IDX;
-        rc = md_getattr(sbi->ll_md_exp, op_data, NULL);
-        mdtidx = op_data->op_mds;
-        ll_finish_md_op_data(op_data);
-        if (rc < 0) {
-                CDEBUG(D_INFO, "md_getattr_name: %d\n", rc);
-                RETURN(rc);
-        }
-        return mdtidx;
+       return ll_get_mdt_idx_by_fid(ll_i2sbi(inode), ll_inode2fid(inode));
 }
 
 /**
@@ -1087,6 +1116,22 @@ lmv_out_free:
                RETURN(rc);
 
        }
+       case LL_IOC_LMV_SET_DEFAULT_STRIPE: {
+               struct lmv_user_md        lum;
+               struct lmv_user_md __user *ulump =
+                                       (struct lmv_user_md __user *)arg;
+               int                       rc;
+
+               if (copy_from_user(&lum, ulump, sizeof(lum)))
+                       RETURN(-EFAULT);
+
+               if (lum.lum_magic != LMV_USER_MAGIC)
+                       RETURN(-EINVAL);
+
+               rc = ll_dir_setstripe(inode, (struct lov_user_md *)&lum, 0);
+
+               RETURN(rc);
+       }
         case LL_IOC_LOV_SETSTRIPE: {
                 struct lov_user_md_v3 lumv3;
                 struct lov_user_md_v1 *lumv1 = (struct lov_user_md_v1 *)&lumv3;
@@ -1116,41 +1161,96 @@ lmv_out_free:
                 RETURN(rc);
         }
        case LL_IOC_LMV_GETSTRIPE: {
-               struct lmv_user_md *lump = (struct lmv_user_md *)arg;
-               struct lmv_user_md lum;
-               struct lmv_user_md *tmp;
-               int lum_size;
-               int rc = 0;
-               int mdtindex;
-
-               if (copy_from_user(&lum, lump, sizeof(struct lmv_user_md)))
+               struct lmv_user_md __user *ulmv =
+                                       (struct lmv_user_md __user *)arg;
+               struct lmv_user_md      lum;
+               struct ptlrpc_request   *request = NULL;
+               union lmv_mds_md        *lmm = NULL;
+               int                     lmmsize;
+               obd_valid               valid = 0;
+               struct lmv_user_md      *tmp = NULL;
+               int                     mdt_index;
+               int                     lum_size;
+               int                     stripe_count;
+               int                     i;
+               int                     rc;
+
+               if (copy_from_user(&lum, ulmv, sizeof(*ulmv)))
                        RETURN(-EFAULT);
 
-               if (lum.lum_magic != LMV_MAGIC_V1)
+               /* lum_magic will indicate which stripe the ioctl will like
+                * to get, LMV_MAGIC_V1 is for normal LMV stripe, LMV_USER_MAGIC
+                * is for default LMV stripe */
+               if (lum.lum_magic == LMV_MAGIC_V1)
+                       valid |= OBD_MD_MEA;
+               else if (lum.lum_magic == LMV_USER_MAGIC)
+                       valid |= OBD_MD_DEFAULT_MEA;
+               else
                        RETURN(-EINVAL);
 
-               lum_size = lmv_user_md_size(1, LMV_MAGIC_V1);
+               rc = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize, &request,
+                                     valid);
+               if (rc != 0 && rc != -ENODATA)
+                       GOTO(finish_req, rc);
+
+               /* Get default LMV EA */
+               if (lum.lum_magic == LMV_USER_MAGIC) {
+                       if (rc != 0)
+                               GOTO(finish_req, rc);
+
+                       if (lmmsize > sizeof(*ulmv))
+                               GOTO(finish_req, rc = -EINVAL);
+
+                       if (copy_to_user(ulmv, lmm, lmmsize))
+                               GOTO(finish_req, rc = -EFAULT);
+
+                       GOTO(finish_req, rc);
+               }
+
+               /* Get normal LMV EA */
+               if (rc == -ENODATA) {
+                       stripe_count = 1;
+               } else {
+                       LASSERT(lmm != NULL);
+                       stripe_count = lmv_mds_md_stripe_count_get(lmm);
+               }
+
+               lum_size = lmv_user_md_size(stripe_count, LMV_MAGIC_V1);
                OBD_ALLOC(tmp, lum_size);
                if (tmp == NULL)
-                       GOTO(free_lmv, rc = -ENOMEM);
+                       GOTO(finish_req, rc = -ENOMEM);
 
-               memcpy(tmp, &lum, sizeof(lum));
+               tmp->lum_magic = LMV_MAGIC_V1;
                tmp->lum_stripe_count = 1;
-               mdtindex = ll_get_mdt_idx(inode);
-               if (mdtindex < 0)
-                       GOTO(free_lmv, rc = -ENOMEM);
-
-               tmp->lum_stripe_offset = mdtindex;
-               tmp->lum_objects[0].lum_mds = mdtindex;
-               memcpy(&tmp->lum_objects[0].lum_fid, ll_inode2fid(inode),
-                      sizeof(struct lu_fid));
-               if (copy_to_user((void *)arg, tmp, lum_size))
-                       GOTO(free_lmv, rc = -EFAULT);
-free_lmv:
-               if (tmp)
-                       OBD_FREE(tmp, lum_size);
-               RETURN(rc);
+               mdt_index = ll_get_mdt_idx(inode);
+               if (mdt_index < 0)
+                       GOTO(out_tmp, rc = -ENOMEM);
+               tmp->lum_stripe_offset = mdt_index;
+               tmp->lum_objects[0].lum_mds = mdt_index;
+               tmp->lum_objects[0].lum_fid = *ll_inode2fid(inode);
+               for (i = 1; i < stripe_count; i++) {
+                       struct lmv_mds_md_v1 *lmm1;
+
+                       lmm1 = &lmm->lmv_md_v1;
+                       mdt_index = ll_get_mdt_idx_by_fid(sbi,
+                                                    &lmm1->lmv_stripe_fids[i]);
+                       if (mdt_index < 0)
+                               GOTO(out_tmp, rc = mdt_index);
+
+                       tmp->lum_objects[i].lum_mds = mdt_index;
+                       tmp->lum_objects[i].lum_fid = lmm1->lmv_stripe_fids[i];
+                       tmp->lum_stripe_count++;
+               }
+
+               if (copy_to_user(ulmv, tmp, lum_size))
+                       GOTO(out_tmp, rc = -EFAULT);
+out_tmp:
+               OBD_FREE(tmp, lum_size);
+finish_req:
+               ptlrpc_req_finished(request);
+               return rc;
        }
+
        case LL_IOC_REMOVE_ENTRY: {
                char            *filename = NULL;
                int              namelen = 0;
@@ -1201,9 +1301,10 @@ out_rmdir:
 
                         rc = ll_lov_getstripe_ea_info(inode, filename, &lmm,
                                                       &lmmsize, &request);
-                } else {
-                        rc = ll_dir_getstripe(inode, &lmm, &lmmsize, &request);
-                }
+               } else {
+                       rc = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize,
+                                             &request, 0);
+               }
 
                 if (request) {
                         body = req_capsule_server_get(&request->rq_pill,
index c4e5f39..59ecdfb 100644 (file)
@@ -838,8 +838,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_getstripe(struct inode *inode, struct lov_mds_md **lmmp,
-                     int *lmm_size, struct ptlrpc_request **request);
+int ll_dir_getstripe(struct inode *inode, void **lmmp,
+                    int *lmm_size, struct ptlrpc_request **request,
+                    obd_valid valid);
 #ifdef HAVE_FILE_FSYNC_4ARGS
 int ll_fsync(struct file *file, loff_t start, loff_t end, int data);
 #elif defined(HAVE_FILE_FSYNC_2ARGS)
index 3db8073..bde8a35 100644 (file)
@@ -476,15 +476,15 @@ ssize_t ll_getxattr(struct dentry *dentry, const char *name,
 
                lsm = ccc_inode_lsm_get(inode);
                if (lsm == NULL) {
-                        if (S_ISDIR(inode->i_mode)) {
-                                rc = ll_dir_getstripe(inode, &lmm,
-                                                      &lmmsize, &request);
-                        } else {
-                                rc = -ENODATA;
-                        }
-                } else {
-                        /* LSM is present already after lookup/getattr call.
-                         * we need to grab layout lock once it is implemented */
+                       if (S_ISDIR(inode->i_mode)) {
+                               rc = ll_dir_getstripe(inode, (void **)&lmm,
+                                                     &lmmsize, &request, 0);
+                       } else {
+                               rc = -ENODATA;
+                       }
+               } else {
+                       /* LSM is present already after lookup/getattr call.
+                        * we need to grab layout lock once it is implemented */
                        rc = obd_packmd(ll_i2dtexp(inode), &lmm, lsm);
                        lmmsize = rc;
                }
@@ -571,10 +571,11 @@ ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
        }
        if (S_ISREG(inode->i_mode)) {
                if (!ll_i2info(inode)->lli_has_smd)
-                        rc2 = -1;
-        } else if (S_ISDIR(inode->i_mode)) {
-                rc2 = ll_dir_getstripe(inode, &lmm, &lmmsize, &request);
-        }
+                       rc2 = -1;
+       } else if (S_ISDIR(inode->i_mode)) {
+               rc2 = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize, &request,
+                                      0);
+       }
 
         if (rc2 < 0) {
                 GOTO(out, rc2 = 0);
index 3647791..b98caf2 100644 (file)
@@ -387,7 +387,7 @@ lod_get_lmv_ea(const struct lu_env *env, struct lod_object *lo)
 static inline int
 lod_get_default_lmv_ea(const struct lu_env *env, struct lod_object *lo)
 {
-       return lod_get_ea(env, lo, XATTR_NAME_DEFALT_LMV);
+       return lod_get_ea(env, lo, XATTR_NAME_DEFAULT_LMV);
 }
 
 void lod_fix_desc(struct lov_desc *desc);
index 3f2a5e5..ba83d07 100644 (file)
@@ -902,8 +902,40 @@ static int lod_declare_xattr_set(const struct lu_env *env,
                        attr->la_mode = S_IFREG;
                }
                rc = lod_declare_striped_object(env, dt, attr, buf, th);
-               if (rc)
+       } else if (S_ISDIR(mode)) {
+               struct lod_device       *d = lu2lod_dev(dt->do_lu.lo_dev);
+               struct lod_object       *lo = lod_dt_obj(dt);
+               int                     i;
+
+               if (strcmp(name, XATTR_NAME_DEFAULT_LMV) == 0) {
+                       struct lmv_user_md_v1 *lum;
+
+                       LASSERT(buf != NULL && buf->lb_buf != NULL);
+                       lum = buf->lb_buf;
+                       rc = lod_verify_md_striping(d, lum);
+                       if (rc != 0)
+                               RETURN(rc);
+               }
+
+               rc = dt_declare_xattr_set(env, next, buf, name, fl, th);
+               if (rc != 0)
+                       RETURN(rc);
+
+               /* set xattr to each stripes, if needed */
+               rc = lod_load_striping(env, lo);
+               if (rc != 0)
                        RETURN(rc);
+
+               if (lo->ldo_stripenr == 0)
+                       RETURN(rc);
+
+               for (i = 0; i < lo->ldo_stripenr; i++) {
+                       LASSERT(lo->ldo_stripe[i]);
+                       rc = dt_declare_xattr_set(env, lo->ldo_stripe[i], buf,
+                                                 name, fl, th);
+                       if (rc != 0)
+                               break;
+               }
        } else {
                rc = dt_declare_xattr_set(env, next, buf, name, fl, th);
        }
@@ -974,6 +1006,53 @@ static int lod_xattr_set_lov_on_dir(const struct lu_env *env,
        RETURN(rc);
 }
 
+static int lod_xattr_set_default_lmv_on_dir(const struct lu_env *env,
+                                           struct dt_object *dt,
+                                           const struct lu_buf *buf,
+                                           const char *name, int fl,
+                                           struct thandle *th,
+                                           struct lustre_capa *capa)
+{
+       struct dt_object        *next = dt_object_child(dt);
+       struct lod_object       *l = lod_dt_obj(dt);
+       struct lmv_user_md_v1   *lum;
+       int                      rc;
+       ENTRY;
+
+       LASSERT(buf != NULL && buf->lb_buf != NULL);
+       lum = buf->lb_buf;
+
+       CDEBUG(D_OTHER, "set default stripe_count # %u stripe_offset %d\n",
+             le32_to_cpu(lum->lum_stripe_count),
+             (int)le32_to_cpu(lum->lum_stripe_offset));
+
+       if (LMVEA_DELETE_VALUES((le32_to_cpu(lum->lum_stripe_count)),
+                                le32_to_cpu(lum->lum_stripe_offset)) &&
+                               le32_to_cpu(lum->lum_magic) == LMV_USER_MAGIC) {
+               rc = dt_xattr_del(env, next, name, th, capa);
+               if (rc == -ENODATA)
+                       rc = 0;
+       } else {
+               rc = dt_xattr_set(env, next, buf, name, fl, th, capa);
+               if (rc != 0)
+                       RETURN(rc);
+
+               /* Update default stripe cache */
+               if (l->ldo_dir_stripe == NULL) {
+                       OBD_ALLOC_PTR(l->ldo_dir_stripe);
+                       if (l->ldo_dir_stripe == NULL)
+                               RETURN(-ENOMEM);
+               }
+
+               l->ldo_dir_striping_cached = 0;
+               l->ldo_dir_def_striping_set = 1;
+               l->ldo_dir_def_stripenr =
+                       le32_to_cpu(lum->lum_stripe_count) - 1;
+       }
+
+       RETURN(rc);
+}
+
 static int lod_xattr_set_lmv(const struct lu_env *env, struct dt_object *dt,
                             const struct lu_buf *buf, const char *name,
                             int fl, struct thandle *th,
@@ -1071,9 +1150,11 @@ static int lod_xattr_set(const struct lu_env *env,
                         const char *name, int fl, struct thandle *th,
                         struct lustre_capa *capa)
 {
+       struct lod_object       *lo = lod_dt_obj(dt);
        struct dt_object        *next = dt_object_child(dt);
        __u32                    attr;
        int                      rc;
+       int                     i;
        ENTRY;
 
        attr = dt->do_lu.lo_header->loh_attr & S_IFMT;
@@ -1092,7 +1173,11 @@ static int lod_xattr_set(const struct lu_env *env,
                } else {
                        rc = lod_striping_create(env, dt, NULL, NULL, th);
                }
-               RETURN(rc);
+       } else if (strcmp(name, XATTR_NAME_DEFAULT_LMV) == 0) {
+               if (!S_ISDIR(attr))
+                       RETURN(-ENOTDIR);
+               rc = lod_xattr_set_default_lmv_on_dir(env, dt, buf, name, fl,
+                                                     th, capa);
        } else {
                /*
                 * behave transparantly for all other EAs
@@ -1100,6 +1185,20 @@ static int lod_xattr_set(const struct lu_env *env,
                rc = dt_xattr_set(env, next, buf, name, fl, th, capa);
        }
 
+       if (rc != 0 || !S_ISDIR(attr))
+               RETURN(rc);
+
+       if (lo->ldo_stripenr == 0)
+               RETURN(rc);
+
+       for (i = 0; i < lo->ldo_stripenr; i++) {
+               LASSERT(lo->ldo_stripe[i]);
+               rc = dt_xattr_set(env, lo->ldo_stripe[i], buf, name, fl, th,
+                                 capa);
+               if (rc != 0)
+                       break;
+       }
+
        RETURN(rc);
 }
 
@@ -1622,11 +1721,11 @@ int lod_dir_striping_create_internal(const struct lu_env *env,
                info->lti_buf.lb_len = sizeof(*v1);
                if (declare)
                        rc = dt_declare_xattr_set(env, next, &info->lti_buf,
-                                                 XATTR_NAME_DEFALT_LMV, 0,
+                                                 XATTR_NAME_DEFAULT_LMV, 0,
                                                  th);
                else
                        rc = dt_xattr_set(env, next, &info->lti_buf,
-                                          XATTR_NAME_DEFALT_LMV, 0, th,
+                                          XATTR_NAME_DEFAULT_LMV, 0, th,
                                           BYPASS_CAPA);
                if (rc != 0)
                        RETURN(rc);
index 22326e6..17340d0 100644 (file)
@@ -521,31 +521,66 @@ static int mdt_big_xattr_get(struct mdt_thread_info *info, struct mdt_object *o,
        RETURN(rc);
 }
 
-int mdt_attr_get_lov(struct mdt_thread_info *info,
-                    struct mdt_object *o, struct md_attr *ma)
+static int mdt_stripe_get(struct mdt_thread_info *info, struct mdt_object *o,
+                         struct md_attr *ma, char *name)
 {
        struct md_object *next = mdt_object_child(o);
        struct lu_buf    *buf = &info->mti_buf;
        int rc;
 
-       buf->lb_buf = ma->ma_lmm;
-       buf->lb_len = ma->ma_lmm_size;
-       rc = mo_xattr_get(info->mti_env, next, buf, XATTR_NAME_LOV);
+       if (strcmp(name, XATTR_NAME_LOV) == 0) {
+               buf->lb_buf = ma->ma_lmm;
+               buf->lb_len = ma->ma_lmm_size;
+               LASSERT(!(ma->ma_valid & MA_LOV));
+       } else if (strcmp(name, XATTR_NAME_LMV) == 0) {
+               buf->lb_buf = ma->ma_lmv;
+               buf->lb_len = ma->ma_lmv_size;
+               LASSERT(!(ma->ma_valid & MA_LMV));
+       } else if (strcmp(name, XATTR_NAME_DEFAULT_LMV) == 0) {
+               buf->lb_buf = ma->ma_lmv;
+               buf->lb_len = ma->ma_lmv_size;
+               LASSERT(!(ma->ma_valid & MA_LMV_DEF));
+       } else {
+               return -EINVAL;
+       }
 
+       rc = mo_xattr_get(info->mti_env, next, buf, name);
        if (rc > 0) {
-               ma->ma_lmm_size = rc;
-               ma->ma_valid |= MA_LOV;
+               if (strcmp(name, XATTR_NAME_LOV) == 0) {
+                       ma->ma_lmm_size = rc;
+                       ma->ma_valid |= MA_LOV;
+               } else if (strcmp(name, XATTR_NAME_LMV) == 0) {
+                       ma->ma_lmv_size = rc;
+                       ma->ma_valid |= MA_LMV;
+               } else if (strcmp(name, XATTR_NAME_DEFAULT_LMV) == 0) {
+                       ma->ma_lmv_size = rc;
+                       ma->ma_valid |= MA_LMV_DEF;
+               }
+
                rc = 0;
        } else if (rc == -ENODATA) {
                /* no LOV EA */
                rc = 0;
        } else if (rc == -ERANGE) {
-               rc = mdt_big_xattr_get(info, o, XATTR_NAME_LOV);
+               /* Default LMV has fixed size, so it must be able to fit
+                * in the original buffer */
+               if (strcmp(name, XATTR_NAME_DEFAULT_LMV) == 0)
+                       return rc;
+               rc = mdt_big_xattr_get(info, o, name);
                if (rc > 0) {
                        info->mti_big_lmm_used = 1;
-                       ma->ma_valid |= MA_LOV;
-                       ma->ma_lmm = info->mti_big_lmm;
-                       ma->ma_lmm_size = rc;
+                       if (!strcmp(name, XATTR_NAME_LOV)) {
+                               ma->ma_valid |= MA_LOV;
+                               ma->ma_lmm = info->mti_big_lmm;
+                               ma->ma_lmm_size = rc;
+                       } else if (!strcmp(name, XATTR_NAME_LMV)) {
+                               ma->ma_valid |= MA_LMV;
+                               ma->ma_lmv = info->mti_big_lmm;
+                               ma->ma_lmv_size = rc;
+                       } else {
+                               return -EINVAL;
+                       }
+
                        /* update mdt_max_mdsize so all clients
                         * will be aware about that */
                        if (info->mti_mdt->mdt_max_mdsize < rc)
@@ -634,23 +669,21 @@ int mdt_attr_get_complex(struct mdt_thread_info *info,
        }
 
        if (need & MA_LOV && (S_ISREG(mode) || S_ISDIR(mode))) {
-               rc = mdt_attr_get_lov(info, o, ma);
+               rc = mdt_stripe_get(info, o, ma, XATTR_NAME_LOV);
                if (rc)
                        GOTO(out, rc);
        }
 
        if (need & MA_LMV && S_ISDIR(mode)) {
-               buf->lb_buf = ma->ma_lmv;
-               buf->lb_len = ma->ma_lmv_size;
-               rc2 = mo_xattr_get(env, next, buf, XATTR_NAME_LMV);
-               if (rc2 > 0) {
-                       ma->ma_lmv_size = rc2;
-                       ma->ma_valid |= MA_LMV;
-               } else if (rc2 == -ENODATA) {
-                       /* no LMV EA */
-                       ma->ma_lmv_size = 0;
-               } else
-                       GOTO(out, rc = rc2);
+               rc = mdt_stripe_get(info, o, ma, XATTR_NAME_LMV);
+               if (rc != 0)
+                       GOTO(out, rc);
+       }
+
+       if (need & MA_LMV_DEF && S_ISDIR(mode)) {
+               rc = mdt_stripe_get(info, o, ma, XATTR_NAME_DEFAULT_LMV);
+               if (rc != 0)
+                       GOTO(out, rc);
        }
 
        if (need & MA_SOM && S_ISREG(mode)) {
@@ -750,13 +783,17 @@ static int mdt_getattr_internal(struct mdt_thread_info *info,
 
        /* If it is dir object and client require MEA, then we got MEA */
        if (S_ISDIR(lu_object_attr(&next->mo_lu)) &&
-           reqbody->valid & OBD_MD_MEA) {
+           (reqbody->valid & (OBD_MD_MEA | OBD_MD_DEFAULT_MEA))) {
                /* Assumption: MDT_MD size is enough for lmv size. */
                ma->ma_lmv = buffer->lb_buf;
                ma->ma_lmv_size = buffer->lb_len;
                ma->ma_need = MA_INODE;
-               if (ma->ma_lmv_size > 0)
-                       ma->ma_need |= MA_LMV;
+               if (ma->ma_lmv_size > 0) {
+                       if (reqbody->valid & OBD_MD_MEA)
+                               ma->ma_need |= MA_LMV;
+                       else if (reqbody->valid & OBD_MD_DEFAULT_MEA)
+                               ma->ma_need |= MA_LMV_DEF;
+               }
        } else {
                ma->ma_lmm = buffer->lb_buf;
                ma->ma_lmm_size = buffer->lb_len;
@@ -806,7 +843,7 @@ static int mdt_getattr_internal(struct mdt_thread_info *info,
                root = mdt_object_find(env, mdt, &rootfid);
                if (IS_ERR(root))
                        RETURN(PTR_ERR(root));
-               rc = mdt_attr_get_lov(info, root, ma);
+               rc = mdt_stripe_get(info, root, ma, XATTR_NAME_LOV);
                mdt_object_put(info->mti_env, root);
                if (unlikely(rc)) {
                        CERROR("%s: getattr error for "DFID": rc = %d\n",
@@ -831,11 +868,17 @@ static int mdt_getattr_internal(struct mdt_thread_info *info,
                         else
                                 repbody->valid |= OBD_MD_FLEASIZE;
                 }
-                if (ma->ma_valid & MA_LMV) {
-                        LASSERT(S_ISDIR(la->la_mode));
-                        repbody->eadatasize = ma->ma_lmv_size;
-                        repbody->valid |= (OBD_MD_FLDIREA|OBD_MD_MEA);
-                }
+               if (ma->ma_valid & MA_LMV) {
+                       LASSERT(S_ISDIR(la->la_mode));
+                       mdt_dump_lmv(D_INFO, ma->ma_lmv);
+                       repbody->eadatasize = ma->ma_lmv_size;
+                       repbody->valid |= (OBD_MD_FLDIREA|OBD_MD_MEA);
+               }
+               if (ma->ma_valid & MA_LMV_DEF) {
+                       LASSERT(S_ISDIR(la->la_mode));
+                       repbody->eadatasize = ma->ma_lmv_size;
+                       repbody->valid |= (OBD_MD_FLDIREA|OBD_MD_DEFAULT_MEA);
+               }
        } else if (S_ISLNK(la->la_mode) &&
                   reqbody->valid & OBD_MD_LINKNAME) {
                buffer->lb_buf = ma->ma_lmm;
index d548988..79c6bcd 100644 (file)
@@ -770,6 +770,7 @@ const struct lu_buf *mdt_buf_const(const struct lu_env *env,
                                    const void *area, ssize_t len);
 
 void mdt_dump_lmm(int level, const struct lov_mds_md *lmm);
+void mdt_dump_lmv(unsigned int level, const union lmv_mds_md *lmv);
 
 int mdt_check_ucred(struct mdt_thread_info *);
 int mdt_init_ucred(struct mdt_thread_info *, struct mdt_body *);
index 08d4809..e2cd8b1 100644 (file)
@@ -555,6 +555,24 @@ void mdt_dump_lmm(int level, const struct lov_mds_md *lmm)
        }
 }
 
+void mdt_dump_lmv(unsigned int level, const union lmv_mds_md *lmv)
+{
+       const struct lmv_mds_md_v1 *lmm1;
+       int                        i;
+
+       lmm1 = &lmv->lmv_md_v1;
+       CDEBUG(level, "magic 0x%08X, master %#X stripe_count %#x\n",
+              le32_to_cpu(lmm1->lmv_magic),
+              le32_to_cpu(lmm1->lmv_master_mdt_index),
+              le32_to_cpu(lmm1->lmv_stripe_count));
+       for (i = 0; i < le32_to_cpu(lmm1->lmv_stripe_count); i++) {
+               struct lu_fid fid;
+
+               fid_le_to_cpu(&fid, &lmm1->lmv_stripe_fids[i]);
+               CDEBUG(level, "idx %u subobj "DFID"\n", i, PFID(&fid));
+       }
+}
+
 /* Shrink and/or grow reply buffers */
 int mdt_fix_reply(struct mdt_thread_info *info)
 {
@@ -946,15 +964,26 @@ static int mdt_setattr_unpack(struct mdt_thread_info *info)
                 rr->rr_eadata = req_capsule_client_get(pill, &RMF_EADATA);
                 rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA,
                                                         RCL_CLIENT);
-                ma->ma_lmm_size = rr->rr_eadatalen;
-                if (ma->ma_lmm_size > 0) {
-                        ma->ma_lmm = (void *)rr->rr_eadata;
-                        ma->ma_valid |= MA_LOV;
-                }
-        }
+               if (rr->rr_eadatalen > 0) {
+                       const struct lmv_user_md        *lum;
+
+                       lum = rr->rr_eadata;
+                       /* Sigh ma_valid(from req) does not indicate whether
+                        * it will set LOV/LMV EA, so we have to check magic */
+                       if (le32_to_cpu(lum->lum_magic) == LMV_USER_MAGIC) {
+                               ma->ma_valid |= MA_LMV;
+                               ma->ma_lmv = (void *)rr->rr_eadata;
+                               ma->ma_lmv_size = rr->rr_eadatalen;
+                       } else {
+                               ma->ma_valid |= MA_LOV;
+                               ma->ma_lmm = (void *)rr->rr_eadata;
+                               ma->ma_lmm_size = rr->rr_eadatalen;
+                       }
+               }
+       }
 
-        rc = mdt_dlmreq_unpack(info);
-        RETURN(rc);
+       rc = mdt_dlmreq_unpack(info);
+       RETURN(rc);
 }
 
 static int mdt_hsm_release_unpack(struct mdt_thread_info *info)
index e3ffad0..98c2ad5 100644 (file)
@@ -615,6 +615,16 @@ static int mdt_reint_setattr(struct mdt_thread_info *info,
                                  buf, XATTR_NAME_LOV, 0);
                if (rc)
                        GOTO(out_put, rc);
+       } else if ((ma->ma_valid & MA_LMV) && (ma->ma_valid & MA_INODE)) {
+               struct lu_buf *buf  = &info->mti_buf;
+
+               LASSERT(ma->ma_attr.la_valid == 0);
+               buf->lb_buf = ma->ma_lmv;
+               buf->lb_len = ma->ma_lmv_size;
+               rc = mo_xattr_set(info->mti_env, mdt_object_child(mo),
+                                 buf, XATTR_NAME_DEFAULT_LMV, 0);
+               if (rc)
+                       GOTO(out_put, rc);
        } else
                LBUG();
 
index 77e92a2..97390de 100644 (file)
@@ -2120,6 +2120,31 @@ void lustre_swab_lmv_desc (struct lmv_desc *ld)
         /* uuid endian insensitive */
 }
 
+/* This structure is always in little-endian */
+static void lustre_swab_lmv_mds_md_v1(struct lmv_mds_md_v1 *lmm1)
+{
+       int i;
+
+       __swab32s(&lmm1->lmv_magic);
+       __swab32s(&lmm1->lmv_stripe_count);
+       __swab32s(&lmm1->lmv_master_mdt_index);
+       __swab32s(&lmm1->lmv_hash_type);
+       __swab32s(&lmm1->lmv_layout_version);
+       for (i = 0; i < lmm1->lmv_stripe_count; i++)
+               lustre_swab_lu_fid(&lmm1->lmv_stripe_fids[i]);
+}
+
+void lustre_swab_lmv_mds_md(union lmv_mds_md *lmm)
+{
+       switch (lmm->lmv_magic) {
+       case LMV_MAGIC_V1:
+               lustre_swab_lmv_mds_md_v1(&lmm->lmv_md_v1);
+               break;
+       default:
+               break;
+       }
+}
+
 void lustre_swab_lmv_user_md(struct lmv_user_md *lum)
 {
        int i;
index 3e2752f..2a05146 100644 (file)
@@ -156,16 +156,18 @@ command_t cmdlist[] = {
        {"setdirstripe", lfs_setdirstripe, 0,
         "To create a remote directory on a specified MDT.\n"
         "usage: setdirstripe <--count|-c stripe_count>\n"
-        "[--index|-i mdt_index] [--hash-type|-t hash_type] <dir>\n"
+        "[--index|-i mdt_index] [--hash-type|-t hash_type]\n"
+        "[--default_stripe|-D ] <dir>\n"
         "\tstripe_count: stripe count of the striped directory\n"
         "\tmdt_index:  MDT index of first stripe\n"
-        "\thash_type:  hash type of the striped directory\n"},
+        "\thash_type:  hash type of the striped directory\n"
+        "\tdefault_stripe: set default dirstripe of the directory\n"},
        {"getdirstripe", lfs_getdirstripe, 0,
         "To list the striping info for a given directory\n"
         "or recursively for all directories in a directory tree.\n"
         "usage: getdirstripe [--obd|-O <uuid>] [--quiet|-q] [--verbose|-v]\n"
         "               [--count|-c ] [--index|-i ] [--raw|-R]\n"
-        "               [--recursive | -r] <dir> ..."},
+        "               [--recursive | -r] [ --default_stripe | -D ] <dir> "},
        {"mkdir", lfs_setdirstripe, 0,
         "To create a remote directory on a specified MDT. And this can only\n"
         "be done on MDT0 by administrator.\n"
@@ -1239,6 +1241,7 @@ static int lfs_getstripe_internal(int argc, char **argv,
                {"stripe-count",        no_argument,            0, 'c'},
                {"stripe_count",        no_argument,            0, 'c'},
                {"directory",           no_argument,            0, 'd'},
+               {"default",             no_argument,            0, 'D'},
                {"generation",          no_argument,            0, 'g'},
 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 53, 0)
                /* This formerly implied "stripe-index", but was explicitly
@@ -1278,7 +1281,7 @@ static int lfs_getstripe_internal(int argc, char **argv,
 
        param->maxdepth = 1;
        optind = 0;
-       while ((c = getopt_long(argc, argv, "cdghiLMoO:pqrRsSv",
+       while ((c = getopt_long(argc, argv, "cdDghiLMoO:pqrRsSv",
                                long_opts, NULL)) != -1) {
                switch (c) {
                case 'O':
@@ -1296,6 +1299,9 @@ static int lfs_getstripe_internal(int argc, char **argv,
                case 'd':
                        param->maxdepth = 0;
                        break;
+               case 'D':
+                       param->get_default_lmv = 1;
+                       break;
                case 'r':
                        param->recursive = 1;
                        break;
@@ -1460,18 +1466,19 @@ static int lfs_setdirstripe(int argc, char **argv)
        char                    *stripe_offset_opt = NULL;
        char                    *stripe_count_opt = NULL;
        char                    *stripe_hash_opt = NULL;
-       int                     flags = 0;
+       int                     default_stripe = 0;
 
        struct option long_opts[] = {
                {"count",       required_argument, 0, 'c'},
                {"index",       required_argument, 0, 'i'},
                {"hash-type",   required_argument, 0, 't'},
+               {"default_stripe", required_argument, 0, 'D'},
                {0, 0, 0, 0}
        };
 
        optind = 0;
 
-       while ((c = getopt_long(argc, argv, "c:i:t:", long_opts, NULL)) >= 0) {
+       while ((c = getopt_long(argc, argv, "c:Di:t:", long_opts, NULL)) >= 0) {
                switch (c) {
                case 0:
                        /* Long options. */
@@ -1479,6 +1486,9 @@ static int lfs_setdirstripe(int argc, char **argv)
                case 'c':
                        stripe_count_opt = optarg;
                        break;
+               case 'D':
+                       default_stripe = 1;
+                       break;
                case 'i':
                        stripe_offset_opt = optarg;
                        break;
@@ -1538,8 +1548,16 @@ static int lfs_setdirstripe(int argc, char **argv)
 
        dname = argv[optind];
        do {
-               result = llapi_dir_create_pool(dname, flags, stripe_offset,
-                                              stripe_count, hash_type, NULL);
+               if (default_stripe == 1) {
+                       result = llapi_dir_set_default_lmv_stripe(dname,
+                                                   stripe_offset, stripe_count,
+                                                   hash_type, NULL);
+               } else {
+                       result = llapi_dir_create_pool(dname, 0, stripe_offset,
+                                                      stripe_count, hash_type,
+                                                      NULL);
+               }
+
                if (result) {
                        fprintf(stderr, "error: %s: create stripe dir '%s' "
                                "failed\n", argv[0], dname);
index 11b0a54..64d9595 100644 (file)
@@ -792,6 +792,50 @@ int llapi_file_create_pool(const char *name, unsigned long long stripe_size,
         return 0;
 }
 
+int llapi_dir_set_default_lmv_stripe(const char *name, int stripe_offset,
+                                    int stripe_count, int stripe_pattern,
+                                    const char *pool_name)
+{
+       struct lmv_user_md      lum = { 0 };
+       int                     fd;
+       int                     rc = 0;
+
+       lum.lum_magic = LMV_USER_MAGIC;
+       lum.lum_stripe_offset = stripe_offset;
+       lum.lum_stripe_count = stripe_count;
+       lum.lum_hash_type = stripe_pattern;
+       if (pool_name != NULL) {
+               if (strlen(pool_name) >= sizeof(lum.lum_pool_name)) {
+                       llapi_err_noerrno(LLAPI_MSG_ERROR,
+                                 "error LL_IOC_LMV_SET_DEFAULT_STRIPE '%s'"
+                                 ": too large pool name: %s", name, pool_name);
+                       return -E2BIG;
+               }
+               strncpy(lum.lum_pool_name, pool_name, strlen(pool_name));
+       }
+
+       fd = open(name, O_DIRECTORY | O_RDONLY);
+       if (fd < 0) {
+               rc = -errno;
+               llapi_error(LLAPI_MSG_ERROR, rc, "unable to open '%s'", name);
+               return rc;
+       }
+
+       rc = ioctl(fd, LL_IOC_LMV_SET_DEFAULT_STRIPE, &lum);
+       if (rc < 0) {
+               char *errmsg = "stripe already set";
+               rc = -errno;
+               if (errno != EEXIST && errno != EALREADY)
+                       errmsg = strerror(errno);
+
+               llapi_err_noerrno(LLAPI_MSG_ERROR,
+                                 "error on LL_IOC_LMV_SETSTRIPE '%s' (%d): %s",
+                                 name, fd, errmsg);
+       }
+       close(fd);
+       return rc;
+}
+
 int llapi_dir_create_pool(const char *name, int flags, int stripe_offset,
                          int stripe_count, int stripe_pattern,
                          const char *pool_name)
@@ -1460,8 +1504,12 @@ static int cb_get_dirstripe(char *path, DIR *d, struct find_param *param)
        int ret = 0;
 
        lmv->lum_stripe_count = param->fp_lmv_count;
-       lmv->lum_magic = LMV_MAGIC_V1;
+       if (param->get_default_lmv)
+               lmv->lum_magic = LMV_USER_MAGIC;
+       else
+               lmv->lum_magic = LMV_MAGIC_V1;
        ret = ioctl(dirfd(d), LL_IOC_LMV_GETSTRIPE, lmv);
+
        return ret;
 }
 
@@ -2379,11 +2427,8 @@ void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name,
                        verbose = VERBOSE_OBJID;
        }
 
-       if (lum->lum_magic == LMV_USER_MAGIC)
-               verbose &= ~VERBOSE_OBJID;
-
        if (depth && path && ((verbose != VERBOSE_OBJID)))
-               llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path);
+               llapi_printf(LLAPI_MSG_NORMAL, "%s%s\n", prefix, path);
 
        if (verbose & VERBOSE_COUNT) {
                if (verbose & ~VERBOSE_COUNT)
@@ -2399,16 +2444,16 @@ void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name,
                             (int)lum->lum_stripe_offset);
        }
 
-       if (verbose & VERBOSE_OBJID) {
+       if (verbose & VERBOSE_OBJID && lum->lum_magic != LMV_USER_MAGIC) {
                if ((obdstripe == 1))
                        llapi_printf(LLAPI_MSG_NORMAL,
-                                    "\tmdtidx\t\t FID[seq:oid:ver]\n");
+                                    "mdtidx\t\t FID[seq:oid:ver]\n");
                for (i = 0; i < lum->lum_stripe_count; i++) {
                        int idx = objects[i].lum_mds;
                        struct lu_fid *fid = &objects[i].lum_fid;
                        if ((obdindex == OBD_NOT_FOUND) || (obdindex == idx))
                                llapi_printf(LLAPI_MSG_NORMAL,
-                                            "\t%6u\t\t "DFID"\t\t%s\n",
+                                            "%6u\t\t "DFID"\t\t%s\n",
                                            idx, PFID(fid),
                                            obdindex == idx ? " *" : "");
                }
@@ -2428,7 +2473,7 @@ void llapi_lov_dump_user_lmm(struct find_param *param, char *path, int is_dir)
 {
        __u32 magic;
 
-       if (param->get_lmv)
+       if (param->get_lmv || param->get_default_lmv)
                magic = (__u32)param->fp_lmv_md->lum_magic;
        else
                magic = *(__u32 *)&param->lmd->lmd_lmm; /* lum->lmm_magic */
@@ -3156,7 +3201,7 @@ static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data,
         }
 
        if (d) {
-               if (param->get_lmv) {
+               if (param->get_lmv || param->get_default_lmv) {
                        ret = cb_get_dirstripe(path, d, param);
                } else {
                        ret = ioctl(dirfd(d), LL_IOC_LOV_GETSTRIPE,
@@ -3188,15 +3233,24 @@ static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data,
                         * a check later on in the code path.
                         * The object_seq needs to be set for the "(Default)"
                         * prefix to be displayed. */
-                       struct lov_user_md *lmm = &param->lmd->lmd_lmm;
-                       lmm->lmm_magic = LOV_USER_MAGIC_V1;
-                       if (!param->raw)
-                               ostid_set_seq(&lmm->lmm_oi,
-                                             FID_SEQ_LOV_DEFAULT);
-                       lmm->lmm_stripe_count = 0;
-                       lmm->lmm_stripe_size = 0;
-                       lmm->lmm_stripe_offset = -1;
-                       goto dump;
+                       if (param->get_default_lmv) {
+                               struct lmv_user_md *lum = param->fp_lmv_md;
+
+                               lum->lum_magic = LMV_USER_MAGIC;
+                               lum->lum_stripe_count = 0;
+                               lum->lum_stripe_offset = -1;
+                               goto dump;
+                       } else {
+                               struct lov_user_md *lmm = &param->lmd->lmd_lmm;
+                               lmm->lmm_magic = LOV_USER_MAGIC_V1;
+                               if (!param->raw)
+                                       ostid_set_seq(&lmm->lmm_oi,
+                                                     FID_SEQ_LOV_DEFAULT);
+                               lmm->lmm_stripe_count = 0;
+                               lmm->lmm_stripe_size = 0;
+                               lmm->lmm_stripe_offset = -1;
+                               goto dump;
+                       }
                 } else if (errno == ENODATA && parent != NULL) {
                        if (!param->obduuid && !param->mdtuuid)
                                 llapi_printf(LLAPI_MSG_NORMAL,