Whamcloud - gitweb
LU-5223 lmv: build master LMV EA dynamically build via readdir 51/10751/17
authorFan Yong <fan.yong@intel.com>
Sun, 25 May 2014 16:34:27 +0000 (00:34 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 8 Jul 2014 15:40:01 +0000 (15:40 +0000)
When creating a striped directory, the master object saves the slave
objects (or shards) as internal sub-directories. The sub-directory's
name is composed of ${shard_FID}:${shard_idx}. With the name, we can
easily to know what the shard is and where it should be.

On the other hand, we need to store some information related with the
striped directory, such as magic, hash type, shards count, and so on.
That is the LMV EA (header). We do NOT store the FID of each shard in
the LMV EA. Instead, when we need the shards' FIDs (such as readdir()
on client-side), we can build the entrie LMV EA on the MDT (in RAM) by
iterating the sub-directory entries that are contained in the master
object of the striped directroy.

Above mechanism can simplify the striped directory create operation.
For very large striped directory, logging the FIDs array in the LMV
EA will be trouble. It also simplify the LFSCK for verifying striped
directory, because it reduces the inconsistency sources.

Another fixing is about the lmv_master_fid in master LMV EA header,
it is redundant information, and may become one of the inconsistency
sources. So replace it with two __u64 padding fields.

Signed-off-by: Fan Yong <fan.yong@intel.com>
Change-Id: If7ddec892b75ff8f6e14d9f3f7a3ae0fa065239e
Reviewed-on: http://review.whamcloud.com/10751
Tested-by: Jenkins
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
18 files changed:
lustre/include/lustre/lustre_idl.h
lustre/include/lustre_lmv.h
lustre/lfsck/lfsck_engine.c
lustre/lfsck/lfsck_internal.h
lustre/llite/llite_lib.c
lustre/lmv/lmv_obd.c
lustre/lod/lod_internal.h
lustre/lod/lod_lov.c
lustre/lod/lod_object.c
lustre/lod/lproc_lod.c
lustre/mdd/mdd_dir.c
lustre/mdt/mdt_handler.c
lustre/osp/osp_md_object.c
lustre/ptlrpc/wiretest.c
lustre/tests/sanity.sh
lustre/utils/liblustreapi.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index f790fa1..aa2de2b 100644 (file)
@@ -2741,9 +2741,9 @@ struct lmv_mds_md_v1 {
                                         * be used to mark the object status,
                                         * for example migrating or dead. */
        __u32 lmv_layout_version;       /* Used for directory restriping */
-       __u32 lmv_padding;
-       struct lu_fid   lmv_master_fid; /* The FID of the master object, which
-                                        * is the namespace-visible dir FID */
+       __u32 lmv_padding1;
+       __u64 lmv_padding2;
+       __u64 lmv_padding3;
        char lmv_pool_name[LOV_MAXPOOLNAME];    /* pool name */
        struct lu_fid lmv_stripe_fids[0];       /* FIDs for each stripe */
 };
index d65b6bd..687bbfc 100644 (file)
@@ -48,7 +48,6 @@ struct lmv_stripe_md {
        __u32   lsm_md_layout_version;
        __u32   lsm_md_default_count;
        __u32   lsm_md_default_index;
-       struct lu_fid   lsm_md_master_fid;
        char    lsm_md_pool_name[LOV_MAXPOOLNAME];
        struct lmv_oinfo lsm_md_oinfo[0];
 };
@@ -86,21 +85,9 @@ void lmv_free_md(union lmv_mds_md *lmm);
 int lmv_alloc_memmd(struct lmv_stripe_md **lsmp, int stripe_count);
 void lmv_free_memmd(struct lmv_stripe_md *lsm);
 
-static inline void lmv1_cpu_to_le(struct lmv_mds_md_v1 *lmv_dst,
-                                 const struct lmv_mds_md_v1 *lmv_src)
-{
-       int i;
-
-       lmv_dst->lmv_magic = cpu_to_le32(lmv_src->lmv_magic);
-       lmv_dst->lmv_stripe_count = cpu_to_le32(lmv_src->lmv_stripe_count);
-       lmv_dst->lmv_master_mdt_index =
-                       cpu_to_le32(lmv_src->lmv_master_mdt_index);
-       lmv_dst->lmv_hash_type = cpu_to_le32(lmv_src->lmv_hash_type);
-       lmv_dst->lmv_layout_version = cpu_to_le32(lmv_src->lmv_layout_version);
-       for (i = 0; i < lmv_src->lmv_stripe_count; i++)
-               fid_cpu_to_le(&lmv_dst->lmv_stripe_fids[i],
-                             &lmv_src->lmv_stripe_fids[i]);
-}
+int lmvea_load_shards(const struct lu_env *env, struct dt_object *obj,
+                     struct lu_dirent *ent, struct lu_buf *buf,
+                     bool resize);
 
 static inline void lmv1_le_to_cpu(struct lmv_mds_md_v1 *lmv_dst,
                                  const struct lmv_mds_md_v1 *lmv_src)
@@ -118,18 +105,6 @@ static inline void lmv1_le_to_cpu(struct lmv_mds_md_v1 *lmv_dst,
                              &lmv_src->lmv_stripe_fids[i]);
 }
 
-static inline void lmv_cpu_to_le(union lmv_mds_md *lmv_dst,
-                                const union lmv_mds_md *lmv_src)
-{
-       switch (lmv_src->lmv_magic) {
-       case LMV_MAGIC_V1:
-               lmv1_cpu_to_le(&lmv_dst->lmv_md_v1, &lmv_src->lmv_md_v1);
-               break;
-       default:
-               break;
-       }
-}
-
 static inline void lmv_le_to_cpu(union lmv_mds_md *lmv_dst,
                                 const union lmv_mds_md *lmv_src)
 {
index 87b442d..325a7a1 100644 (file)
@@ -158,7 +158,8 @@ static int lfsck_master_dir_engine(const struct lu_env *env,
        struct dt_object                *dir    = lfsck->li_obj_dir;
        const struct dt_it_ops          *iops   = &dir->do_index_ops->dio_it;
        struct dt_it                    *di     = lfsck->li_di_dir;
-       struct lu_dirent                *ent    = &info->lti_ent;
+       struct lu_dirent                *ent    =
+                       (struct lu_dirent *)info->lti_key;
        struct lu_fid                   *fid    = &info->lti_fid;
        struct lfsck_bookmark           *bk     = &lfsck->li_bookmark_ram;
        struct ptlrpc_thread            *thread = &lfsck->li_thread;
index e00d856..1deb99c 100644 (file)
@@ -557,10 +557,8 @@ struct lfsck_thread_info {
                char                    lti_lma_old[LMA_OLD_SIZE];
        };
        struct dt_object_format lti_dof;
-       /* lti_ent and lti_key must be conjoint,
-        * then lti_ent::lde_name will be lti_key. */
-       struct lu_dirent        lti_ent;
-       char                    lti_key[NAME_MAX + 16];
+       /* There will be '\0' at the end of the name. */
+       char            lti_key[sizeof(struct lu_dirent) + NAME_MAX + 1];
        char                    lti_tmpbuf[LFSCK_TMPBUF_LEN];
        struct lfsck_request    lti_lr;
        struct lfsck_async_interpret_args lti_laia;
index 8a43a1f..7e49c90 100644 (file)
@@ -1378,12 +1378,11 @@ static int ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
                struct lmv_stripe_md    *old_lsm = lli->lli_lsm_md;
                int                     idx;
 
-               CERROR("%s: lmv layout mismatch "DFID"(%p)/"DFID"(%p)"
+               CERROR("%s: inode "DFID"(%p)'s lmv layout mismatch (%p)/(%p)"
                       "magic:0x%x/0x%x stripe count: %d/%d master_mdt: %d/%d"
                       "hash_type:0x%x/0x%x layout: 0x%x/0x%x pool:%s/%s\n",
-                      ll_get_fsname(inode->i_sb, NULL, 0),
-                      PFID(&lsm->lsm_md_master_fid), lsm,
-                      PFID(&old_lsm->lsm_md_master_fid), old_lsm,
+                      ll_get_fsname(inode->i_sb, NULL, 0), PFID(&lli->lli_fid),
+                      inode, lsm, old_lsm,
                       lsm->lsm_md_magic, old_lsm->lsm_md_magic,
                       lsm->lsm_md_stripe_count,
                       old_lsm->lsm_md_stripe_count,
index 368057a..c1a5d20 100644 (file)
@@ -3088,13 +3088,9 @@ static int lmv_unpack_md_v1(struct obd_export *exp, struct lmv_stripe_md *lsm,
        else
                lsm->lsm_md_hash_type = le32_to_cpu(lmm1->lmv_hash_type);
        lsm->lsm_md_layout_version = le32_to_cpu(lmm1->lmv_layout_version);
-       fid_le_to_cpu(&lsm->lsm_md_master_fid, &lmm1->lmv_master_fid);
        cplen = strlcpy(lsm->lsm_md_pool_name, lmm1->lmv_pool_name,
                        sizeof(lsm->lsm_md_pool_name));
 
-       if (!fid_is_sane(&lsm->lsm_md_master_fid))
-               RETURN(-EPROTO);
-
        if (cplen >= sizeof(lsm->lsm_md_pool_name))
                RETURN(-E2BIG);
 
index ac1d256..7d9b95f 100644 (file)
@@ -158,7 +158,8 @@ struct lod_device {
        spinlock_t            lod_connects_lock;
        int                   lod_connects;
        unsigned int          lod_recovery_completed:1,
-                             lod_initialized:1;
+                             lod_initialized:1,
+                             lod_lmv_failout:1;
 
        /* lov settings descriptor storing static information */
        struct lov_desc       lod_desc;
@@ -457,6 +458,8 @@ int lod_procfs_init(struct lod_device *lod);
 void lod_procfs_fini(struct lod_device *lod);
 
 /* lod_object.c */
+int lod_load_lmv_shards(const struct lu_env *env, struct lod_object *lo,
+                       struct lu_buf *buf, bool resize);
 int lod_object_set_pool(struct lod_object *o, char *pool);
 int lod_declare_striped_object(const struct lu_env *env, struct dt_object *dt,
                               struct lu_attr *attr,
index 4ff0f10..80e96cd 100644 (file)
 /*
  * lustre/lod/lod_lov.c
  *
- * Author: Alex Zhuravlev <alexey.zhuravlev@intel.com> 
+ * Author: Alex Zhuravlev <alexey.zhuravlev@intel.com>
  */
 
 #define DEBUG_SUBSYSTEM S_MDS
 
 #include <obd_class.h>
 #include <lustre_lfsck.h>
+#include <lustre_lmv.h>
 
 #include "lod_internal.h"
 
@@ -843,6 +844,7 @@ out:
 int lod_load_striping_locked(const struct lu_env *env, struct lod_object *lo)
 {
        struct lod_thread_info  *info = lod_env_info(env);
+       struct lu_buf           *buf  = &info->lti_buf;
        struct dt_object        *next = dt_object_child(&lo->ldo_obj);
        int                      rc = 0;
        ENTRY;
@@ -866,20 +868,34 @@ int lod_load_striping_locked(const struct lu_env *env, struct lod_object *lo)
                 * there is LOV EA (striping information) in this object
                 * let's parse it and create in-core objects for the stripes
                 */
-               info->lti_buf.lb_buf = info->lti_ea_store;
-               info->lti_buf.lb_len = info->lti_ea_store_size;
-               rc = lod_parse_striping(env, lo, &info->lti_buf);
+               buf->lb_buf = info->lti_ea_store;
+               buf->lb_len = info->lti_ea_store_size;
+               rc = lod_parse_striping(env, lo, buf);
        } else if (S_ISDIR(lu_object_attr(lod2lu_obj(lo)))) {
                rc = lod_get_lmv_ea(env, lo);
-               if (rc <= 0)
-                       GOTO(out, rc);
+               if (rc < sizeof(struct lmv_mds_md_v1))
+                       GOTO(out, rc = rc > 0 ? -EINVAL : rc);
+
+               buf->lb_buf = info->lti_ea_store;
+               buf->lb_len = info->lti_ea_store_size;
+               if (rc == sizeof(struct lmv_mds_md_v1)) {
+                       rc = lod_load_lmv_shards(env, lo, buf, true);
+                       if (buf->lb_buf != info->lti_ea_store) {
+                               OBD_FREE_LARGE(info->lti_ea_store,
+                                              info->lti_ea_store_size);
+                               info->lti_ea_store = buf->lb_buf;
+                               info->lti_ea_store_size = buf->lb_len;
+                       }
+
+                       if (rc < 0)
+                               GOTO(out, rc);
+               }
+
                /*
                 * there is LOV EA (striping information) in this object
                 * let's parse it and create in-core objects for the stripes
                 */
-               info->lti_buf.lb_buf = info->lti_ea_store;
-               info->lti_buf.lb_len = info->lti_ea_store_size;
-               rc = lod_parse_dir_striping(env, lo, &info->lti_buf);
+               rc = lod_parse_dir_striping(env, lo, buf);
        }
 out:
        RETURN(rc);
index d6dc2e5..fb43a8d 100644 (file)
@@ -668,6 +668,201 @@ static struct dt_index_operations lod_striped_index_ops = {
 };
 
 /**
+ * Append the FID for each shard of the striped directory after the
+ * given LMV EA header.
+ *
+ * To simplify striped directory and the consistency verification,
+ * we only store the LMV EA header on disk, for both master object
+ * and slave objects. When someone wants to know the whole LMV EA,
+ * such as client readdir(), we can build the entrie LMV EA on the
+ * MDT side (in RAM) via iterating the sub-directory entries that
+ * are contained in the master object of the stripe directory.
+ *
+ * For the master object of the striped directroy, the valid name
+ * for each shard is composed of the ${shard_FID}:${shard_idx}.
+ *
+ * There may be holes in the LMV EA if some shards' name entries
+ * are corrupted or lost.
+ *
+ * \param[in] env      pointer to the thread context
+ * \param[in] lo       pointer to the master object of the striped directory
+ * \param[in] buf      pointer to the lu_buf which will hold the LMV EA
+ * \param[in] resize   whether re-allocate the buffer if it is not big enough
+ *
+ * \retval             positive size of the LMV EA
+ * \retval             0 for nothing to be loaded
+ * \retval             negative error number on failure
+ */
+int lod_load_lmv_shards(const struct lu_env *env, struct lod_object *lo,
+                       struct lu_buf *buf, bool resize)
+{
+       struct lu_dirent        *ent    =
+                       (struct lu_dirent *)lod_env_info(env)->lti_key;
+       struct lod_device       *lod    = lu2lod_dev(lo->ldo_obj.do_lu.lo_dev);
+       struct dt_object        *obj    = dt_object_child(&lo->ldo_obj);
+       struct lmv_mds_md_v1    *lmv1   = buf->lb_buf;
+       struct dt_it            *it;
+       const struct dt_it_ops  *iops;
+       __u32                    stripes;
+       __u32                    magic  = le32_to_cpu(lmv1->lmv_magic);
+       int                      size;
+       int                      rc;
+       ENTRY;
+
+       /* If it is not a striped directory, then load nothing. */
+       if (magic != LMV_MAGIC_V1)
+               RETURN(0);
+
+       /* If it is in migration (or failure), then load nothing. */
+       if (le32_to_cpu(lmv1->lmv_hash_type) & LMV_HASH_FLAG_MIGRATION)
+               RETURN(0);
+
+       stripes = le32_to_cpu(lmv1->lmv_stripe_count);
+       if (stripes < 1)
+               RETURN(0);
+
+       size = lmv_mds_md_size(stripes, magic);
+       if (buf->lb_len < size) {
+               struct lu_buf tbuf;
+
+               if (!resize)
+                       RETURN(-ERANGE);
+
+               tbuf = *buf;
+               buf->lb_buf = NULL;
+               buf->lb_len = 0;
+               lu_buf_alloc(buf, size);
+               lmv1 = buf->lb_buf;
+               if (lmv1 == NULL)
+                       RETURN(-ENOMEM);
+
+               memcpy(buf->lb_buf, tbuf.lb_buf, tbuf.lb_len);
+       }
+
+       if (unlikely(!dt_try_as_dir(env, obj)))
+               RETURN(-ENOTDIR);
+
+       memset(&lmv1->lmv_stripe_fids[0], 0, stripes * sizeof(struct lu_fid));
+       iops = &obj->do_index_ops->dio_it;
+       it = iops->init(env, obj, LUDA_64BITHASH, BYPASS_CAPA);
+       if (IS_ERR(it))
+               RETURN(PTR_ERR(it));
+
+       rc = iops->load(env, it, 0);
+       if (rc == 0)
+               rc = iops->next(env, it);
+       else if (rc > 0)
+               rc = 0;
+
+       while (rc == 0) {
+               char             name[FID_LEN + 2] = "";
+               struct lu_fid    fid;
+               __u32            index;
+               int              len;
+
+               rc = iops->rec(env, it, (struct dt_rec *)ent, LUDA_64BITHASH);
+               if (rc != 0)
+                       break;
+
+               rc = -EIO;
+
+               fid_le_to_cpu(&fid, &ent->lde_fid);
+               ent->lde_namelen = le16_to_cpu(ent->lde_namelen);
+               if (ent->lde_name[0] == '.') {
+                       if (ent->lde_namelen == 1)
+                               goto next;
+
+                       if (ent->lde_namelen == 2 && ent->lde_name[1] == '.')
+                               goto next;
+               }
+
+               len = snprintf(name, FID_LEN + 1, DFID":", PFID(&ent->lde_fid));
+               /* The ent->lde_name is composed of ${FID}:${index} */
+               if (ent->lde_namelen < len + 1 ||
+                   memcmp(ent->lde_name, name, len) != 0) {
+                       CDEBUG(lod->lod_lmv_failout ? D_ERROR : D_INFO,
+                              "%s: invalid shard name %.*s with the FID "DFID
+                              " for the striped directory "DFID", %s\n",
+                              lod2obd(lod)->obd_name, ent->lde_namelen,
+                              ent->lde_name, PFID(&fid),
+                              PFID(lu_object_fid(&obj->do_lu)),
+                              lod->lod_lmv_failout ? "failout" : "skip");
+
+                       if (lod->lod_lmv_failout)
+                               break;
+
+                       goto next;
+               }
+
+               index = 0;
+               do {
+                       if (ent->lde_name[len] < '0' ||
+                           ent->lde_name[len] > '9') {
+                               CDEBUG(lod->lod_lmv_failout ? D_ERROR : D_INFO,
+                                      "%s: invalid shard name %.*s with the "
+                                      "FID "DFID" for the striped directory "
+                                      DFID", %s\n",
+                                      lod2obd(lod)->obd_name, ent->lde_namelen,
+                                      ent->lde_name, PFID(&fid),
+                                      PFID(lu_object_fid(&obj->do_lu)),
+                                      lod->lod_lmv_failout ?
+                                      "failout" : "skip");
+
+                               if (lod->lod_lmv_failout)
+                                       break;
+
+                               goto next;
+                       }
+
+                       index = index * 10 + ent->lde_name[len++] - '0';
+               } while (len < ent->lde_namelen);
+
+               if (len == ent->lde_namelen) {
+                       /* Out of LMV EA range. */
+                       if (index >= stripes) {
+                               CERROR("%s: the shard %.*s for the striped "
+                                      "directory "DFID" is out of the known "
+                                      "LMV EA range [0 - %u], failout\n",
+                                      lod2obd(lod)->obd_name, ent->lde_namelen,
+                                      ent->lde_name,
+                                      PFID(lu_object_fid(&obj->do_lu)),
+                                      stripes - 1);
+
+                               break;
+                       }
+
+                       /* The slot has been occupied. */
+                       if (!fid_is_zero(&lmv1->lmv_stripe_fids[index])) {
+                               struct lu_fid fid0;
+
+                               fid_le_to_cpu(&fid0,
+                                       &lmv1->lmv_stripe_fids[index]);
+                               CERROR("%s: both the shard "DFID" and "DFID
+                                      " for the striped directory "DFID
+                                      " claim the same LMV EA slot at the "
+                                      "index %d, failout\n",
+                                      lod2obd(lod)->obd_name,
+                                      PFID(&fid0), PFID(&fid),
+                                      PFID(lu_object_fid(&obj->do_lu)), index);
+
+                               break;
+                       }
+
+                       /* stored as LE mode */
+                       lmv1->lmv_stripe_fids[index] = ent->lde_fid;
+
+next:
+                       rc = iops->next(env, it);
+               }
+       }
+
+       iops->put(env, it);
+       iops->fini(env, it);
+
+       RETURN(rc > 0 ? lmv_mds_md_size(stripes, magic) : rc);
+}
+
+/**
  * Implementation of dt_object_operations:: do_index_try
  *
  * This function will try to initialize the index api pointer for the
@@ -1018,6 +1213,42 @@ static int lod_xattr_get(const struct lu_env *env, struct dt_object *dt,
        ENTRY;
 
        rc = dt_xattr_get(env, dt_object_child(dt), buf, name, capa);
+       if (strcmp(name, XATTR_NAME_LMV) == 0) {
+               struct lmv_mds_md_v1    *lmv1;
+               int                      rc1 = 0;
+
+               if (rc > sizeof(*lmv1))
+                       RETURN(rc);
+
+               if (rc < sizeof(*lmv1))
+                       RETURN(rc = rc > 0 ? -EINVAL : rc);
+
+               if (buf->lb_buf == NULL || buf->lb_len == 0) {
+                       CLASSERT(sizeof(*lmv1) <= sizeof(info->lti_key));
+
+                       info->lti_buf.lb_buf = info->lti_key;
+                       info->lti_buf.lb_len = sizeof(*lmv1);
+                       rc = dt_xattr_get(env, dt_object_child(dt),
+                                         &info->lti_buf, name, capa);
+                       if (unlikely(rc != sizeof(*lmv1)))
+                               RETURN(rc = rc > 0 ? -EINVAL : rc);
+
+                       lmv1 = info->lti_buf.lb_buf;
+                       /* The on-disk LMV EA only contains header, but the
+                        * returned LMV EA size should contain the space for
+                        * the FIDs of all shards of the striped directory. */
+                       if (le32_to_cpu(lmv1->lmv_magic) == LMV_MAGIC_V1)
+                               rc = lmv_mds_md_size(
+                                       le32_to_cpu(lmv1->lmv_stripe_count),
+                                       LMV_MAGIC_V1);
+               } else {
+                       rc1 = lod_load_lmv_shards(env, lod_dt_obj(dt),
+                                                 buf, false);
+               }
+
+               RETURN(rc = rc1 != 0 ? rc1 : rc);
+       }
+
        if (rc != -ENODATA || !S_ISDIR(dt->do_lu.lo_header->loh_attr & S_IFMT))
                RETURN(rc);
 
@@ -1081,8 +1312,7 @@ out:
 /**
  * Master LMVEA will be same as slave LMVEA, except
  * 1. different magic
- * 2. No lmv_stripe_fids on slave
- * 3. lmv_master_mdt_index on slave LMV EA will be stripe_index.
+ * 2. lmv_master_mdt_index on slave LMV EA will be stripe_index.
  */
 static void lod_prep_slave_lmv_md(struct lmv_mds_md_v1 *slave_lmv,
                                  const struct lmv_mds_md_v1 *master_lmv)
@@ -1099,9 +1329,7 @@ int lod_prep_lmv_md(const struct lu_env *env, struct dt_object *dt,
        struct lod_object       *lo = lod_dt_obj(dt);
        struct lmv_mds_md_v1    *lmm1;
        int                     stripe_count;
-       int                     lmm_size;
        int                     type = LU_SEQ_RANGE_ANY;
-       int                     i;
        int                     rc;
        __u32                   mdtidx;
        ENTRY;
@@ -1109,11 +1337,13 @@ int lod_prep_lmv_md(const struct lu_env *env, struct dt_object *dt,
        LASSERT(lo->ldo_dir_striped != 0);
        LASSERT(lo->ldo_stripenr > 0);
        stripe_count = lo->ldo_stripenr;
-       lmm_size = lmv_mds_md_size(stripe_count, LMV_MAGIC);
-       if (info->lti_ea_store_size < lmm_size) {
-               rc = lod_ea_store_resize(info, lmm_size);
+       /* Only store the LMV EA heahder on the disk. */
+       if (info->lti_ea_store_size < sizeof(*lmm1)) {
+               rc = lod_ea_store_resize(info, sizeof(*lmm1));
                if (rc != 0)
                        RETURN(rc);
+       } else {
+               memset(info->lti_ea_store, 0, sizeof(*lmm1));
        }
 
        lmm1 = (struct lmv_mds_md_v1 *)info->lti_ea_store;
@@ -1126,18 +1356,8 @@ int lod_prep_lmv_md(const struct lu_env *env, struct dt_object *dt,
                RETURN(rc);
 
        lmm1->lmv_master_mdt_index = cpu_to_le32(mdtidx);
-       fid_cpu_to_le(&lmm1->lmv_master_fid, lu_object_fid(&dt->do_lu));
-       for (i = 0; i < lo->ldo_stripenr; i++) {
-               struct dt_object *dto;
-
-               dto = lo->ldo_stripe[i];
-               LASSERT(dto != NULL);
-               fid_cpu_to_le(&lmm1->lmv_stripe_fids[i],
-                             lu_object_fid(&dto->do_lu));
-       }
-
        lmv_buf->lb_buf = info->lti_ea_store;
-       lmv_buf->lb_len = lmm_size;
+       lmv_buf->lb_len = sizeof(*lmm1);
        lo->ldo_dir_striping_cached = 1;
 
        RETURN(rc);
@@ -1168,7 +1388,7 @@ int lod_parse_dir_striping(const struct lu_env *env, struct lod_object *lo,
        if (le32_to_cpu(lmv1->lmv_magic) != LMV_MAGIC_V1)
                RETURN(-EINVAL);
 
-       if (le32_to_cpu(lmv1->lmv_stripe_count) <= 1)
+       if (le32_to_cpu(lmv1->lmv_stripe_count) < 1)
                RETURN(0);
 
        LASSERT(lo->ldo_stripe == NULL);
@@ -1579,8 +1799,12 @@ static int lod_dir_declare_xattr_set(const struct lu_env *env,
        if (rc != 0)
                RETURN(rc);
 
-       if (lo->ldo_stripenr == 0)
-               RETURN(rc);
+       /* Note: Do not set LinkEA on sub-stripes, otherwise
+        * it will confuse the fid2path process(see mdt_path_current()).
+        * The linkEA between master and sub-stripes is set in
+        * lod_xattr_set_lmv(). */
+       if (lo->ldo_stripenr == 0 || strcmp(name, XATTR_NAME_LINK) == 0)
+               RETURN(0);
 
        for (i = 0; i < lo->ldo_stripenr; i++) {
                LASSERT(lo->ldo_stripe[i]);
@@ -1673,8 +1897,12 @@ static int lod_xattr_set_internal(const struct lu_env *env,
        if (rc != 0 || !S_ISDIR(dt->do_lu.lo_header->loh_attr))
                RETURN(rc);
 
-       if (lo->ldo_stripenr == 0)
-               RETURN(rc);
+       /* Note: Do not set LinkEA on sub-stripes, otherwise
+        * it will confuse the fid2path process(see mdt_path_current()).
+        * The linkEA between master and sub-stripes is set in
+        * lod_xattr_set_lmv(). */
+       if (lo->ldo_stripenr == 0 || strcmp(name, XATTR_NAME_LINK) == 0)
+               RETURN(0);
 
        for (i = 0; i < lo->ldo_stripenr; i++) {
                LASSERT(lo->ldo_stripe[i]);
index 1598658..b2318bb 100644 (file)
@@ -437,6 +437,43 @@ LPROC_SEQ_FOPS_RO_TYPE(lod, dt_kbytesavail);
 LPROC_SEQ_FOPS_RO_TYPE(lod, dt_filestotal);
 LPROC_SEQ_FOPS_RO_TYPE(lod, dt_filesfree);
 
+static int lod_lmv_failout_seq_show(struct seq_file *m, void *v)
+{
+       struct obd_device *dev = m->private;
+       struct lod_device *lod;
+
+       LASSERT(dev != NULL);
+       lod = lu2lod_dev(dev->obd_lu_dev);
+
+       return seq_printf(m, "%d\n", lod->lod_lmv_failout ? 1 : 0);
+}
+
+static ssize_t
+lod_lmv_failout_seq_write(struct file *file, const char *buffer,
+                         size_t count, loff_t *off)
+{
+       struct seq_file         *m      = file->private_data;
+       struct obd_device       *dev    = m->private;
+       struct lod_device       *lod;
+       int                      val    = 0;
+       int                      rc;
+
+       LASSERT(dev != NULL);
+       lod = lu2lod_dev(dev->obd_lu_dev);
+
+       rc = lprocfs_write_helper(buffer, count, &val);
+       if (rc != 0)
+               return rc;
+
+       if (val != 0)
+               lod->lod_lmv_failout = 1;
+       else
+               lod->lod_lmv_failout = 0;
+
+       return count;
+}
+LPROC_SEQ_FOPS(lod_lmv_failout);
+
 static struct lprocfs_seq_vars lprocfs_lod_obd_vars[] = {
        { .name =       "uuid",
          .fops =       &lod_uuid_fops          },
@@ -460,6 +497,8 @@ static struct lprocfs_seq_vars lprocfs_lod_obd_vars[] = {
          .fops =       &lod_qos_thresholdrr_fops },
        { .name =       "qos_maxage",
          .fops =       &lod_qos_maxage_fops    },
+       { .name =       "lmv_failout",
+         .fops =       &lod_lmv_failout_fops   },
        { 0 }
 };
 
index d85dfef..3b22a66 100644 (file)
@@ -3376,11 +3376,11 @@ static int mdd_migrate_create(const struct lu_env *env,
        }
 
        mgr_ea = (struct lmv_mds_md_v1 *)info->mti_xattr_buf;
+       memset(mgr_ea, 0, sizeof(mgr_ea));
        mgr_ea->lmv_magic = cpu_to_le32(LMV_MAGIC_V1);
        mgr_ea->lmv_stripe_count = cpu_to_le32(2);
        mgr_ea->lmv_master_mdt_index = mdd_seq_site(mdd)->ss_node_id;
        mgr_ea->lmv_hash_type = cpu_to_le32(LMV_HASH_FLAG_MIGRATION);
-       fid_cpu_to_le(&mgr_ea->lmv_master_fid, mdd_object_fid(mdd_sobj));
        fid_cpu_to_le(&mgr_ea->lmv_stripe_fids[0], mdd_object_fid(mdd_sobj));
        fid_cpu_to_le(&mgr_ea->lmv_stripe_fids[1], mdd_object_fid(mdd_tobj));
 
index f6d5a58..f64795f 100644 (file)
@@ -5331,44 +5331,21 @@ static int mdt_path_current(struct mdt_thread_info *info,
                if (IS_ERR(mdt_obj))
                        GOTO(out, rc = PTR_ERR(mdt_obj));
 
-               if (mdt_object_remote(mdt_obj)) {
+               if (!mdt_object_exists(mdt_obj)) {
                        mdt_object_put(info->mti_env, mdt_obj);
-                       GOTO(remote_out, rc = -EREMOTE);
-               }
-
-               lmv_buf.lb_buf = info->mti_xattr_buf;
-               lmv_buf.lb_len = sizeof(info->mti_xattr_buf);
-
-               /* Check if it is slave stripes */
-               rc = mo_xattr_get(info->mti_env, mdt_object_child(mdt_obj),
-                                 &lmv_buf, XATTR_NAME_LMV);
-               if (rc > 0) {
-                       union lmv_mds_md *lmm = lmv_buf.lb_buf;
-
-                       /* For slave stripes, get its master */
-                       if (le32_to_cpu(lmm->lmv_magic) == LMV_MAGIC_STRIPE) {
-                               struct lmv_mds_md_v1 *lmm1 = &lmm->lmv_md_v1;
-
-                               fid_le_to_cpu(tmpfid, &lmm1->lmv_master_fid);
-                               if (!fid_is_sane(tmpfid)) {
-                                       mdt_object_put(info->mti_env, mdt_obj);
-                                       GOTO(out, rc = -EINVAL);
-                               }
-                               mdt_object_put(info->mti_env, mdt_obj);
-                               pli->pli_fids[pli->pli_fidcount] = *tmpfid;
-                               continue;
-                       }
+                       GOTO(out, rc = -ENOENT);
                }
 
-               if (!mdt_object_exists(mdt_obj)) {
+               if (mdt_object_remote(mdt_obj)) {
                        mdt_object_put(info->mti_env, mdt_obj);
-                       GOTO(out, rc = -ENOENT);
+                       GOTO(remote_out, rc = -EREMOTE);
                }
 
                rc = mdt_links_read(info, mdt_obj, &ldata);
-               mdt_object_put(info->mti_env, mdt_obj);
-               if (rc != 0)
+               if (rc != 0) {
+                       mdt_object_put(info->mti_env, mdt_obj);
                        GOTO(out, rc);
+               }
 
                leh = buf->lb_buf;
                lee = (struct link_ea_entry *)(leh + 1); /* link #0 */
@@ -5389,6 +5366,26 @@ static int mdt_path_current(struct mdt_thread_info *info,
                                pli->pli_linkno++;
                }
 
+               lmv_buf.lb_buf = info->mti_xattr_buf;
+               lmv_buf.lb_len = sizeof(info->mti_xattr_buf);
+               /* Check if it is slave stripes */
+               rc = mo_xattr_get(info->mti_env, mdt_object_child(mdt_obj),
+                                 &lmv_buf, XATTR_NAME_LMV);
+               mdt_object_put(info->mti_env, mdt_obj);
+               if (rc > 0) {
+                       union lmv_mds_md *lmm = lmv_buf.lb_buf;
+
+                       /* For slave stripes, get its master */
+                       if (le32_to_cpu(lmm->lmv_magic) == LMV_MAGIC_STRIPE) {
+                               pli->pli_fids[pli->pli_fidcount] = *tmpfid;
+                               continue;
+                       }
+               } else if (rc < 0 && rc != -ENODATA) {
+                       GOTO(out, rc);
+               }
+
+               rc = 0;
+
                /* Pack the name in the end of the buffer */
                ptr -= tmpname->ln_namelen;
                if (ptr - 1 <= pli->pli_path)
index ea5ef0a..d84a259 100644 (file)
@@ -515,14 +515,18 @@ again:
 static struct dt_key *osp_it_key(const struct lu_env *env,
                                 const struct dt_it *di)
 {
-       LBUG();
-       return NULL;
+       struct osp_it           *it = (struct osp_it *)di;
+       struct lu_dirent        *ent = (struct lu_dirent *)it->ooi_ent;
+
+       return (struct dt_key *)ent->lde_name;
 }
 
 static int osp_it_key_size(const struct lu_env *env, const struct dt_it *di)
 {
-       LBUG();
-       return 0;
+       struct osp_it           *it = (struct osp_it *)di;
+       struct lu_dirent        *ent = (struct lu_dirent *)it->ooi_ent;
+
+       return (int)le16_to_cpu(ent->lde_namelen);
 }
 
 static int osp_md_index_it_rec(const struct lu_env *env, const struct dt_it *di,
@@ -537,11 +541,33 @@ static int osp_md_index_it_rec(const struct lu_env *env, const struct dt_it *di,
        return 0;
 }
 
+/**
+ * Locate the iteration cursor to the specified position (cookie).
+ *
+ * \param[in] env      pointer to the thread context
+ * \param[in] di       pointer to the iteration structure
+ * \param[in] hash     the specified position
+ *
+ * \retval             positive number for locating to the exactly position
+ *                     or the next
+ * \retval             0 for arriving at the end of the iteration
+ * \retval             negative error number on failure
+ */
 static int osp_it_load(const struct lu_env *env, const struct dt_it *di,
                       __u64 hash)
 {
-       LBUG();
-       return 0;
+       struct osp_it   *it     = (struct osp_it *)di;
+       int              rc;
+
+       it->ooi_next = hash;
+       rc = osp_md_index_it_next(env, (struct dt_it *)di);
+       if (rc == 1)
+               return 0;
+
+       if (rc == 0)
+               return 1;
+
+       return rc;
 }
 
 const struct dt_index_operations osp_md_index_ops = {
index c6114e6..62ddffa 100644 (file)
@@ -1519,6 +1519,55 @@ void lustre_assert_wire_constants(void)
        LASSERTF(LOV_PATTERN_CMOBD == 0x00000200UL, "found 0x%.8xUL\n",
                (unsigned)LOV_PATTERN_CMOBD);
 
+       /* Checks for struct lmv_mds_md_v1 */
+       LASSERTF((int)sizeof(struct lmv_mds_md_v1) == 56, "found %lld\n",
+                (long long)(int)sizeof(struct lmv_mds_md_v1));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_magic) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_magic));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_magic) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_magic));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_stripe_count) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_stripe_count));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_stripe_count) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_stripe_count));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_master_mdt_index) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_master_mdt_index));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_master_mdt_index) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_master_mdt_index));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_hash_type) == 12, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_hash_type));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_hash_type) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_hash_type));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_layout_version) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_layout_version));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_layout_version) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_layout_version));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_padding1) == 20, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_padding1));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding1) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding1));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_padding2) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_padding2));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding2) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding2));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_padding3) == 32, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_padding3));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding3) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding3));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_pool_name[16]) == 56, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_pool_name[16]));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_pool_name[16]) == 1, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_pool_name[16]));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_stripe_fids[0]) == 56, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_stripe_fids[0]));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_stripe_fids[0]) == 16, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_stripe_fids[0]));
+       CLASSERT(LMV_MAGIC_V1 == 0x0CD20CD0);
+       CLASSERT(LMV_MAGIC_STRIPE == 0x0CD40CD0);
+       CLASSERT(LMV_HASH_TYPE_MASK == 0x0000ffff);
+       CLASSERT(LMV_HASH_FLAG_MIGRATION == 0x80000000);
+       CLASSERT(LMV_HASH_FLAG_DEAD == 0x40000000);
+
        /* Checks for struct obd_statfs */
        LASSERTF((int)sizeof(struct obd_statfs) == 144, "found %lld\n",
                 (long long)(int)sizeof(struct obd_statfs));
index d725f62..13f112c 100644 (file)
@@ -10340,25 +10340,30 @@ test_162() {
        test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
        # regular file
        FID=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
-       check_path "$tdir/d2/$tfile" $FSNAME $FID --link 0
+       check_path "$tdir/d2/$tfile" $FSNAME $FID --link 0 ||
+               error "check path $tdir/d2/$tfile failed"
 
        # softlink
        ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
        FID=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
-       check_path "$tdir/d2/p/q/r/slink" $FSNAME $FID --link 0
+       check_path "$tdir/d2/p/q/r/slink" $FSNAME $FID --link 0 ||
+               error "check path $tdir/d2/p/q/r/slink failed"
 
        # softlink to wrong file
        ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
        FID=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
-       check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME $FID --link 0
+       check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME $FID --link 0 ||
+               error "check path $tdir/d2/p/q/r/slink.wrong failed"
 
        # hardlink
        ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
        mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
        FID=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
        # fid2path dir/fsname should both work
-       check_path "$tdir/d2/a/b/c/new_file" $FSNAME $FID --link 1
-       check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR $FID --link 0
+       check_path "$tdir/d2/a/b/c/new_file" $FSNAME $FID --link 1 ||
+               error "check path $tdir/d2/a/b/c/new_file failed"
+       check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR $FID --link 0 ||
+               error "check path $DIR/$tdir/d2/p/q/r/hlink failed"
 
        # hardlink count: check that there are 2 links
        # Doesnt work with CMD yet: 17935
@@ -10367,7 +10372,8 @@ test_162() {
 
        # hardlink indexing: remove the first link
        rm $DIR/$tdir/d2/p/q/r/hlink
-       check_path "$tdir/d2/a/b/c/new_file" $FSNAME $FID --link 0
+       check_path "$tdir/d2/a/b/c/new_file" $FSNAME $FID --link 0 ||
+               error "check path $DIR/$tdir/d2/a/b/c/new_file failed"
 
        return 0
 }
@@ -10392,11 +10398,13 @@ test_162b() {
        for ((i=0;i<5;i++)); do
                FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
                        error "get fid for f$i failed"
-               check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
+               check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0 ||
+                       error "check path $tdir/striped_dir/f$i failed"
 
                FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
                        error "get fid for d$i failed"
-               check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
+               check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0 ||
+                       error "check path $tdir/striped_dir/d$i failed"
        done
 
        return 0
index f7f8e69..b4e7729 100644 (file)
@@ -3335,6 +3335,8 @@ static int cb_getstripe(char *path, DIR *parent, DIR **dirp, void *data,
 
                ret = ioctl(dirfd(parent), IOC_MDC_GETFILESTRIPE,
                            (void *)&param->lmd->lmd_lmm);
+       } else {
+               return 0;
        }
 
         if (ret) {
index 416f8fe..9fbaf50 100644 (file)
@@ -691,6 +691,29 @@ check_lov_mds_md_v3(void)
 }
 
 static void
+check_lmv_mds_md_v1(void)
+{
+       BLANK_LINE();
+       CHECK_STRUCT(lmv_mds_md_v1);
+       CHECK_MEMBER(lmv_mds_md_v1, lmv_magic);
+       CHECK_MEMBER(lmv_mds_md_v1, lmv_stripe_count);
+       CHECK_MEMBER(lmv_mds_md_v1, lmv_master_mdt_index);
+       CHECK_MEMBER(lmv_mds_md_v1, lmv_hash_type);
+       CHECK_MEMBER(lmv_mds_md_v1, lmv_layout_version);
+       CHECK_MEMBER(lmv_mds_md_v1, lmv_padding1);
+       CHECK_MEMBER(lmv_mds_md_v1, lmv_padding2);
+       CHECK_MEMBER(lmv_mds_md_v1, lmv_padding3);
+       CHECK_MEMBER(lmv_mds_md_v1, lmv_pool_name[LOV_MAXPOOLNAME]);
+       CHECK_MEMBER(lmv_mds_md_v1, lmv_stripe_fids[0]);
+
+       CHECK_CDEFINE(LMV_MAGIC_V1);
+       CHECK_CDEFINE(LMV_MAGIC_STRIPE);
+       CHECK_CDEFINE(LMV_HASH_TYPE_MASK);
+       CHECK_CDEFINE(LMV_HASH_FLAG_MIGRATION);
+       CHECK_CDEFINE(LMV_HASH_FLAG_DEAD);
+}
+
+static void
 check_obd_statfs(void)
 {
        BLANK_LINE();
@@ -2412,6 +2435,7 @@ main(int argc, char **argv)
        check_lov_ost_data_v1();
        check_lov_mds_md_v1();
        check_lov_mds_md_v3();
+       check_lmv_mds_md_v1();
        check_obd_statfs();
        check_obd_ioobj();
        check_obd_quotactl();
index 55ec116..3537bcf 100644 (file)
@@ -1525,6 +1525,55 @@ void lustre_assert_wire_constants(void)
        LASSERTF(LOV_PATTERN_CMOBD == 0x00000200UL, "found 0x%.8xUL\n",
                (unsigned)LOV_PATTERN_CMOBD);
 
+       /* Checks for struct lmv_mds_md_v1 */
+       LASSERTF((int)sizeof(struct lmv_mds_md_v1) == 56, "found %lld\n",
+                (long long)(int)sizeof(struct lmv_mds_md_v1));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_magic) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_magic));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_magic) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_magic));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_stripe_count) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_stripe_count));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_stripe_count) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_stripe_count));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_master_mdt_index) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_master_mdt_index));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_master_mdt_index) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_master_mdt_index));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_hash_type) == 12, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_hash_type));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_hash_type) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_hash_type));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_layout_version) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_layout_version));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_layout_version) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_layout_version));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_padding1) == 20, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_padding1));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding1) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding1));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_padding2) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_padding2));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding2) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding2));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_padding3) == 32, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_padding3));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding3) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding3));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_pool_name[16]) == 56, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_pool_name[16]));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_pool_name[16]) == 1, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_pool_name[16]));
+       LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_stripe_fids[0]) == 56, "found %lld\n",
+                (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_stripe_fids[0]));
+       LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_stripe_fids[0]) == 16, "found %lld\n",
+                (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_stripe_fids[0]));
+       CLASSERT(LMV_MAGIC_V1 == 0x0CD20CD0);
+       CLASSERT(LMV_MAGIC_STRIPE == 0x0CD40CD0);
+       CLASSERT(LMV_HASH_TYPE_MASK == 0x0000ffff);
+       CLASSERT(LMV_HASH_FLAG_MIGRATION == 0x80000000);
+       CLASSERT(LMV_HASH_FLAG_DEAD == 0x40000000);
+
        /* Checks for struct obd_statfs */
        LASSERTF((int)sizeof(struct obd_statfs) == 144, "found %lld\n",
                 (long long)(int)sizeof(struct obd_statfs));