Whamcloud - gitweb
LU-13602 flr: skip unknown FLR component types 13/39513/8
authorQian Yingjin <qian@ddn.com>
Mon, 27 Jul 2020 03:56:22 +0000 (11:56 +0800)
committerOleg Drokin <green@whamcloud.com>
Fri, 22 Jan 2021 20:14:28 +0000 (20:14 +0000)
Currently, in lov_init_composite() it will quit with error when
reading an unknown LOV pattern.
Since FLR will be used for upcoming new features, like PCC-RO,
an old client should be able to read the old format of the
component types, ignore and skip the new types of FLR component.

Signed-off-by: Qian Yingjin <qian@ddn.com>
Change-Id: Ica3fe98203d44b52cf25b085c34c83b1a4702464
Reviewed-on: https://review.whamcloud.com/39513
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/lov/lov_cl_internal.h
lustre/lov/lov_ea.c
lustre/lov/lov_internal.h
lustre/lov/lov_io.c
lustre/lov/lov_object.c

index e3553cf..a13306e 100644 (file)
@@ -707,6 +707,7 @@ struct fsxattr {
 #define LOV_PATTERN_RAID1              0x002
 #define LOV_PATTERN_MDT                        0x100
 #define LOV_PATTERN_OVERSTRIPING       0x200
 #define LOV_PATTERN_RAID1              0x002
 #define LOV_PATTERN_MDT                        0x100
 #define LOV_PATTERN_OVERSTRIPING       0x200
+#define LOV_PATTERN_FOREIGN            0x400
 
 #define LOV_PATTERN_F_MASK     0xffff0000
 #define LOV_PATTERN_F_HOLE     0x40000000 /* there is hole in LOV EA */
 
 #define LOV_PATTERN_F_MASK     0xffff0000
 #define LOV_PATTERN_F_HOLE     0x40000000 /* there is hole in LOV EA */
index 3a112da..45914f1 100644 (file)
@@ -151,7 +151,8 @@ static inline char *llt2str(enum lov_layout_type llt)
 static inline __u32 lov_entry_type(struct lov_stripe_md_entry *lsme)
 {
        if ((lov_pattern(lsme->lsme_pattern) & LOV_PATTERN_RAID0) ||
 static inline __u32 lov_entry_type(struct lov_stripe_md_entry *lsme)
 {
        if ((lov_pattern(lsme->lsme_pattern) & LOV_PATTERN_RAID0) ||
-           (lov_pattern(lsme->lsme_pattern) == LOV_PATTERN_MDT))
+           (lov_pattern(lsme->lsme_pattern) == LOV_PATTERN_MDT) ||
+           (lov_pattern(lsme->lsme_pattern) == LOV_PATTERN_FOREIGN))
                return lov_pattern(lsme->lsme_pattern &
                                   ~LOV_PATTERN_OVERSTRIPING);
        return 0;
                return lov_pattern(lsme->lsme_pattern &
                                   ~LOV_PATTERN_OVERSTRIPING);
        return 0;
@@ -239,8 +240,10 @@ struct lov_mirror_entry {
        unsigned short  lre_mirror_id;
        unsigned short  lre_preferred:1,
                        lre_stale:1,    /* set if any components is stale */
        unsigned short  lre_mirror_id;
        unsigned short  lre_preferred:1,
                        lre_stale:1,    /* set if any components is stale */
-                       lre_valid:1;    /* set if at least one of components
+                       lre_valid:1,    /* set if at least one of components
                                         * in this mirror is valid */
                                         * in this mirror is valid */
+                       lre_foreign:1;  /* set if it is a foreign component */
+
        unsigned short  lre_start;      /* index to lo_entries, start index of
                                         * this mirror */
        unsigned short  lre_end;        /* end index of this mirror */
        unsigned short  lre_start;      /* index to lo_entries, start index of
                                         * this mirror */
        unsigned short  lre_end;        /* end index of this mirror */
index f07419e..19dffc7 100644 (file)
@@ -121,10 +121,23 @@ out:
 
 static void lsme_free(struct lov_stripe_md_entry *lsme)
 {
 
 static void lsme_free(struct lov_stripe_md_entry *lsme)
 {
-       unsigned int stripe_count = lsme->lsme_stripe_count;
+       unsigned int stripe_count;
        unsigned int i;
        size_t lsme_size;
 
        unsigned int i;
        size_t lsme_size;
 
+       if (lsme->lsme_magic == LOV_MAGIC_FOREIGN) {
+               /*
+                * TODO: In addition to HSM foreign layout, It needs to add
+                * support for other kinds of foreign layout types such as
+                * DAOS, S3. When add these supports, it will use non-inline
+                * @lov_hsm_base to store layout information, and need to
+                * free extra allocated buffer.
+                */
+               OBD_FREE_LARGE(lsme, sizeof(*lsme));
+               return;
+       }
+
+       stripe_count = lsme->lsme_stripe_count;
        if (!lsme_inited(lsme) ||
            lsme->lsme_pattern & LOV_PATTERN_F_RELEASED)
                stripe_count = 0;
        if (!lsme_inited(lsme) ||
            lsme->lsme_pattern & LOV_PATTERN_F_RELEASED)
                stripe_count = 0;
@@ -184,8 +197,7 @@ lsme_unpack(struct lov_obd *lov, struct lov_mds_md *lmm, size_t buf_size,
        else
                stripe_count = le16_to_cpu(lmm->lmm_stripe_count);
 
        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))) {
+       if (buf_size < lov_mds_md_size(stripe_count, magic)) {
                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 ?
                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 ?
@@ -406,35 +418,60 @@ static int lsm_verify_comp_md_v1(struct lov_comp_md_v1 *lcm,
 }
 
 static struct lov_stripe_md_entry *
 }
 
 static struct lov_stripe_md_entry *
+lsme_unpack_foreign(struct lov_obd *lov, void *buf, size_t buf_size,
+                   bool inited, loff_t *maxbytes)
+{
+       struct lov_stripe_md_entry *lsme;
+       struct lov_foreign_md *lfm = buf;
+       __u32 magic;
+
+       ENTRY;
+
+       magic = le32_to_cpu(lfm->lfm_magic);
+       if (magic != LOV_MAGIC_FOREIGN)
+               RETURN(ERR_PTR(-EINVAL));
+
+       OBD_ALLOC_LARGE(lsme, sizeof(*lsme));
+       if (!lsme)
+               RETURN(ERR_PTR(-ENOMEM));
+
+       lsme->lsme_magic = magic;
+       lsme->lsme_pattern = LOV_PATTERN_FOREIGN;
+       lsme->lsme_flags = 0;
+
+       if (maxbytes)
+               *maxbytes = MAX_LFS_FILESIZE;
+
+       RETURN(lsme);
+}
+
+static struct lov_stripe_md_entry *
 lsme_unpack_comp(struct lov_obd *lov, struct lov_mds_md *lmm,
                 size_t lmm_buf_size, bool inited, loff_t *maxbytes)
 {
        unsigned int magic;
 lsme_unpack_comp(struct lov_obd *lov, struct lov_mds_md *lmm,
                 size_t lmm_buf_size, bool inited, loff_t *maxbytes)
 {
        unsigned int magic;
-       unsigned int stripe_count;
-
-       stripe_count = le16_to_cpu(lmm->lmm_stripe_count);
-       if (stripe_count == 0 &&
-           lov_pattern(le32_to_cpu(lmm->lmm_pattern)) != LOV_PATTERN_MDT)
-               RETURN(ERR_PTR(-EINVAL));
-       /* un-instantiated lmm contains no ost id info, i.e. lov_ost_data_v1 */
-       if (!inited)
-               stripe_count = 0;
 
        magic = le32_to_cpu(lmm->lmm_magic);
 
        magic = le32_to_cpu(lmm->lmm_magic);
-       if (magic != LOV_MAGIC_V1 && magic != LOV_MAGIC_V3)
+       if (magic != LOV_MAGIC_V1 && magic != LOV_MAGIC_V3 &&
+           magic != LOV_MAGIC_FOREIGN)
                RETURN(ERR_PTR(-EINVAL));
 
                RETURN(ERR_PTR(-EINVAL));
 
-       if (lmm_buf_size < lov_mds_md_size(stripe_count, magic))
+       if (magic != LOV_MAGIC_FOREIGN &&
+           le16_to_cpu(lmm->lmm_stripe_count) == 0 &&
+           lov_pattern(le32_to_cpu(lmm->lmm_pattern)) != LOV_PATTERN_MDT)
                RETURN(ERR_PTR(-EINVAL));
 
        if (magic == LOV_MAGIC_V1) {
                return lsme_unpack(lov, lmm, lmm_buf_size, NULL,
                                   inited, lmm->lmm_objects, maxbytes);
                RETURN(ERR_PTR(-EINVAL));
 
        if (magic == LOV_MAGIC_V1) {
                return lsme_unpack(lov, lmm, lmm_buf_size, NULL,
                                   inited, lmm->lmm_objects, maxbytes);
-       } else {
+       } else if (magic == LOV_MAGIC_V3) {
                struct lov_mds_md_v3 *lmm3 = (struct lov_mds_md_v3 *)lmm;
 
                return lsme_unpack(lov, lmm, lmm_buf_size, lmm3->lmm_pool_name,
                                   inited, lmm3->lmm_objects, maxbytes);
                struct lov_mds_md_v3 *lmm3 = (struct lov_mds_md_v3 *)lmm;
 
                return lsme_unpack(lov, lmm, lmm_buf_size, lmm3->lmm_pool_name,
                                   inited, lmm3->lmm_objects, maxbytes);
+       } else { /* LOV_MAGIC_FOREIGN */
+               return lsme_unpack_foreign(lov, lmm, lmm_buf_size,
+                                          inited, maxbytes);
        }
 }
 
        }
 }
 
index 8016610..9512b3e 100644 (file)
@@ -95,6 +95,17 @@ struct lov_stripe_md {
 
 #define lsm_foreign(lsm) (lsm->lsm_entries[0])
 
 
 #define lsm_foreign(lsm) (lsm->lsm_entries[0])
 
+static inline bool lsme_is_foreign(const struct lov_stripe_md_entry *lsme)
+{
+       return lsme->lsme_magic == LOV_MAGIC_FOREIGN;
+}
+
+static inline bool lsm_entry_is_foreign(const struct lov_stripe_md *lsm,
+                                       int index)
+{
+       return lsme_is_foreign(lsm->lsm_entries[index]);
+}
+
 static inline bool lsme_inited(const struct lov_stripe_md_entry *lsme)
 {
        return lsme->lsme_flags & LCME_FL_INIT;
 static inline bool lsme_inited(const struct lov_stripe_md_entry *lsme)
 {
        return lsme->lsme_flags & LCME_FL_INIT;
@@ -125,7 +136,8 @@ static inline size_t lov_comp_md_size(const struct lov_stripe_md *lsm)
 
        LASSERT(lsm->lsm_magic == LOV_MAGIC_COMP_V1);
 
 
        LASSERT(lsm->lsm_magic == LOV_MAGIC_COMP_V1);
 
-       size = sizeof(struct lov_comp_md_v1);
+       size = sizeof(struct lov_comp_md_v1) +
+              sizeof(struct lov_comp_md_entry_v1) * lsm->lsm_entry_count;
        for (entry = 0; entry < lsm->lsm_entry_count; entry++) {
                u16 stripe_count;
 
        for (entry = 0; entry < lsm->lsm_entry_count; entry++) {
                u16 stripe_count;
 
@@ -136,7 +148,6 @@ static inline size_t lov_comp_md_size(const struct lov_stripe_md *lsm)
                else
                        stripe_count = 0;
 
                else
                        stripe_count = 0;
 
-               size += sizeof(*lsme);
                size += lov_mds_md_size(stripe_count,
                                        lsme->lsme_magic);
        }
                size += lov_mds_md_size(stripe_count,
                                        lsme->lsme_magic);
        }
index b9592d1..7c52b99 100644 (file)
@@ -408,6 +408,9 @@ static int lov_io_mirror_init(struct lov_io *lio, struct lov_object *obj,
                if (!lre->lre_valid)
                        continue;
 
                if (!lre->lre_valid)
                        continue;
 
+               if (lre->lre_foreign)
+                       continue;
+
                lov_foreach_mirror_layout_entry(obj, lle, lre) {
                        if (!lle->lle_valid)
                                continue;
                lov_foreach_mirror_layout_entry(obj, lle, lre) {
                        if (!lle->lle_valid)
                                continue;
@@ -815,6 +818,9 @@ static int lov_io_iter_init(const struct lu_env *env,
                        continue;
                }
 
                        continue;
                }
 
+               if (lsm_entry_is_foreign(lsm, index))
+                       continue;
+
                if (!le->lle_valid && !ios->cis_io->ci_designated_mirror) {
                        CERROR("I/O to invalid component: %d, mirror: %d\n",
                               index, lio->lis_mirror_index);
                if (!le->lle_valid && !ios->cis_io->ci_designated_mirror) {
                        CERROR("I/O to invalid component: %d, mirror: %d\n",
                               index, lio->lis_mirror_index);
@@ -949,6 +955,9 @@ static int lov_io_rw_iter_init(const struct lu_env *env,
 
        lse = lov_lse(lio->lis_object, index);
 
 
        lse = lov_lse(lio->lis_object, index);
 
+       if (lsme_is_foreign(lse))
+               RETURN(-EINVAL);
+
        next = MAX_LFS_FILESIZE;
        if (lse->lsme_stripe_count > 1) {
                unsigned long ssize = lse->lsme_stripe_size;
        next = MAX_LFS_FILESIZE;
        if (lse->lsme_stripe_count > 1) {
                unsigned long ssize = lse->lsme_stripe_size;
@@ -1135,7 +1144,8 @@ static int lov_io_read_ahead(const struct lu_env *env,
 
        offset = cl_offset(obj, start);
        index = lov_io_layout_at(lio, offset);
 
        offset = cl_offset(obj, start);
        index = lov_io_layout_at(lio, offset);
-       if (index < 0 || !lsm_entry_inited(loo->lo_lsm, index))
+       if (index < 0 || !lsm_entry_inited(loo->lo_lsm, index) ||
+           lsm_entry_is_foreign(loo->lo_lsm, index))
                RETURN(-ENODATA);
 
        /* avoid readahead to expand to stale components */
                RETURN(-ENODATA);
 
        /* avoid readahead to expand to stale components */
@@ -1808,6 +1818,8 @@ int lov_io_layout_at(struct lov_io *lio, __u64 offset)
        for (i = start_index; i <= end_index; i++) {
                struct lov_layout_entry *lle = lov_entry(lov, i);
 
        for (i = start_index; i <= end_index; i++) {
                struct lov_layout_entry *lle = lov_entry(lov, i);
 
+               LASSERT(!lsme_is_foreign(lle->lle_lsme));
+
                if ((offset >= lle->lle_extent->e_start &&
                     offset < lle->lle_extent->e_end) ||
                    (offset == OBD_OBJECT_EOF &&
                if ((offset >= lle->lle_extent->e_start &&
                     offset < lle->lle_extent->e_end) ||
                    (offset == OBD_OBJECT_EOF &&
index 1491851..cff9c1d 100644 (file)
@@ -683,6 +683,9 @@ static int lov_init_composite(const struct lu_env *env, struct lov_device *dev,
                        }
                        lle->lle_comp_ops = &dom_ops;
                        break;
                        }
                        lle->lle_comp_ops = &dom_ops;
                        break;
+               case LOV_PATTERN_FOREIGN:
+                       lle->lle_comp_ops = NULL;
+                       break;
                default:
                        CERROR("%s: unknown composite layout entry type %i\n",
                               lov2obd(dev->ld_lov)->obd_name,
                default:
                        CERROR("%s: unknown composite layout entry type %i\n",
                               lov2obd(dev->ld_lov)->obd_name,
@@ -702,6 +705,8 @@ static int lov_init_composite(const struct lu_env *env, struct lov_device *dev,
                        if (mirror_id == lre->lre_mirror_id) {
                                lre->lre_valid |= lle->lle_valid;
                                lre->lre_stale |= !lle->lle_valid;
                        if (mirror_id == lre->lre_mirror_id) {
                                lre->lre_valid |= lle->lle_valid;
                                lre->lre_stale |= !lle->lle_valid;
+                               lre->lre_foreign |=
+                                       lsme_is_foreign(lle->lle_lsme);
                                lre->lre_end = i;
                                continue;
                        }
                                lre->lre_end = i;
                                continue;
                        }
@@ -723,6 +728,7 @@ static int lov_init_composite(const struct lu_env *env, struct lov_device *dev,
                                        LCME_FL_PREF_RD);
                lre->lre_valid = lle->lle_valid;
                lre->lre_stale = !lle->lle_valid;
                                        LCME_FL_PREF_RD);
                lre->lre_valid = lle->lle_valid;
                lre->lre_stale = !lle->lle_valid;
+               lre->lre_foreign = lsme_is_foreign(lle->lle_lsme);
        }
 
        /* sanity check for FLR */
        }
 
        /* sanity check for FLR */
@@ -746,6 +752,9 @@ static int lov_init_composite(const struct lu_env *env, struct lov_device *dev,
                if (!lsme_inited(lle->lle_lsme))
                        continue;
 
                if (!lsme_inited(lle->lle_lsme))
                        continue;
 
+               if (lsme_is_foreign(lle->lle_lsme))
+                       continue;
+
                result = lle->lle_comp_ops->lco_init(env, dev, lov, index,
                                                     conf, lle);
                if (result < 0)
                result = lle->lle_comp_ops->lco_init(env, dev, lov, index,
                                                     conf, lle);
                if (result < 0)
@@ -769,6 +778,9 @@ static int lov_init_composite(const struct lu_env *env, struct lov_device *dev,
                if (lre->lre_stale)
                        continue;
 
                if (lre->lre_stale)
                        continue;
 
+               if (lre->lre_foreign)
+                       continue;
+
                mirror_count++; /* valid mirror */
 
                if (lre->lre_preferred || comp->lo_preferred_mirror < 0)
                mirror_count++; /* valid mirror */
 
                if (lre->lre_preferred || comp->lo_preferred_mirror < 0)
@@ -848,8 +860,12 @@ static int lov_delete_composite(const struct lu_env *env,
 
        lov_layout_wait(env, lov);
        if (comp->lo_entries)
 
        lov_layout_wait(env, lov);
        if (comp->lo_entries)
-               lov_foreach_layout_entry(lov, entry)
+               lov_foreach_layout_entry(lov, entry) {
+                       if (lsme_is_foreign(entry->lle_lsme))
+                               continue;
+
                        lov_delete_raid0(env, lov, entry);
                        lov_delete_raid0(env, lov, entry);
+       }
 
        RETURN(0);
 }
 
        RETURN(0);
 }
@@ -930,7 +946,9 @@ static int lov_print_composite(const struct lu_env *env, void *cookie,
                     lse->lsme_id, lse->lsme_pattern, lse->lsme_layout_gen,
                     lse->lsme_flags, lse->lsme_stripe_count,
                     lse->lsme_stripe_size);
                     lse->lsme_id, lse->lsme_pattern, lse->lsme_layout_gen,
                     lse->lsme_flags, lse->lsme_stripe_count,
                     lse->lsme_stripe_size);
-               lov_print_raid0(env, cookie, p, lle);
+
+               if (!lsme_is_foreign(lse))
+                       lov_print_raid0(env, cookie, p, lle);
        }
 
        return 0;
        }
 
        return 0;