Whamcloud - gitweb
LU-8998 lov: add composite layout unpacking
authorBobi Jam <bobijam.xu@intel.com>
Wed, 5 Apr 2017 23:57:54 +0000 (07:57 +0800)
committerJinshan Xiong <jinshan.xiong@intel.com>
Thu, 6 Apr 2017 04:31:52 +0000 (21:31 -0700)
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 <john.hammond@intel.com>
Signed-off-by: Bobi Jam <bobijam.xu@intel.com>
Signed-off-by: Niu Yawei <yawei.niu@intel.com>
Reviewed-by: Jinshan Xiong <jinshan.xiong@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
lustre/include/obd.h
lustre/lov/lov_ea.c
lustre/lov/lov_internal.h
lustre/lov/lov_io.c
lustre/lov/lov_merge.c
lustre/lov/lov_object.c
lustre/lov/lov_offset.c
lustre/lov/lov_pack.c

index b399149..508aa97 100644 (file)
@@ -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;
 
index 0007f88..896b403 100644 (file)
 #define DEBUG_SUBSYSTEM S_LOV
 
 #include <linux/math64.h>
+#include <linux/sort.h>
 #include <libcfs/libcfs.h>
 
 #include <obd_class.h>
 #include <lustre/lustre_idl.h>
+#include <lustre/lustre_user.h>
 
 #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);
 }
index e3ecc04..376c7eb 100644 (file)
  * 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);
 
index 68612c3..00f6ae0 100644 (file)
@@ -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);
index 2169042..f13ec67 100644 (file)
@@ -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;
 
index 7ee0ebc..9edd3e4 100644 (file)
@@ -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 = &lti->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;
index 3a7f610..ba93d76 100644 (file)
@@ -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;
index cc9e0e9..cc8c205 100644 (file)
@@ -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;