From f3f651556282469e9675e5d16e20949e48b8c84a Mon Sep 17 00:00:00 2001 From: Bobi Jam Date: Thu, 6 Apr 2017 07:57:54 +0800 Subject: [PATCH] LU-8998 lov: add composite layout unpacking Update struct lov_stripe_md to accommodate composite layouts. Add methods to unpack composite layouts. Reviewed-on: https://review.whamcloud.com/24849 Change-Id: Ife0b2ae7671dd0ec0020a1da04e7261ef9f7e5f3 Signed-off-by: John L. Hammond Signed-off-by: Bobi Jam Signed-off-by: Niu Yawei Reviewed-by: Jinshan Xiong Reviewed-by: Andreas Dilger --- lustre/include/obd.h | 4 - lustre/lov/lov_ea.c | 496 +++++++++++++++++++++++++++++++--------------- lustre/lov/lov_internal.h | 51 +++-- lustre/lov/lov_io.c | 17 +- lustre/lov/lov_merge.c | 4 +- lustre/lov/lov_object.c | 78 +++++--- lustre/lov/lov_offset.c | 8 +- lustre/lov/lov_pack.c | 122 +++--------- 8 files changed, 455 insertions(+), 325 deletions(-) diff --git a/lustre/include/obd.h b/lustre/include/obd.h index b399149..508aa97 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -76,10 +76,6 @@ static inline void loi_kms_set(struct lov_oinfo *oinfo, __u64 kms) oinfo->loi_kms_valid = 1; } -static inline void loi_init(struct lov_oinfo *loi) -{ -} - struct lov_stripe_md; struct obd_info; diff --git a/lustre/lov/lov_ea.c b/lustre/lov/lov_ea.c index 0007f88..896b403 100644 --- a/lustre/lov/lov_ea.c +++ b/lustre/lov/lov_ea.c @@ -37,15 +37,49 @@ #define DEBUG_SUBSYSTEM S_LOV #include +#include #include #include #include +#include #include "lov_internal.h" -static int lsm_lmm_verify_common(struct lov_mds_md *lmm, int lmm_bytes, - __u16 stripe_count) +static inline void +lu_extent_le_to_cpu(struct lu_extent *dst, const struct lu_extent *src) +{ + dst->e_start = le64_to_cpu(src->e_start); + dst->e_end = le64_to_cpu(src->e_end); +} + +/* Find minimum stripe maxbytes value. For inactive or + * reconnecting targets use LUSTRE_EXT3_STRIPE_MAXBYTES. */ +static loff_t lov_tgt_maxbytes(struct lov_tgt_desc *tgt) +{ + struct obd_import *imp; + loff_t maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES; + + if (!tgt->ltd_active) + return maxbytes; + + imp = tgt->ltd_obd->u.cli.cl_import; + if (imp == NULL) + return maxbytes; + + spin_lock(&imp->imp_lock); + if (imp->imp_state == LUSTRE_IMP_FULL && + (imp->imp_connect_data.ocd_connect_flags & OBD_CONNECT_MAXBYTES) && + imp->imp_connect_data.ocd_maxbytes > 0) + maxbytes = imp->imp_connect_data.ocd_maxbytes; + + spin_unlock(&imp->imp_lock); + + return maxbytes; +} + +static int lsm_lmm_verify_v1v3(struct lov_mds_md *lmm, size_t lmm_size, + u16 stripe_count) { if (stripe_count > LOV_V1_INSANE_STRIPE_COUNT) { CERROR("bad stripe count %d\n", stripe_count); @@ -75,103 +109,106 @@ static int lsm_lmm_verify_common(struct lov_mds_md *lmm, int lmm_bytes, return 0; } -struct lov_stripe_md *lsm_alloc_plain(u16 stripe_count) +static void lsme_free(struct lov_stripe_md_entry *lsme) { - struct lov_stripe_md *lsm; - struct lov_oinfo *loi; - size_t lsm_size; - size_t oinfo_ptrs_size; - int i; - - LASSERT(stripe_count <= LOV_MAX_STRIPE_COUNT); - - oinfo_ptrs_size = sizeof(struct lov_oinfo *) * stripe_count; - lsm_size = sizeof(*lsm) + oinfo_ptrs_size; + unsigned int stripe_count = lsme->lsme_stripe_count; + unsigned int i; + size_t lsme_size; - OBD_ALLOC_LARGE(lsm, lsm_size); - if (!lsm) - return NULL; + for (i = 0; i < stripe_count; i++) + OBD_SLAB_FREE_PTR(lsme->lsme_oinfo[i], lov_oinfo_slab); - for (i = 0; i < stripe_count; i++) { - OBD_SLAB_ALLOC_PTR_GFP(loi, lov_oinfo_slab, GFP_NOFS); - if (loi == NULL) - goto err; - lsm->lsm_oinfo[i] = loi; - } - lsm->lsm_stripe_count = stripe_count; - return lsm; + lsme_size = offsetof(typeof(*lsme), lsme_oinfo[stripe_count]); + OBD_FREE_LARGE(lsme, lsme_size); +} -err: - while (--i >= 0) - OBD_SLAB_FREE(lsm->lsm_oinfo[i], lov_oinfo_slab, sizeof(*loi)); +void lsm_free(struct lov_stripe_md *lsm) +{ + unsigned int entry_count = lsm->lsm_entry_count; + unsigned int i; + size_t lsm_size; - OBD_FREE_LARGE(lsm, lsm_size); + for (i = 0; i < entry_count; i++) + lsme_free(lsm->lsm_entries[i]); - return NULL; + lsm_size = offsetof(typeof(*lsm), lsm_entries[entry_count]); + OBD_FREE(lsm, lsm_size); } -void lsm_free_plain(struct lov_stripe_md *lsm) +/** + * Unpack a struct lov_mds_md into a struct lov_stripe_md_entry. + * + * The caller should set id and extent. + */ +static struct lov_stripe_md_entry * +lsme_unpack(struct lov_obd *lov, struct lov_mds_md *lmm, size_t buf_size, + const char *pool_name, struct lov_ost_data_v1 *objects, + loff_t *maxbytes) { - __u16 stripe_count = lsm->lsm_stripe_count; - int i; + struct lov_stripe_md_entry *lsme; + size_t lsme_size; + loff_t min_stripe_maxbytes = 0; + loff_t lov_bytes; + u32 magic; + u32 pattern; + unsigned int stripe_count; + unsigned int i; + int rc; - for (i = 0; i < stripe_count; i++) - OBD_SLAB_FREE(lsm->lsm_oinfo[i], lov_oinfo_slab, - sizeof(struct lov_oinfo)); - OBD_FREE_LARGE(lsm, sizeof(struct lov_stripe_md) + - stripe_count * sizeof(struct lov_oinfo *)); -} + magic = le32_to_cpu(lmm->lmm_magic); + if (magic != LOV_MAGIC_V1 && magic != LOV_MAGIC_V3) + RETURN(ERR_PTR(-EINVAL)); -/* Find minimum stripe maxbytes value. For inactive or - * reconnecting targets use LUSTRE_EXT3_STRIPE_MAXBYTES. */ -static loff_t lov_tgt_maxbytes(struct lov_tgt_desc *tgt) -{ - struct obd_import *imp; - loff_t maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES; + pattern = le32_to_cpu(lmm->lmm_pattern); + if (pattern & LOV_PATTERN_F_RELEASED) + stripe_count = 0; + else + stripe_count = le16_to_cpu(lmm->lmm_stripe_count); + + if (buf_size < (magic == LOV_MAGIC_V1 ? sizeof(struct lov_mds_md_v1) : + sizeof(struct lov_mds_md_v3))) { + CERROR("LOV EA %s too small: %zu, need %u\n", + magic == LOV_MAGIC_V1 ? "V1" : "V3", buf_size, + lov_mds_md_size(stripe_count, magic == LOV_MAGIC_V1 ? + LOV_MAGIC_V1 : LOV_MAGIC_V3)); + lov_dump_lmm_common(D_WARNING, lmm); + return ERR_PTR(-EINVAL); + } - if (!tgt->ltd_active) - return maxbytes; + rc = lsm_lmm_verify_v1v3(lmm, buf_size, stripe_count); + if (rc < 0) + return ERR_PTR(rc); - imp = tgt->ltd_obd->u.cli.cl_import; - if (imp == NULL) - return maxbytes; + lsme_size = offsetof(typeof(*lsme), lsme_oinfo[stripe_count]); + OBD_ALLOC_LARGE(lsme, lsme_size); + if (lsme == NULL) + RETURN(ERR_PTR(-ENOMEM)); - spin_lock(&imp->imp_lock); - if (imp->imp_state == LUSTRE_IMP_FULL && - (imp->imp_connect_data.ocd_connect_flags & OBD_CONNECT_MAXBYTES) && - imp->imp_connect_data.ocd_maxbytes > 0) - maxbytes = imp->imp_connect_data.ocd_maxbytes; + lsme->lsme_magic = magic; + lsme->lsme_pattern = pattern; + lsme->lsme_stripe_size = le32_to_cpu(lmm->lmm_stripe_size); + lsme->lsme_stripe_count = stripe_count; + lsme->lsme_layout_gen = le16_to_cpu(lmm->lmm_layout_gen); - spin_unlock(&imp->imp_lock); + if (pool_name != NULL) { + size_t pool_name_len; - return maxbytes; -} + pool_name_len = strlcpy(lsme->lsme_pool_name, pool_name, + sizeof(lsme->lsme_pool_name)); + if (pool_name_len >= sizeof(lsme->lsme_pool_name)) + GOTO(out_lsme, rc = -E2BIG); + } -static int lsm_unpackmd_common(struct lov_obd *lov, - struct lov_stripe_md *lsm, - struct lov_mds_md *lmm, - struct lov_ost_data_v1 *objects) -{ - struct lov_oinfo *loi; - loff_t min_stripe_maxbytes = 0; - loff_t lov_bytes; - unsigned int stripe_count; - unsigned int i; + for (i = 0; i < stripe_count; i++) { + struct lov_oinfo *loi; + struct lov_tgt_desc *ltd; - /* - * This supposes lov_mds_md_v1/v3 first fields are - * are the same - */ - lmm_oi_le_to_cpu(&lsm->lsm_oi, &lmm->lmm_oi); - lsm->lsm_stripe_size = le32_to_cpu(lmm->lmm_stripe_size); - lsm->lsm_pattern = le32_to_cpu(lmm->lmm_pattern); - lsm->lsm_layout_gen = le16_to_cpu(lmm->lmm_layout_gen); - lsm->lsm_pool_name[0] = '\0'; + OBD_SLAB_ALLOC_PTR_GFP(loi, lov_oinfo_slab, GFP_NOFS); + if (loi == NULL) + GOTO(out_lsme, rc = -ENOMEM); - stripe_count = lsm_is_released(lsm) ? 0 : lsm->lsm_stripe_count; + lsme->lsme_oinfo[i] = loi; - for (i = 0; i < stripe_count; i++) { - loi = lsm->lsm_oinfo[i]; ostid_le_to_cpu(&objects[i].l_ost_oi, &loi->loi_oi); loi->loi_ost_idx = le32_to_cpu(objects[i].l_ost_idx); loi->loi_ost_gen = le32_to_cpu(objects[i].l_ost_gen); @@ -184,17 +221,18 @@ static int lsm_unpackmd_common(struct lov_obd *lov, (char*)lov->desc.ld_uuid.uuid, loi->loi_ost_idx, lov->desc.ld_tgt_count); lov_dump_lmm_v1(D_WARNING, lmm); - return -EINVAL; + GOTO(out_lsme, rc = -EINVAL); } - if (lov->lov_tgts[loi->loi_ost_idx] == NULL) { + ltd = lov->lov_tgts[loi->loi_ost_idx]; + if (ltd == NULL) { CERROR("%s: OST index %d missing\n", (char*)lov->desc.ld_uuid.uuid, loi->loi_ost_idx); lov_dump_lmm_v1(D_WARNING, lmm); continue; } - lov_bytes = lov_tgt_maxbytes(lov->lov_tgts[loi->loi_ost_idx]); + lov_bytes = lov_tgt_maxbytes(ltd); if (min_stripe_maxbytes == 0 || lov_bytes < min_stripe_maxbytes) min_stripe_maxbytes = lov_bytes; } @@ -202,15 +240,72 @@ static int lsm_unpackmd_common(struct lov_obd *lov, if (min_stripe_maxbytes == 0) min_stripe_maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES; - stripe_count = lsm->lsm_stripe_count ?: lov->desc.ld_tgt_count; lov_bytes = min_stripe_maxbytes * stripe_count; - if (lov_bytes < min_stripe_maxbytes) /* handle overflow */ - lsm->lsm_maxbytes = MAX_LFS_FILESIZE; - else - lsm->lsm_maxbytes = lov_bytes; + if (maxbytes != NULL) { + if (lov_bytes < min_stripe_maxbytes) /* handle overflow */ + *maxbytes = MAX_LFS_FILESIZE; + else + *maxbytes = lov_bytes; + } - return 0; + return lsme; + +out_lsme: + for (i = 0; i < stripe_count; i++) { + struct lov_oinfo *loi = lsme->lsme_oinfo[i]; + + if (loi != NULL) + OBD_SLAB_FREE_PTR(lsme->lsme_oinfo[i], lov_oinfo_slab); + } + OBD_FREE_LARGE(lsme, lsme_size); + + return ERR_PTR(rc); +} + +static struct lov_stripe_md * +lsm_unpackmd_v1v3(struct lov_obd *lov, + struct lov_mds_md *lmm, size_t buf_size, + const char *pool_name, + struct lov_ost_data_v1 *objects) +{ + struct lov_stripe_md *lsm; + struct lov_stripe_md_entry *lsme; + size_t lsm_size; + loff_t maxbytes; + u32 pattern; + int rc; + + pattern = le32_to_cpu(lmm->lmm_pattern); + + lsme = lsme_unpack(lov, lmm, buf_size, pool_name, objects, &maxbytes); + if (IS_ERR(lsme)) + RETURN(ERR_CAST(lsme)); + + lsme->lsme_extent.e_start = 0; + lsme->lsme_extent.e_end = LUSTRE_EOF; + + lsm_size = offsetof(typeof(*lsm), lsm_entries[1]); + OBD_ALLOC(lsm, lsm_size); + if (lsm == NULL) + GOTO(out_lsme, rc = -ENOMEM); + + atomic_set(&lsm->lsm_refc, 1); + spin_lock_init(&lsm->lsm_lock); + lsm->lsm_maxbytes = maxbytes; + lmm_oi_le_to_cpu(&lsm->lsm_oi, &lmm->lmm_oi); + lsm->lsm_magic = le32_to_cpu(lmm->lmm_magic); + lsm->lsm_layout_gen = le16_to_cpu(lmm->lmm_layout_gen); + lsm->lsm_entry_count = 1; + lsm->lsm_is_released = pattern & LOV_PATTERN_F_RELEASED; + lsm->lsm_entries[0] = lsme; + + return lsm; + +out_lsme: + lsme_free(lsme); + + return ERR_PTR(rc); } static void @@ -218,7 +313,8 @@ lsm_stripe_by_index_plain(struct lov_stripe_md *lsm, int *stripeno, loff_t *lov_off, loff_t *swidth) { if (swidth != NULL) - *swidth = (loff_t)lsm->lsm_stripe_size * lsm->lsm_stripe_count; + *swidth = (loff_t)lsm->lsm_entries[0]->lsme_stripe_size * + lsm->lsm_entries[0]->lsme_stripe_count; } static void @@ -226,99 +322,186 @@ lsm_stripe_by_offset_plain(struct lov_stripe_md *lsm, int *stripeno, loff_t *lov_off, loff_t *swidth) { if (swidth != NULL) - *swidth = (loff_t)lsm->lsm_stripe_size * lsm->lsm_stripe_count; + *swidth = (loff_t)lsm->lsm_entries[0]->lsme_stripe_size * + lsm->lsm_entries[0]->lsme_stripe_count; } -static int lsm_lmm_verify_v1(struct lov_mds_md_v1 *lmm, int lmm_bytes, - __u16 *stripe_count) +static inline struct lov_stripe_md * +lsm_unpackmd_v1(struct lov_obd *lov, void *buf, size_t buf_size) { - if (lmm_bytes < sizeof(*lmm)) { - CERROR("lov_mds_md_v1 too small: %d, need at least %d\n", - lmm_bytes, (int)sizeof(*lmm)); - return -EINVAL; - } + struct lov_mds_md_v1 *lmm = buf; - *stripe_count = le16_to_cpu(lmm->lmm_stripe_count); - if (le32_to_cpu(lmm->lmm_pattern) & LOV_PATTERN_F_RELEASED) - *stripe_count = 0; - - if (lmm_bytes < lov_mds_md_size(*stripe_count, LOV_MAGIC_V1)) { - CERROR("LOV EA V1 too small: %d, need %d\n", - lmm_bytes, lov_mds_md_size(*stripe_count, LOV_MAGIC_V1)); - lov_dump_lmm_common(D_WARNING, lmm); - return -EINVAL; - } - - return lsm_lmm_verify_common(lmm, lmm_bytes, *stripe_count); -} - -static int lsm_unpackmd_v1(struct lov_obd *lov, struct lov_stripe_md *lsm, - struct lov_mds_md_v1 *lmm) -{ - return lsm_unpackmd_common(lov, lsm, lmm, lmm->lmm_objects); + return lsm_unpackmd_v1v3(lov, buf, buf_size, NULL, lmm->lmm_objects); } const struct lsm_operations lsm_v1_ops = { - .lsm_free = lsm_free_plain, .lsm_stripe_by_index = lsm_stripe_by_index_plain, .lsm_stripe_by_offset = lsm_stripe_by_offset_plain, - .lsm_lmm_verify = lsm_lmm_verify_v1, .lsm_unpackmd = lsm_unpackmd_v1, }; -static int lsm_lmm_verify_v3(struct lov_mds_md *lmmv1, int lmm_bytes, - __u16 *stripe_count) +static inline struct lov_stripe_md * +lsm_unpackmd_v3(struct lov_obd *lov, void *buf, size_t buf_size) { - struct lov_mds_md_v3 *lmm; + struct lov_mds_md_v3 *lmm = buf; - lmm = (struct lov_mds_md_v3 *)lmmv1; + return lsm_unpackmd_v1v3(lov, buf, buf_size, lmm->lmm_pool_name, + lmm->lmm_objects); +} - if (lmm_bytes < sizeof(*lmm)) { - CERROR("lov_mds_md_v3 too small: %d, need at least %d\n", - lmm_bytes, (int)sizeof(*lmm)); - return -EINVAL; - } +const struct lsm_operations lsm_v3_ops = { + .lsm_stripe_by_index = lsm_stripe_by_index_plain, + .lsm_stripe_by_offset = lsm_stripe_by_offset_plain, + .lsm_unpackmd = lsm_unpackmd_v3, +}; - *stripe_count = le16_to_cpu(lmm->lmm_stripe_count); - if (le32_to_cpu(lmm->lmm_pattern) & LOV_PATTERN_F_RELEASED) - *stripe_count = 0; +static int lsm_verify_comp_md_v1(struct lov_comp_md_v1 *lcm, + size_t lcm_buf_size) +{ + unsigned int entry_count; + unsigned int i; + size_t lcm_size; - if (lmm_bytes < lov_mds_md_size(*stripe_count, LOV_MAGIC_V3)) { - CERROR("LOV EA V3 too small: %d, need %d\n", - lmm_bytes, lov_mds_md_size(*stripe_count, LOV_MAGIC_V3)); - lov_dump_lmm_common(D_WARNING, lmm); - return -EINVAL; + lcm_size = le32_to_cpu(lcm->lcm_size); + if (lcm_buf_size < lcm_size) { + CERROR("bad LCM buffer size %zu, expected %zu\n", + lcm_buf_size, lcm_size); + RETURN(-EINVAL); } - return lsm_lmm_verify_common((struct lov_mds_md_v1 *)lmm, lmm_bytes, - *stripe_count); + entry_count = le16_to_cpu(lcm->lcm_entry_count); + for (i = 0; i < entry_count; i++) { + struct lov_comp_md_entry_v1 *lcme = &lcm->lcm_entries[i]; + size_t blob_offset; + size_t blob_size; + + blob_offset = le32_to_cpu(lcme->lcme_offset); + blob_size = le32_to_cpu(lcme->lcme_size); + + if (lcm_size < blob_offset || lcm_size < blob_size || + lcm_size < blob_offset + blob_size) { + CERROR("LCM entry %u has invalid blob: " + "LCM size = %zu, offset = %zu, size = %zu\n", + le32_to_cpu(lcme->lcme_id), + lcm_size, blob_offset, blob_size); + RETURN(-EINVAL); + } + } + + return 0; +} + +static struct lov_stripe_md_entry * +lsme_unpack_comp(struct lov_obd *lov, struct lov_mds_md *lmm, + size_t lmm_buf_size, loff_t *maxbytes) +{ + unsigned int magic; + unsigned int stripe_count; + + stripe_count = le16_to_cpu(lmm->lmm_stripe_count); + if (stripe_count == 0) + RETURN(ERR_PTR(-EINVAL)); + + magic = le32_to_cpu(lmm->lmm_magic); + if (magic != LOV_MAGIC_V1 && magic != LOV_MAGIC_V3) + RETURN(ERR_PTR(-EINVAL)); + + if (lmm_buf_size < lov_mds_md_size(stripe_count, magic)) + RETURN(ERR_PTR(-EINVAL)); + + if (magic == LOV_MAGIC_V1) { + return lsme_unpack(lov, lmm, lmm_buf_size, NULL, + lmm->lmm_objects, maxbytes); + } else { + struct lov_mds_md_v3 *lmm3 = (struct lov_mds_md_v3 *)lmm; + + return lsme_unpack(lov, lmm, lmm_buf_size, lmm3->lmm_pool_name, + lmm3->lmm_objects, maxbytes); + } } -static int lsm_unpackmd_v3(struct lov_obd *lov, struct lov_stripe_md *lsm, - struct lov_mds_md *lmm) +static struct lov_stripe_md * +lsm_unpackmd_comp_md_v1(struct lov_obd *lov, void *buf, size_t buf_size) { - struct lov_mds_md_v3 *lmm_v3 = (struct lov_mds_md_v3 *)lmm; - size_t cplen; + struct lov_comp_md_v1 *lcm = buf; + struct lov_stripe_md *lsm; + size_t lsm_size; + unsigned int entry_count = 0; + unsigned int i; + loff_t maxbytes; int rc; - rc = lsm_unpackmd_common(lov, lsm, lmm, lmm_v3->lmm_objects); - if (rc != 0) - return rc; + rc = lsm_verify_comp_md_v1(buf, buf_size); + if (rc < 0) + return ERR_PTR(rc); + + entry_count = le16_to_cpu(lcm->lcm_entry_count); + + lsm_size = offsetof(typeof(*lsm), lsm_entries[entry_count]); + OBD_ALLOC(lsm, lsm_size); + if (lsm == NULL) + return ERR_PTR(-ENOMEM); + + atomic_set(&lsm->lsm_refc, 1); + spin_lock_init(&lsm->lsm_lock); + lsm->lsm_magic = le32_to_cpu(lcm->lcm_magic); + lsm->lsm_layout_gen = le32_to_cpu(lcm->lcm_layout_gen); + lsm->lsm_entry_count = entry_count; + lsm->lsm_is_released = true; + lsm->lsm_maxbytes = LLONG_MIN; + + for (i = 0; i < entry_count; i++) { + struct lov_comp_md_entry_v1 *lcme = &lcm->lcm_entries[i]; + struct lov_stripe_md_entry *lsme; + size_t blob_offset; + size_t blob_size; + void *blob; + + blob_offset = le32_to_cpu(lcme->lcme_offset); + blob_size = le32_to_cpu(lcme->lcme_size); + blob = (char *)lcm + blob_offset; + + lsme = lsme_unpack_comp(lov, blob, blob_size, + (i == entry_count - 1) ? &maxbytes : + NULL); + if (IS_ERR(lsme)) + GOTO(out_lsm, rc = PTR_ERR(lsme)); + + if (!(lsme->lsme_pattern & LOV_PATTERN_F_RELEASED)) + lsm->lsm_is_released = false; + + lsm->lsm_entries[i] = lsme; + lsme->lsme_id = le32_to_cpu(lcme->lcme_id); + lu_extent_le_to_cpu(&lsme->lsme_extent, &lcme->lcme_extent); + + if (i == entry_count - 1) { + lsm->lsm_maxbytes = (loff_t)lsme->lsme_extent.e_start + + maxbytes; + /* the last component hasn't been defined, or + * lsm_maxbytes overflowed. */ + if (lsme->lsme_extent.e_end != LUSTRE_EOF || + lsm->lsm_maxbytes < + (loff_t)lsme->lsme_extent.e_start) + lsm->lsm_maxbytes = MAX_LFS_FILESIZE; + } + } - cplen = strlcpy(lsm->lsm_pool_name, lmm_v3->lmm_pool_name, - sizeof(lsm->lsm_pool_name)); - if (cplen >= sizeof(lsm->lsm_pool_name)) - return -E2BIG; + RETURN(lsm); - return 0; +out_lsm: + for (i = 0; i < entry_count; i++) + if (lsm->lsm_entries[i] != NULL) + lsme_free(lsm->lsm_entries[i]); + + OBD_FREE(lsm, lsm_size); + + RETURN(ERR_PTR(rc)); } -const struct lsm_operations lsm_v3_ops = { - .lsm_free = lsm_free_plain, - .lsm_stripe_by_index = lsm_stripe_by_index_plain, - .lsm_stripe_by_offset = lsm_stripe_by_offset_plain, - .lsm_lmm_verify = lsm_lmm_verify_v3, - .lsm_unpackmd = lsm_unpackmd_v3, +const struct lsm_operations lsm_comp_md_v1_ops = { + .lsm_stripe_by_index = lsm_stripe_by_index_plain, + .lsm_stripe_by_offset = lsm_stripe_by_offset_plain, + .lsm_unpackmd = lsm_unpackmd_comp_md_v1, }; void dump_lsm(unsigned int level, const struct lov_stripe_md *lsm) @@ -327,7 +510,8 @@ void dump_lsm(unsigned int level, const struct lov_stripe_md *lsm) " stripe_size %u, stripe_count %u, refc: %d," " layout_gen %u, pool ["LOV_POOLNAMEF"]\n", lsm, POSTID(&lsm->lsm_oi), lsm->lsm_maxbytes, lsm->lsm_magic, - lsm->lsm_stripe_size, lsm->lsm_stripe_count, + lsm->lsm_entries[0]->lsme_stripe_size, + lsm->lsm_entries[0]->lsme_stripe_count, atomic_read(&lsm->lsm_refc), lsm->lsm_layout_gen, - lsm->lsm_pool_name); + lsm->lsm_entries[0]->lsme_pool_name); } diff --git a/lustre/lov/lov_internal.h b/lustre/lov/lov_internal.h index e3ecc04..376c7eb 100644 --- a/lustre/lov/lov_internal.h +++ b/lustre/lov/lov_internal.h @@ -41,6 +41,18 @@ * the old maximum object size from ext3. */ #define LUSTRE_EXT3_STRIPE_MAXBYTES 0x1fffffff000ULL +struct lov_stripe_md_entry { + struct lu_extent lsme_extent; + u32 lsme_id; + u32 lsme_magic; + u32 lsme_pattern; + u32 lsme_stripe_size; + u16 lsme_stripe_count; + u16 lsme_layout_gen; + char lsme_pool_name[LOV_MAXPOOLNAME + 1]; + struct lov_oinfo *lsme_oinfo[]; +}; + struct lov_stripe_md { atomic_t lsm_refc; spinlock_t lsm_lock; @@ -51,44 +63,28 @@ struct lov_stripe_md { loff_t lsm_maxbytes; struct ost_id lsm_oi; u32 lsm_magic; - u32 lsm_stripe_size; - u32 lsm_pattern; /* RAID0, RAID1, released, ... */ - u16 lsm_stripe_count; - u16 lsm_layout_gen; - char lsm_pool_name[LOV_MAXPOOLNAME + 1]; - struct lov_oinfo *lsm_oinfo[0]; + u32 lsm_layout_gen; + u32 lsm_entry_count; + bool lsm_is_released; + struct lov_stripe_md_entry *lsm_entries[]; }; -static inline bool lsm_is_released(struct lov_stripe_md *lsm) -{ - return !!(lsm->lsm_pattern & LOV_PATTERN_F_RELEASED); -} - static inline bool lsm_has_objects(struct lov_stripe_md *lsm) { - if (lsm == NULL) - return false; - - if (lsm_is_released(lsm)) - return false; - - return true; + return lsm != NULL && !lsm->lsm_is_released; } struct lsm_operations { - void (*lsm_free)(struct lov_stripe_md *); void (*lsm_stripe_by_index)(struct lov_stripe_md *, int *, loff_t *, loff_t *); void (*lsm_stripe_by_offset)(struct lov_stripe_md *, int *, loff_t *, loff_t *); - int (*lsm_lmm_verify)(struct lov_mds_md *lmm, int lmm_bytes, - u16 *stripe_count); - int (*lsm_unpackmd)(struct lov_obd *lov, struct lov_stripe_md *lsm, - struct lov_mds_md *lmm); + struct lov_stripe_md *(*lsm_unpackmd)(struct lov_obd *, void *, size_t); }; extern const struct lsm_operations lsm_v1_ops; extern const struct lsm_operations lsm_v3_ops; +extern const struct lsm_operations lsm_comp_md_v1_ops; static inline const struct lsm_operations *lsm_op_find(int magic) { switch (magic) { @@ -96,12 +92,16 @@ static inline const struct lsm_operations *lsm_op_find(int magic) return &lsm_v1_ops; case LOV_MAGIC_V3: return &lsm_v3_ops; + case LOV_MAGIC_COMP_V1: + return &lsm_comp_md_v1_ops; default: CERROR("unrecognized lsm_magic %08x\n", magic); return NULL; } } +void lsm_free(struct lov_stripe_md *lsm); + /* lov_do_div64(a, b) returns a % b, and a = a / b. * The 32-bit code is LOV-specific due to knowing about stripe limits in * order to reduce the divisor to a 32-bit number. If the divisor is @@ -212,8 +212,8 @@ int lov_del_target(struct obd_device *obd, __u32 index, /* lov_pack.c */ ssize_t lov_lsm_pack(const struct lov_stripe_md *lsm, void *buf, size_t buf_size); -struct lov_stripe_md *lov_unpackmd(struct lov_obd *lov, struct lov_mds_md *lmm, - size_t lmm_size); +struct lov_stripe_md *lov_unpackmd(struct lov_obd *lov, void *buf, + size_t buf_size); int lov_free_memmd(struct lov_stripe_md **lsmp); void lov_dump_lmm_v1(int level, struct lov_mds_md_v1 *lmm); @@ -222,7 +222,6 @@ void lov_dump_lmm_common(int level, void *lmmp); void lov_dump_lmm(int level, void *lmm); /* lov_ea.c */ -struct lov_stripe_md *lsm_alloc_plain(u16 stripe_count); void lsm_free_plain(struct lov_stripe_md *lsm); void dump_lsm(unsigned int level, const struct lov_stripe_md *lsm); diff --git a/lustre/lov/lov_io.c b/lustre/lov/lov_io.c index 68612c3..00f6ae0 100644 --- a/lustre/lov/lov_io.c +++ b/lustre/lov/lov_io.c @@ -252,7 +252,8 @@ static int lov_io_subio_init(const struct lu_env *env, struct lov_io *lio, * when writing a page. -jay */ OBD_ALLOC_LARGE(lio->lis_subs, - lsm->lsm_stripe_count * sizeof lio->lis_subs[0]); + lsm->lsm_entries[0]->lsme_stripe_count * + sizeof lio->lis_subs[0]); if (lio->lis_subs != NULL) { lio->lis_nr_subios = lio->lis_stripe_count; lio->lis_single_subio_index = -1; @@ -273,7 +274,7 @@ static int lov_io_slice_init(struct lov_io *lio, lio->lis_object = obj; LASSERT(obj->lo_lsm != NULL); - lio->lis_stripe_count = obj->lo_lsm->lsm_stripe_count; + lio->lis_stripe_count = obj->lo_lsm->lsm_entries[0]->lsme_stripe_count; switch (io->ci_type) { case CIT_READ: @@ -286,7 +287,7 @@ static int lov_io_slice_init(struct lov_io *lio, /* If there is LOV EA hole, then we may cannot locate * the current file-tail exactly. */ - if (unlikely(obj->lo_lsm->lsm_pattern & + if (unlikely(obj->lo_lsm->lsm_entries[0]->lsme_pattern & LOV_PATTERN_F_HOLE)) RETURN(-EIO); @@ -423,9 +424,9 @@ static int lov_io_rw_iter_init(const struct lu_env *env, struct lov_io *lio = cl2lov_io(env, ios); struct cl_io *io = ios->cis_io; struct lov_stripe_md *lsm = lio->lis_object->lo_lsm; - loff_t start = io->u.ci_rw.crw_pos; - loff_t next; - unsigned long ssize = lsm->lsm_stripe_size; + loff_t start = io->u.ci_rw.crw_pos; + loff_t next; + unsigned long ssize = lsm->lsm_entries[0]->lsme_stripe_size; LASSERT(io->ci_type == CIT_READ || io->ci_type == CIT_WRITE); ENTRY; @@ -614,12 +615,12 @@ static int lov_io_read_ahead(const struct lu_env *env, if (ra_end != CL_PAGE_EOF) ra_end = lov_stripe_pgoff(loo->lo_lsm, ra_end, stripe); - pps = loo->lo_lsm->lsm_stripe_size >> PAGE_SHIFT; + pps = loo->lo_lsm->lsm_entries[0]->lsme_stripe_size >> PAGE_SHIFT; CDEBUG(D_READA, DFID " max_index = %lu, pps = %u, " "stripe_size = %u, stripe no = %u, start index = %lu\n", PFID(lu_object_fid(lov2lu(loo))), ra_end, pps, - loo->lo_lsm->lsm_stripe_size, stripe, start); + loo->lo_lsm->lsm_entries[0]->lsme_stripe_size, stripe, start); /* never exceed the end of the stripe */ ra->cra_end = min_t(pgoff_t, ra_end, start + pps - start % pps - 1); diff --git a/lustre/lov/lov_merge.c b/lustre/lov/lov_merge.c index 2169042..f13ec67 100644 --- a/lustre/lov/lov_merge.c +++ b/lustre/lov/lov_merge.c @@ -61,8 +61,8 @@ int lov_merge_lvb_kms(struct lov_stripe_md *lsm, " a=%llu c=%llu b=%llu\n", POSTID(&lsm->lsm_oi), lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_atime, lvb->lvb_ctime, lvb->lvb_blocks); - for (i = 0; i < lsm->lsm_stripe_count; i++) { - struct lov_oinfo *loi = lsm->lsm_oinfo[i]; + for (i = 0; i < lsm->lsm_entries[0]->lsme_stripe_count; i++) { + struct lov_oinfo *loi = lsm->lsm_entries[0]->lsme_oinfo[i]; u64 lov_size; u64 tmpsize; diff --git a/lustre/lov/lov_object.c b/lustre/lov/lov_object.c index 7ee0ebc..9edd3e4 100644 --- a/lustre/lov/lov_object.c +++ b/lustre/lov/lov_object.c @@ -152,7 +152,7 @@ static int lov_init_sub(const struct lu_env *env, struct lov_object *lov, hdr = cl_object_header(lov2cl(lov)); subhdr = cl_object_header(stripe); - oinfo = lov->lo_lsm->lsm_oinfo[idx]; + oinfo = lov->lo_lsm->lsm_entries[0]->lsme_oinfo[idx]; CDEBUG(D_INODE, DFID"@%p[%d] -> "DFID"@%p: ostid: "DOSTID " idx: %d gen: %d\n", PFID(&subhdr->coh_lu.loh_fid), subhdr, idx, @@ -239,7 +239,7 @@ static int lov_init_raid0(const struct lu_env *env, struct lov_device *dev, LASSERT(lov->lo_lsm == NULL); lov->lo_lsm = lsm_addref(lsm); - r0->lo_nr = lsm->lsm_stripe_count; + r0->lo_nr = lsm->lsm_entries[0]->lsme_stripe_count; LASSERT(r0->lo_nr <= lov_targets_nr(dev)); lov->lo_layout_invalid = true; @@ -255,8 +255,9 @@ static int lov_init_raid0(const struct lu_env *env, struct lov_device *dev, * Create stripe cl_objects. */ for (i = 0; i < r0->lo_nr && result == 0; ++i) { - struct cl_device *subdev; - struct lov_oinfo *oinfo = lsm->lsm_oinfo[i]; + struct cl_device *subdev; + struct lov_oinfo *oinfo = + lsm->lsm_entries[0]->lsme_oinfo[i]; int ost_idx = oinfo->loi_ost_idx; if (lov_oinfo_is_dummy(oinfo)) @@ -312,7 +313,7 @@ static int lov_init_released(const struct lu_env *env, union lov_layout_state *state) { LASSERT(lsm != NULL); - LASSERT(lsm_is_released(lsm)); + LASSERT(lsm->lsm_is_released); LASSERT(lov->lo_lsm == NULL); lov->lo_lsm = lsm_addref(lsm); @@ -325,7 +326,7 @@ static struct cl_object *lov_find_subobj(const struct lu_env *env, int stripe_idx) { struct lov_device *dev = lu2lov_dev(lov2lu(lov)->lo_dev); - struct lov_oinfo *oinfo = lsm->lsm_oinfo[stripe_idx]; + struct lov_oinfo *oinfo = lsm->lsm_entries[0]->lsme_oinfo[stripe_idx]; struct lov_thread_info *lti = lov_env_info(env); struct lu_fid *ofid = <i->lti_fid; struct cl_device *subdev; @@ -484,7 +485,7 @@ static int lov_print_raid0(const struct lu_env *env, void *cookie, (*p)(env, cookie, "stripes: %d, %s, lsm{%p 0x%08X %d %u %u}:\n", r0->lo_nr, lov->lo_layout_invalid ? "invalid" : "valid", lsm, lsm->lsm_magic, atomic_read(&lsm->lsm_refc), - lsm->lsm_stripe_count, lsm->lsm_layout_gen); + lsm->lsm_entries[0]->lsme_stripe_count, lsm->lsm_layout_gen); for (i = 0; i < r0->lo_nr; ++i) { struct lu_object *sub; @@ -508,7 +509,7 @@ static int lov_print_released(const struct lu_env *env, void *cookie, "released: %s, lsm{%p 0x%08X %d %u %u}:\n", lov->lo_layout_invalid ? "invalid" : "valid", lsm, lsm->lsm_magic, atomic_read(&lsm->lsm_refc), - lsm->lsm_stripe_count, lsm->lsm_layout_gen); + lsm->lsm_entries[0]->lsme_stripe_count, lsm->lsm_layout_gen); return 0; } @@ -649,8 +650,13 @@ static enum lov_layout_type lov_type(struct lov_stripe_md *lsm) { if (lsm == NULL) return LLT_EMPTY; - if (lsm_is_released(lsm)) + + if (lsm->lsm_magic == LOV_MAGIC_COMP_V1) + return LLT_EMPTY; + + if (lsm->lsm_is_released) return LLT_RELEASED; + return LLT_RAID0; } @@ -890,7 +896,8 @@ static int lov_conf_set(const struct lu_env *env, struct cl_object *obj, if ((lsm == NULL && lov->lo_lsm == NULL) || ((lsm != NULL && lov->lo_lsm != NULL) && (lov->lo_lsm->lsm_layout_gen == lsm->lsm_layout_gen) && - (lov->lo_lsm->lsm_pattern == lsm->lsm_pattern))) { + (lov->lo_lsm->lsm_entries[0]->lsme_pattern == + lsm->lsm_entries[0]->lsme_pattern))) { /* same version of layout */ lov->lo_layout_invalid = false; GOTO(out, result = 0); @@ -1020,19 +1027,24 @@ static int fiemap_calc_last_stripe(struct lov_stripe_md *lsm, u64 obd_end; int i, j; - if (fm_end - fm_start > lsm->lsm_stripe_size * lsm->lsm_stripe_count) { - last_stripe = (start_stripe < 1 ? lsm->lsm_stripe_count - 1 : - start_stripe - 1); - *stripe_count = lsm->lsm_stripe_count; + if (fm_end - fm_start > lsm->lsm_entries[0]->lsme_stripe_size * + lsm->lsm_entries[0]->lsme_stripe_count) { + last_stripe = (start_stripe < 1 ? + lsm->lsm_entries[0]->lsme_stripe_count - 1 : + start_stripe - 1); + *stripe_count = lsm->lsm_entries[0]->lsme_stripe_count; } else { - for (j = 0, i = start_stripe; j < lsm->lsm_stripe_count; - i = (i + 1) % lsm->lsm_stripe_count, j++) { + for (j = 0, i = start_stripe; + j < lsm->lsm_entries[0]->lsme_stripe_count; + i = (i + 1) % lsm->lsm_entries[0]->lsme_stripe_count, + j++) { if ((lov_stripe_intersects(lsm, i, fm_start, fm_end, &obd_start, &obd_end)) == 0) break; } *stripe_count = j; - last_stripe = (start_stripe + j - 1) % lsm->lsm_stripe_count; + last_stripe = (start_stripe + j - 1) % + lsm->lsm_entries[0]->lsme_stripe_count; } return last_stripe; @@ -1102,8 +1114,8 @@ static u64 fiemap_calc_fm_end_offset(struct fiemap *fiemap, return 0; /* Find out stripe_no from ost_index saved in the fe_device */ - for (i = 0; i < lsm->lsm_stripe_count; i++) { - struct lov_oinfo *oinfo = lsm->lsm_oinfo[i]; + for (i = 0; i < lsm->lsm_entries[0]->lsme_stripe_count; i++) { + struct lov_oinfo *oinfo = lsm->lsm_entries[0]->lsme_oinfo[i]; if (lov_oinfo_is_dummy(oinfo)) continue; @@ -1128,7 +1140,8 @@ static u64 fiemap_calc_fm_end_offset(struct fiemap *fiemap, /* This is a special value to indicate that caller should * calculate offset in next stripe. */ fm_end_offset = 0; - *start_stripe = (stripe_no + 1) % lsm->lsm_stripe_count; + *start_stripe = (stripe_no + 1) % + lsm->lsm_entries[0]->lsme_stripe_count; } return fm_end_offset; @@ -1177,7 +1190,7 @@ int fiemap_for_stripe(const struct lu_env *env, struct cl_object *obj, &lun_start, &obd_object_end)) == 0) return 0; - if (lov_oinfo_is_dummy(lsm->lsm_oinfo[stripeno])) + if (lov_oinfo_is_dummy(lsm->lsm_entries[0]->lsme_oinfo[stripeno])) return -EIO; /* If this is a continuation FIEMAP call and we are on @@ -1225,7 +1238,8 @@ int fiemap_for_stripe(const struct lu_env *env, struct cl_object *obj, fs->fs_fm->fm_mapped_extents = 0; fs->fs_fm->fm_flags = fiemap->fm_flags; - ost_index = lsm->lsm_oinfo[stripeno]->loi_ost_idx; + ost_index = lsm->lsm_entries[0]->lsme_oinfo[stripeno]-> + loi_ost_idx; if (ost_index < 0 || ost_index >= lov->desc.ld_tgt_count) GOTO(obj_put, rc = -EINVAL); @@ -1351,11 +1365,11 @@ static int lov_object_fiemap(const struct lu_env *env, struct cl_object *obj, * If the stripe_count > 1 and the application does not understand * DEVICE_ORDER flag, it cannot interpret the extents correctly. */ - if (lsm->lsm_stripe_count > 1 && !(fiemap->fm_flags & - FIEMAP_FLAG_DEVICE_ORDER)) + if (lsm->lsm_entries[0]->lsme_stripe_count > 1 && + !(fiemap->fm_flags & FIEMAP_FLAG_DEVICE_ORDER)) GOTO(out_lsm, rc = -ENOTSUPP); - if (lsm_is_released(lsm)) { + if (lsm->lsm_is_released) { if (fiemap->fm_start < fmkey->lfik_oa.o_size) { /** * released file, return a minimal FIEMAP if @@ -1428,7 +1442,8 @@ static int lov_object_fiemap(const struct lu_env *env, struct cl_object *obj, /* Check each stripe */ for (cur_stripe = fs.fs_start_stripe; stripe_count > 0; --stripe_count, - cur_stripe = (cur_stripe + 1) % lsm->lsm_stripe_count) { + cur_stripe = (cur_stripe + 1) % + lsm->lsm_entries[0]->lsme_stripe_count) { rc = fiemap_for_stripe(env, obj, lsm, fiemap, buflen, fmkey, cur_stripe, &fs); if (rc < 0) @@ -1439,7 +1454,7 @@ static int lov_object_fiemap(const struct lu_env *env, struct cl_object *obj, /* Indicate that we are returning device offsets unless file just has * single stripe */ - if (lsm->lsm_stripe_count > 1) + if (lsm->lsm_entries[0]->lsme_stripe_count > 1) fiemap->fm_flags |= FIEMAP_FLAG_DEVICE_ORDER; if (fiemap->fm_extent_count == 0) @@ -1495,7 +1510,8 @@ static int lov_object_layout_get(const struct lu_env *env, RETURN(0); } - cl->cl_size = lov_mds_md_size(lsm->lsm_stripe_count, lsm->lsm_magic); + cl->cl_size = lov_mds_md_size(lsm->lsm_entries[0]->lsme_stripe_count, + lsm->lsm_magic); cl->cl_layout_gen = lsm->lsm_layout_gen; rc = lov_lsm_pack(lsm, buf->lb_buf, buf->lb_len); @@ -1601,8 +1617,10 @@ int lov_read_and_clear_async_rc(struct cl_object *clob) lsm = lov->lo_lsm; LASSERT(lsm != NULL); - for (i = 0; i < lsm->lsm_stripe_count; i++) { - struct lov_oinfo *loi = lsm->lsm_oinfo[i]; + for (i = 0; i < lsm->lsm_entries[0]->lsme_stripe_count; + i++) { + struct lov_oinfo *loi = + lsm->lsm_entries[0]->lsme_oinfo[i]; if (lov_oinfo_is_dummy(loi)) continue; diff --git a/lustre/lov/lov_offset.c b/lustre/lov/lov_offset.c index 3a7f610..ba93d76 100644 --- a/lustre/lov/lov_offset.c +++ b/lustre/lov/lov_offset.c @@ -41,7 +41,7 @@ /* compute object size given "stripeno" and the ost size */ u64 lov_stripe_size(struct lov_stripe_md *lsm, u64 ost_size, int stripeno) { - unsigned long ssize = lsm->lsm_stripe_size; + unsigned long ssize = lsm->lsm_entries[0]->lsme_stripe_size; unsigned long stripe_size; loff_t swidth; loff_t lov_size; @@ -128,7 +128,7 @@ pgoff_t lov_stripe_pgoff(struct lov_stripe_md *lsm, pgoff_t stripe_index, int lov_stripe_offset(struct lov_stripe_md *lsm, loff_t lov_off, int stripeno, loff_t *obdoff) { - unsigned long ssize = lsm->lsm_stripe_size; + unsigned long ssize = lsm->lsm_entries[0]->lsme_stripe_size; loff_t stripe_off; loff_t this_stripe; loff_t swidth; @@ -186,7 +186,7 @@ int lov_stripe_offset(struct lov_stripe_md *lsm, loff_t lov_off, int stripeno, loff_t lov_size_to_stripe(struct lov_stripe_md *lsm, u64 file_size, int stripeno) { - unsigned long ssize = lsm->lsm_stripe_size; + unsigned long ssize = lsm->lsm_entries[0]->lsme_stripe_size; loff_t stripe_off; loff_t this_stripe; loff_t swidth; @@ -260,7 +260,7 @@ int lov_stripe_intersects(struct lov_stripe_md *lsm, int stripeno, /* compute which stripe number "lov_off" will be written into */ int lov_stripe_number(struct lov_stripe_md *lsm, loff_t lov_off) { - unsigned long ssize = lsm->lsm_stripe_size; + unsigned long ssize = lsm->lsm_entries[0]->lsme_stripe_size; loff_t stripe_off; loff_t swidth; u32 magic = lsm->lsm_magic; diff --git a/lustre/lov/lov_pack.c b/lustre/lov/lov_pack.c index cc9e0e9..cc8c205 100644 --- a/lustre/lov/lov_pack.c +++ b/lustre/lov/lov_pack.c @@ -138,7 +138,8 @@ ssize_t lov_lsm_pack(const struct lov_stripe_md *lsm, void *buf, unsigned int i; ENTRY; - lmm_size = lov_mds_md_size(lsm->lsm_stripe_count, lsm->lsm_magic); + lmm_size = lov_mds_md_size(lsm->lsm_entries[0]->lsme_stripe_count, + lsm->lsm_magic); if (buf_size == 0) RETURN(lmm_size); @@ -150,23 +151,26 @@ ssize_t lov_lsm_pack(const struct lov_stripe_md *lsm, void *buf, */ lmmv1->lmm_magic = cpu_to_le32(lsm->lsm_magic); lmm_oi_cpu_to_le(&lmmv1->lmm_oi, &lsm->lsm_oi); - lmmv1->lmm_stripe_size = cpu_to_le32(lsm->lsm_stripe_size); - lmmv1->lmm_stripe_count = cpu_to_le16(lsm->lsm_stripe_count); - lmmv1->lmm_pattern = cpu_to_le32(lsm->lsm_pattern); + lmmv1->lmm_stripe_size = cpu_to_le32( + lsm->lsm_entries[0]->lsme_stripe_size); + lmmv1->lmm_stripe_count = cpu_to_le16( + lsm->lsm_entries[0]->lsme_stripe_count); + lmmv1->lmm_pattern = cpu_to_le32(lsm->lsm_entries[0]->lsme_pattern); lmmv1->lmm_layout_gen = cpu_to_le16(lsm->lsm_layout_gen); if (lsm->lsm_magic == LOV_MAGIC_V3) { - CLASSERT(sizeof(lsm->lsm_pool_name) == + CLASSERT(sizeof(lsm->lsm_entries[0]->lsme_pool_name) == sizeof(lmmv3->lmm_pool_name)); - strlcpy(lmmv3->lmm_pool_name, lsm->lsm_pool_name, + strlcpy(lmmv3->lmm_pool_name, + lsm->lsm_entries[0]->lsme_pool_name, sizeof(lmmv3->lmm_pool_name)); lmm_objects = lmmv3->lmm_objects; } else { lmm_objects = lmmv1->lmm_objects; } - for (i = 0; i < lsm->lsm_stripe_count; i++) { - struct lov_oinfo *loi = lsm->lsm_oinfo[i]; + for (i = 0; i < lsm->lsm_entries[0]->lsme_stripe_count; i++) { + struct lov_oinfo *loi = lsm->lsm_entries[0]->lsme_oinfo[i]; ostid_cpu_to_le(&loi->loi_oi, &lmm_objects[i].l_ost_oi); lmm_objects[i].l_ost_gen = cpu_to_le32(loi->loi_ost_gen); @@ -201,67 +205,6 @@ __u16 lov_get_stripecnt(struct lov_obd *lov, __u32 magic, __u16 stripe_count) return stripe_count; } -static int lov_verify_lmm(void *lmm, int lmm_bytes, __u16 *stripe_count) -{ - int rc; - - if (lsm_op_find(le32_to_cpu(*(__u32 *)lmm)) == NULL) { - char *buffer; - int sz; - - CERROR("bad disk LOV MAGIC: 0x%08X; dumping LMM (size=%d):\n", - le32_to_cpu(*(__u32 *)lmm), lmm_bytes); - sz = lmm_bytes * 2 + 1; - OBD_ALLOC_LARGE(buffer, sz); - if (buffer != NULL) { - int i; - - for (i = 0; i < lmm_bytes; i++) - sprintf(buffer+2*i, "%.2X", ((char *)lmm)[i]); - buffer[sz - 1] = '\0'; - CERROR("%s\n", buffer); - OBD_FREE_LARGE(buffer, sz); - } - return -EINVAL; - } - rc = lsm_op_find(le32_to_cpu(*(__u32 *)lmm))->lsm_lmm_verify(lmm, - lmm_bytes, stripe_count); - return rc; -} - -struct lov_stripe_md *lov_lsm_alloc(u16 stripe_count, u32 pattern, u32 magic) -{ - struct lov_stripe_md *lsm; - unsigned int i; - ENTRY; - - CDEBUG(D_INFO, "alloc lsm, stripe_count %u\n", - (unsigned int)stripe_count); - - lsm = lsm_alloc_plain(stripe_count); - if (lsm == NULL) { - CERROR("cannot allocate LSM stripe_count %u\n", - (unsigned int)stripe_count); - RETURN(ERR_PTR(-ENOMEM)); - } - - atomic_set(&lsm->lsm_refc, 1); - spin_lock_init(&lsm->lsm_lock); - lsm->lsm_magic = magic; - lsm->lsm_stripe_count = stripe_count; - lsm->lsm_maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES * stripe_count; - lsm->lsm_pattern = pattern; - lsm->lsm_pool_name[0] = '\0'; - lsm->lsm_layout_gen = 0; - if (stripe_count > 0) - lsm->lsm_oinfo[0]->loi_ost_idx = ~0; - - for (i = 0; i < stripe_count; i++) - loi_init(lsm->lsm_oinfo[i]); - - RETURN(lsm); -} - int lov_free_memmd(struct lov_stripe_md **lsmp) { struct lov_stripe_md *lsm = *lsmp; @@ -270,43 +213,32 @@ int lov_free_memmd(struct lov_stripe_md **lsmp) *lsmp = NULL; refc = atomic_dec_return(&lsm->lsm_refc); LASSERT(refc >= 0); - if (refc == 0) { - LASSERT(lsm_op_find(lsm->lsm_magic) != NULL); - lsm_op_find(lsm->lsm_magic)->lsm_free(lsm); - } + if (refc == 0) + lsm_free(lsm); + return refc; } /* Unpack LOV object metadata from disk storage. It is packed in LE byte * order and is opaque to the networking layer. */ -struct lov_stripe_md *lov_unpackmd(struct lov_obd *lov, struct lov_mds_md *lmm, - size_t lmm_size) +struct lov_stripe_md *lov_unpackmd(struct lov_obd *lov, void *buf, + size_t buf_size) { + const struct lsm_operations *op; struct lov_stripe_md *lsm; - u16 stripe_count; u32 magic; - u32 pattern; - int rc; ENTRY; - rc = lov_verify_lmm(lmm, lmm_size, &stripe_count); - if (rc != 0) - RETURN(ERR_PTR(rc)); + if (buf_size < sizeof(magic)) + RETURN(ERR_PTR(-EINVAL)); - magic = le32_to_cpu(lmm->lmm_magic); - pattern = le32_to_cpu(lmm->lmm_pattern); + magic = le32_to_cpu(*(u32 *)buf); + op = lsm_op_find(magic); + if (op == NULL) + RETURN(ERR_PTR(-EINVAL)); - lsm = lov_lsm_alloc(stripe_count, pattern, magic); - if (IS_ERR(lsm)) - RETURN(lsm); - - LASSERT(lsm_op_find(magic) != NULL); - rc = lsm_op_find(magic)->lsm_unpackmd(lov, lsm, lmm); - if (rc != 0) { - lov_free_memmd(&lsm); - RETURN(ERR_PTR(rc)); - } + lsm = lsm_op_find(magic)->lsm_unpackmd(lov, buf, buf_size); RETURN(lsm); } @@ -336,8 +268,8 @@ int lov_getstripe(struct lov_object *obj, struct lov_stripe_md *lsm, GOTO(out, rc = -EIO); } - if (!lsm_is_released(lsm)) - stripe_count = lsm->lsm_stripe_count; + if (!lsm->lsm_is_released) + stripe_count = lsm->lsm_entries[0]->lsme_stripe_count; else stripe_count = 0; -- 1.8.3.1