From 7a9c9ccabe93f2d96c80e90f8cbb786faca74835 Mon Sep 17 00:00:00 2001 From: Bobi Jam Date: Thu, 2 Dec 2021 18:34:42 +0800 Subject: [PATCH] LU-15278 lod: distinguish DIR/REGULAR lod_object members In lod_striping_free_nolock(), we need to distinguish lod_object type, since DIR/REGULAR lod_object structure share the same memory region, it could accidently free some unintended memory if it treat DIR lod_object as REGULAR one, or vice versa. Fixes: 6a20bdcc608b ("LU-11376 lov: new foreign LOV format") Fixes: fdad38781ccc ("LU-11376 lmv: new foreign LMV format") Signed-off-by: Bobi Jam Change-Id: I2d4c563725b35f7a75f0f1fbf9c1d35b1799eff4 Reviewed-on: https://review.whamcloud.com/45710 Tested-by: jenkins Tested-by: Maloo Reviewed-by: John L. Hammond Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- lustre/lod/lod_internal.h | 9 ++-- lustre/lod/lod_lov.c | 3 +- lustre/lod/lod_object.c | 126 ++++++++++++++++++++++++---------------------- 3 files changed, 72 insertions(+), 66 deletions(-) diff --git a/lustre/lod/lod_internal.h b/lustre/lod/lod_internal.h index 49b5568..9b8df7b 100644 --- a/lustre/lod/lod_internal.h +++ b/lustre/lod/lod_internal.h @@ -246,6 +246,8 @@ struct lod_object { /* common fields for both files and directories */ struct dt_object ldo_obj; struct mutex ldo_layout_mutex; + /* foreign file/directory */ + __u32 ldo_is_foreign:1; union { /* file stripe (LOV) */ struct { @@ -259,8 +261,7 @@ struct lod_object { struct lod_mirror_entry *ldo_mirrors; __u32 ldo_is_composite:1, ldo_flr_state:4, - ldo_comp_cached:1, - ldo_is_foreign:1; + ldo_comp_cached:1; }; /* directory stripe (LMV) */ struct { @@ -277,9 +278,7 @@ struct lod_object { __u32 ldo_dir_slave_stripe:1, ldo_dir_striped:1, /* the stripe has been loaded */ - ldo_dir_stripe_loaded:1, - /* foreign directory */ - ldo_dir_is_foreign; + ldo_dir_stripe_loaded:1; /* * This default LMV is parent default LMV, which will be * used in child creation, and it's not cached, so this diff --git a/lustre/lod/lod_lov.c b/lustre/lod/lod_lov.c index 4017dca..b3f9cd8 100644 --- a/lustre/lod/lod_lov.c +++ b/lustre/lod/lod_lov.c @@ -584,6 +584,7 @@ int lod_alloc_comp_entries(struct lod_object *lo, } lo->ldo_comp_cnt = comp_count; + lo->ldo_is_foreign = 0; return 0; } @@ -1512,7 +1513,7 @@ int lod_striping_load(const struct lu_env *env, struct lod_object *lo) info->lti_ea_store_size = 0; lo->ldo_dir_stripe_loaded = 1; - lo->ldo_dir_is_foreign = 1; + lo->ldo_is_foreign = 1; GOTO(unlock, rc = 0); } } diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index 982ccec..ac8d0c0 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -1868,6 +1868,7 @@ int lod_parse_dir_striping(const struct lu_env *env, struct lod_object *lo, } out: lo->ldo_stripe = stripe; + lo->ldo_is_foreign = 0; lo->ldo_dir_stripe_count = le32_to_cpu(lmv1->lmv_stripe_count); lo->ldo_dir_stripes_allocated = le32_to_cpu(lmv1->lmv_stripe_count); lo->ldo_dir_layout_version = le32_to_cpu(lmv1->lmv_layout_version); @@ -2300,6 +2301,41 @@ out: /** * + * Alloc cached foreign LOV + * + * \param[in] lo object + * \param[in] size size of foreign LOV + * + * \retval 0 on success + * \retval negative if failed + */ +int lod_alloc_foreign_lov(struct lod_object *lo, size_t size) +{ + OBD_ALLOC_LARGE(lo->ldo_foreign_lov, size); + if (lo->ldo_foreign_lov == NULL) + return -ENOMEM; + lo->ldo_foreign_lov_size = size; + lo->ldo_is_foreign = 1; + return 0; +} + +/** + * + * Free cached foreign LOV + * + * \param[in] lo object + */ +void lod_free_foreign_lov(struct lod_object *lo) +{ + if (lo->ldo_foreign_lov != NULL) + OBD_FREE_LARGE(lo->ldo_foreign_lov, lo->ldo_foreign_lov_size); + lo->ldo_foreign_lov = NULL; + lo->ldo_foreign_lov_size = 0; + lo->ldo_is_foreign = 0; +} + +/** + * * Alloc cached foreign LMV * * \param[in] lo object @@ -2314,12 +2350,27 @@ int lod_alloc_foreign_lmv(struct lod_object *lo, size_t size) if (lo->ldo_foreign_lmv == NULL) return -ENOMEM; lo->ldo_foreign_lmv_size = size; - lo->ldo_dir_is_foreign = 1; + lo->ldo_is_foreign = 1; return 0; } /** + * + * Free cached foreign LMV + * + * \param[in] lo object + */ +void lod_free_foreign_lmv(struct lod_object *lo) +{ + if (lo->ldo_foreign_lmv != NULL) + OBD_FREE_LARGE(lo->ldo_foreign_lmv, lo->ldo_foreign_lmv_size); + lo->ldo_foreign_lmv = NULL; + lo->ldo_foreign_lmv_size = 0; + lo->ldo_is_foreign = 0; +} + +/** * Declare create striped md object. * * The function declares intention to create a striped directory. This is a @@ -2357,7 +2408,7 @@ static int lod_declare_xattr_set_lmv(const struct lu_env *env, (int)le32_to_cpu(lum->lum_stripe_offset)); if (lo->ldo_dir_stripe_count == 0) { - if (lo->ldo_dir_is_foreign) { + if (lo->ldo_is_foreign) { rc = lod_alloc_foreign_lmv(lo, lum_buf->lb_len); if (rc != 0) GOTO(out, rc); @@ -4231,7 +4282,7 @@ static int lod_xattr_set_lmv(const struct lu_env *env, struct dt_object *dt, /* The stripes are supposed to be allocated in declare phase, * if there are no stripes being allocated, it will skip */ if (lo->ldo_dir_stripe_count == 0) { - if (lo->ldo_dir_is_foreign) { + if (lo->ldo_is_foreign) { rc = lod_sub_xattr_set(env, dt_object_child(dt), buf, XATTR_NAME_LMV, fl, th); if (rc != 0) @@ -4463,7 +4514,7 @@ static int lod_dir_striping_create_internal(const struct lu_env *env, lmu, dof, th); } } else { - if (lo->ldo_dir_is_foreign) { + if (lo->ldo_is_foreign) { LASSERT(lo->ldo_foreign_lmv != NULL && lo->ldo_foreign_lmv_size > 0); info->lti_buf.lb_buf = lo->ldo_foreign_lmv; @@ -5650,7 +5701,7 @@ static void lod_ah_init(const struct lu_env *env, */ if (ah->dah_eadata != NULL && ah->dah_eadata_len != 0 && le32_to_cpu(lum1->lum_magic) == LMV_MAGIC_FOREIGN) { - lc->ldo_dir_is_foreign = true; + lc->ldo_is_foreign = true; /* keep stripe_count 0 and stripe_offset -1 */ CDEBUG(D_INFO, "no default striping for foreign dir\n"); RETURN_EXIT; @@ -8346,6 +8397,7 @@ static int lod_dir_declare_layout_attach(const struct lu_env *env, OBD_FREE_PTR_ARRAY(lo->ldo_stripe, lo->ldo_dir_stripes_allocated); lo->ldo_stripe = stripes; + lo->ldo_is_foreign = 0; lo->ldo_dir_migrate_offset = lo->ldo_dir_stripe_count; lo->ldo_dir_migrate_hash = le32_to_cpu(lmv->lmv_hash_type); lo->ldo_dir_stripe_count += stripe_count; @@ -8590,6 +8642,7 @@ static int lod_dir_declare_layout_split(const struct lu_env *env, OBD_FREE(lo->ldo_stripe, sizeof(*stripes) * lo->ldo_dir_stripes_allocated); lo->ldo_stripe = stripes; + lo->ldo_is_foreign = 0; lo->ldo_dir_striped = 1; lo->ldo_dir_stripe_count = rc; lo->ldo_dir_stripes_allocated = stripe_count; @@ -9059,56 +9112,6 @@ static int lod_object_init(const struct lu_env *env, struct lu_object *lo, /** * - * Alloc cached foreign LOV - * - * \param[in] lo object - * \param[in] size size of foreign LOV - * - * \retval 0 on success - * \retval negative if failed - */ -int lod_alloc_foreign_lov(struct lod_object *lo, size_t size) -{ - OBD_ALLOC_LARGE(lo->ldo_foreign_lov, size); - if (lo->ldo_foreign_lov == NULL) - return -ENOMEM; - lo->ldo_foreign_lov_size = size; - lo->ldo_is_foreign = 1; - return 0; -} - -/** - * - * Free cached foreign LOV - * - * \param[in] lo object - */ -void lod_free_foreign_lov(struct lod_object *lo) -{ - if (lo->ldo_foreign_lov != NULL) - OBD_FREE_LARGE(lo->ldo_foreign_lov, lo->ldo_foreign_lov_size); - lo->ldo_foreign_lov = NULL; - lo->ldo_foreign_lov_size = 0; - lo->ldo_is_foreign = 0; -} - -/** - * - * Free cached foreign LMV - * - * \param[in] lo object - */ -void lod_free_foreign_lmv(struct lod_object *lo) -{ - if (lo->ldo_foreign_lmv != NULL) - OBD_FREE_LARGE(lo->ldo_foreign_lmv, lo->ldo_foreign_lmv_size); - lo->ldo_foreign_lmv = NULL; - lo->ldo_foreign_lmv_size = 0; - lo->ldo_dir_is_foreign = 0; -} - -/** - * * Release resources associated with striping. * * If the object is striped (regular or directory), then release @@ -9120,14 +9123,17 @@ void lod_free_foreign_lmv(struct lod_object *lo) void lod_striping_free_nolock(const struct lu_env *env, struct lod_object *lo) { struct lod_layout_component *lod_comp; + __u32 obj_attr = lo->ldo_obj.do_lu.lo_header->loh_attr; int i, j; if (unlikely(lo->ldo_is_foreign)) { - lod_free_foreign_lov(lo); - lo->ldo_comp_cached = 0; - } else if (unlikely(lo->ldo_dir_is_foreign)) { - lod_free_foreign_lmv(lo); - lo->ldo_dir_stripe_loaded = 0; + if (S_ISREG(obj_attr)) { + lod_free_foreign_lov(lo); + lo->ldo_comp_cached = 0; + } else if (S_ISDIR(obj_attr)) { + lod_free_foreign_lmv(lo); + lo->ldo_dir_stripe_loaded = 0; + } } else if (lo->ldo_stripe != NULL) { LASSERT(lo->ldo_comp_entries == NULL); LASSERT(lo->ldo_dir_stripes_allocated > 0); -- 1.8.3.1