From 61a002cd8631ecd35a0326dba68f0eb6e48dc44f Mon Sep 17 00:00:00 2001 From: Qian Yingjin Date: Mon, 27 Jul 2020 11:56:22 +0800 Subject: [PATCH] LU-13602 flr: skip unknown FLR component types 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 Change-Id: Ica3fe98203d44b52cf25b085c34c83b1a4702464 Reviewed-on: https://review.whamcloud.com/39513 Reviewed-by: Andreas Dilger Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/include/uapi/linux/lustre/lustre_user.h | 1 + lustre/lov/lov_cl_internal.h | 7 ++- lustre/lov/lov_ea.c | 67 ++++++++++++++++++++------ lustre/lov/lov_internal.h | 15 +++++- lustre/lov/lov_io.c | 14 +++++- lustre/lov/lov_object.c | 22 ++++++++- 6 files changed, 104 insertions(+), 22 deletions(-) diff --git a/lustre/include/uapi/linux/lustre/lustre_user.h b/lustre/include/uapi/linux/lustre/lustre_user.h index e3553cf..a13306e 100644 --- a/lustre/include/uapi/linux/lustre/lustre_user.h +++ b/lustre/include/uapi/linux/lustre/lustre_user.h @@ -707,6 +707,7 @@ struct fsxattr { #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 */ diff --git a/lustre/lov/lov_cl_internal.h b/lustre/lov/lov_cl_internal.h index 3a112da..45914f1 100644 --- a/lustre/lov/lov_cl_internal.h +++ b/lustre/lov/lov_cl_internal.h @@ -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) || - (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; @@ -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 */ - 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 */ + 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 */ diff --git a/lustre/lov/lov_ea.c b/lustre/lov/lov_ea.c index f07419e..19dffc7 100644 --- a/lustre/lov/lov_ea.c +++ b/lustre/lov/lov_ea.c @@ -121,10 +121,23 @@ out: 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; + 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; @@ -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); - 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 ? @@ -406,35 +418,60 @@ static int lsm_verify_comp_md_v1(struct lov_comp_md_v1 *lcm, } 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; - 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); - 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)); - 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); - } 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); + } else { /* LOV_MAGIC_FOREIGN */ + return lsme_unpack_foreign(lov, lmm, lmm_buf_size, + inited, maxbytes); } } diff --git a/lustre/lov/lov_internal.h b/lustre/lov/lov_internal.h index 8016610..9512b3e 100644 --- a/lustre/lov/lov_internal.h +++ b/lustre/lov/lov_internal.h @@ -95,6 +95,17 @@ struct lov_stripe_md { #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; @@ -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); - 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; @@ -136,7 +148,6 @@ static inline size_t lov_comp_md_size(const struct lov_stripe_md *lsm) else stripe_count = 0; - size += sizeof(*lsme); size += lov_mds_md_size(stripe_count, lsme->lsme_magic); } diff --git a/lustre/lov/lov_io.c b/lustre/lov/lov_io.c index b9592d1..7c52b99 100644 --- a/lustre/lov/lov_io.c +++ b/lustre/lov/lov_io.c @@ -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_foreign) + 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; } + 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); @@ -949,6 +955,9 @@ static int lov_io_rw_iter_init(const struct lu_env *env, 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; @@ -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); - 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 */ @@ -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); + LASSERT(!lsme_is_foreign(lle->lle_lsme)); + if ((offset >= lle->lle_extent->e_start && offset < lle->lle_extent->e_end) || (offset == OBD_OBJECT_EOF && diff --git a/lustre/lov/lov_object.c b/lustre/lov/lov_object.c index 1491851..cff9c1d 100644 --- a/lustre/lov/lov_object.c +++ b/lustre/lov/lov_object.c @@ -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; + 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, @@ -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; + lre->lre_foreign |= + lsme_is_foreign(lle->lle_lsme); 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; + lre->lre_foreign = lsme_is_foreign(lle->lle_lsme); } /* 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_is_foreign(lle->lle_lsme)) + continue; + 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_foreign) + continue; + 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_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); + } 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); - lov_print_raid0(env, cookie, p, lle); + + if (!lsme_is_foreign(lse)) + lov_print_raid0(env, cookie, p, lle); } return 0; -- 1.8.3.1