From de2d5808bd2987f76d2486272e1a9c192ba277d4 Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Mon, 26 May 2014 00:34:27 +0800 Subject: [PATCH] LU-5223 lmv: build master LMV EA dynamically build via readdir 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 Change-Id: If7ddec892b75ff8f6e14d9f3f7a3ae0fa065239e Reviewed-on: http://review.whamcloud.com/10751 Tested-by: Jenkins Reviewed-by: Andreas Dilger Reviewed-by: Alex Zhuravlev Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/include/lustre/lustre_idl.h | 6 +- lustre/include/lustre_lmv.h | 31 +---- lustre/lfsck/lfsck_engine.c | 3 +- lustre/lfsck/lfsck_internal.h | 6 +- lustre/llite/llite_lib.c | 7 +- lustre/lmv/lmv_obd.c | 4 - lustre/lod/lod_internal.h | 5 +- lustre/lod/lod_lov.c | 34 +++-- lustre/lod/lod_object.c | 274 +++++++++++++++++++++++++++++++++---- lustre/lod/lproc_lod.c | 39 ++++++ lustre/mdd/mdd_dir.c | 2 +- lustre/mdt/mdt_handler.c | 57 ++++---- lustre/osp/osp_md_object.c | 38 ++++- lustre/ptlrpc/wiretest.c | 49 +++++++ lustre/tests/sanity.sh | 24 ++-- lustre/utils/liblustreapi.c | 2 + lustre/utils/wirecheck.c | 24 ++++ lustre/utils/wiretest.c | 49 +++++++ 18 files changed, 532 insertions(+), 122 deletions(-) diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index f790fa1..aa2de2b 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -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 */ }; diff --git a/lustre/include/lustre_lmv.h b/lustre/include/lustre_lmv.h index d65b6bd..687bbfc 100644 --- a/lustre/include/lustre_lmv.h +++ b/lustre/include/lustre_lmv.h @@ -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) { diff --git a/lustre/lfsck/lfsck_engine.c b/lustre/lfsck/lfsck_engine.c index 87b442d..325a7a1 100644 --- a/lustre/lfsck/lfsck_engine.c +++ b/lustre/lfsck/lfsck_engine.c @@ -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; diff --git a/lustre/lfsck/lfsck_internal.h b/lustre/lfsck/lfsck_internal.h index e00d856..1deb99c 100644 --- a/lustre/lfsck/lfsck_internal.h +++ b/lustre/lfsck/lfsck_internal.h @@ -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; diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 8a43a1f..7e49c90 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -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, diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index 368057a..c1a5d20 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -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); diff --git a/lustre/lod/lod_internal.h b/lustre/lod/lod_internal.h index ac1d256..7d9b95f 100644 --- a/lustre/lod/lod_internal.h +++ b/lustre/lod/lod_internal.h @@ -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, diff --git a/lustre/lod/lod_lov.c b/lustre/lod/lod_lov.c index 4ff0f10..80e96cd 100644 --- a/lustre/lod/lod_lov.c +++ b/lustre/lod/lod_lov.c @@ -28,13 +28,14 @@ /* * lustre/lod/lod_lov.c * - * Author: Alex Zhuravlev + * Author: Alex Zhuravlev */ #define DEBUG_SUBSYSTEM S_MDS #include #include +#include #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); diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index d6dc2e5..fb43a8d 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -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]); diff --git a/lustre/lod/lproc_lod.c b/lustre/lod/lproc_lod.c index 1598658..b2318bb 100644 --- a/lustre/lod/lproc_lod.c +++ b/lustre/lod/lproc_lod.c @@ -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 } }; diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index d85dfef..3b22a66 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -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)); diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index f6d5a58..f64795f 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -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) diff --git a/lustre/osp/osp_md_object.c b/lustre/osp/osp_md_object.c index ea5ef0a..d84a259 100644 --- a/lustre/osp/osp_md_object.c +++ b/lustre/osp/osp_md_object.c @@ -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 = { diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index c6114e6..62ddffa 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -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)); diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index d725f620..13f112c 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -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 diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index f7f8e69..b4e7729 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -3335,6 +3335,8 @@ static int cb_getstripe(char *path, DIR *parent, DIR **dirp, void *data, ret = ioctl(dirfd(parent), IOC_MDC_GETFILESTRIPE, (void *)¶m->lmd->lmd_lmm); + } else { + return 0; } if (ret) { diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index 416f8fe..9fbaf50 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -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(); diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 55ec116..3537bcf 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -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)); -- 1.8.3.1