From 96bfcd13b6cc3fce12f1e6f5abe4971cc8a59e1f Mon Sep 17 00:00:00 2001 From: Patrick Farrell Date: Thu, 20 Jun 2019 00:29:12 +0300 Subject: [PATCH] LU-10070 lod: SEL: split lod_del_layout SEL deletes layout components as part of other operations, rather than only as a separate delete operation. So we split lod_layout_del in to a function that prepares the layout and one that writes it out. The prep_layout function will be used in later patches. Cray-bug-id: LUS-2528 Signed-off-by: Patrick Farrell Change-Id: I5d7270db9a8d9bc94f4571906ed9e2d4a17a151b Reviewed-on: https://review.whamcloud.com/33780 Reviewed-by: Patrick Farrell Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- lustre/lod/lod_object.c | 185 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 125 insertions(+), 60 deletions(-) diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index 3097952..8c20f0d 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -4119,35 +4119,72 @@ static int lod_generate_and_set_lovea(const struct lu_env *env, RETURN(rc); } +static int lod_layout_data_init(struct lod_thread_info *info, __u32 comp_cnt) +{ + ENTRY; + + /* clear memory region that will be used for layout change */ + memset(&info->lti_layout_attr, 0, sizeof(struct lu_attr)); + info->lti_count = 0; + + if (info->lti_comp_size >= comp_cnt) + RETURN(0); + + if (info->lti_comp_size > 0) { + OBD_FREE(info->lti_comp_idx, + info->lti_comp_size * sizeof(__u32)); + info->lti_comp_size = 0; + } + + OBD_ALLOC(info->lti_comp_idx, comp_cnt * sizeof(__u32)); + if (!info->lti_comp_idx) + RETURN(-ENOMEM); + + info->lti_comp_size = comp_cnt; + RETURN(0); +} + /** - * Delete layout component(s) + * Prepare new layout minus deleted components * - * \param[in] env execution environment for this thread - * \param[in] dt object - * \param[in] th transaction handle + * Removes components marked for deletion (LCME_ID_INVAL) by copying to a new + * layout and skipping those components. Removes stripe objects if any exist. * - * \retval 0 on success - * \retval negative error number on failure + * NB: + * Reallocates layout components array (lo->ldo_comp_entries), invalidating + * any pre-existing pointers to components. + * + * Caller is responsible for updating mirror end (ldo_mirror[].lme_end). + * + * \param[in] env execution environment for this thread + * \param[in,out] lo object to update the layout of + * \param[in] th transaction handle for this operation + * + * \retval # of components deleted + * \retval negative errno on error */ -static int lod_layout_del(const struct lu_env *env, struct dt_object *dt, - struct thandle *th) +static int lod_layout_del_prep_layout(const struct lu_env *env, + struct lod_object *lo, + struct thandle *th) { - struct lod_layout_component *lod_comp; - struct lod_object *lo = lod_dt_obj(dt); - struct dt_object *next = dt_object_child(dt); - struct lu_attr *attr = &lod_env_info(env)->lti_attr; - int rc, i, j, left; + struct lod_layout_component *lod_comp; + struct lod_thread_info *info = lod_env_info(env); + int rc = 0, i, j, deleted = 0; - LASSERT(lo->ldo_is_composite); - LASSERT(lo->ldo_comp_cnt > 0 && lo->ldo_comp_entries != NULL); + ENTRY; - left = lo->ldo_comp_cnt; - for (i = (lo->ldo_comp_cnt - 1); i >= 0; i--) { + rc = lod_layout_data_init(info, lo->ldo_comp_cnt); + if (rc) + RETURN(rc); + + for (i = 0; i < lo->ldo_comp_cnt; i++) { lod_comp = &lo->ldo_comp_entries[i]; - if (lod_comp->llc_id != LCME_ID_INVAL) - break; - left--; + if (lod_comp->llc_id != LCME_ID_INVAL) { + /* Build array of things to keep */ + info->lti_comp_idx[info->lti_count++] = i; + continue; + } lod_obj_set_pool(lo, i, NULL); if (lod_comp->llc_ostlist.op_array) { @@ -4157,7 +4194,11 @@ static int lod_layout_del(const struct lu_env *env, struct dt_object *dt, lod_comp->llc_ostlist.op_size = 0; } - /* Not instantiated component */ + deleted++; + CDEBUG(D_LAYOUT, "deleting comp %d, left %d\n", i, + lo->ldo_comp_cnt - deleted); + + /* No striping info for this component */ if (lod_comp->llc_stripe == NULL) continue; @@ -4167,9 +4208,14 @@ static int lod_layout_del(const struct lu_env *env, struct dt_object *dt, if (obj == NULL) continue; - rc = lod_sub_destroy(env, obj, th); - if (rc) - GOTO(out, rc); + + /* components which are not init have no sub objects + * to destroy */ + if (lod_comp_inited(lod_comp)) { + rc = lod_sub_destroy(env, obj, th); + if (rc) + GOTO(out, rc); + } lu_object_put(env, &obj->do_lu); lod_comp->llc_stripe[j] = NULL; @@ -4183,29 +4229,73 @@ static int lod_layout_del(const struct lu_env *env, struct dt_object *dt, lod_comp->llc_stripes_allocated = 0; } - LASSERTF(left >= 0 && left < lo->ldo_comp_cnt, "left = %d\n", left); - if (left > 0) { - struct lod_layout_component *comp_array; + /* info->lti_count has the amount of left components */ + LASSERTF(info->lti_count >= 0 && info->lti_count < lo->ldo_comp_cnt, + "left = %d, lo->ldo_comp_cnt %d\n", (int)info->lti_count, + (int)lo->ldo_comp_cnt); + + if (info->lti_count > 0) { + struct lod_layout_component *comp_array; - OBD_ALLOC(comp_array, sizeof(*comp_array) * left); + OBD_ALLOC(comp_array, sizeof(*comp_array) * info->lti_count); if (comp_array == NULL) GOTO(out, rc = -ENOMEM); - memcpy(&comp_array[0], &lo->ldo_comp_entries[0], - sizeof(*comp_array) * left); + for (i = 0; i < info->lti_count; i++) { + memcpy(&comp_array[i], + &lo->ldo_comp_entries[info->lti_comp_idx[i]], + sizeof(*comp_array)); + } OBD_FREE(lo->ldo_comp_entries, sizeof(*comp_array) * lo->ldo_comp_cnt); lo->ldo_comp_entries = comp_array; - lo->ldo_comp_cnt = left; - - LASSERT(lo->ldo_mirror_count == 1); - lo->ldo_mirrors[0].lme_end = left - 1; - lod_obj_inc_layout_gen(lo); + lo->ldo_comp_cnt = info->lti_count; } else { lod_free_comp_entries(lo); } + EXIT; +out: + return rc ? rc : deleted; +} + +/** + * Delete layout component(s) + * + * This function sets up the layout data in the env and does the setattrs + * required to write out the new layout. The layout itself is modified in + * lod_layout_del_prep_layout. + * + * \param[in] env execution environment for this thread + * \param[in] dt object + * \param[in] th transaction handle + * + * \retval 0 on success + * \retval negative error number on failure + */ +static int lod_layout_del(const struct lu_env *env, struct dt_object *dt, + struct thandle *th) +{ + struct lod_object *lo = lod_dt_obj(dt); + struct dt_object *next = dt_object_child(dt); + struct lu_attr *attr = &lod_env_info(env)->lti_attr; + int rc; + + LASSERT(lo->ldo_is_composite); + LASSERT(lo->ldo_mirror_count == 1); + LASSERT(lo->ldo_comp_cnt > 0 && lo->ldo_comp_entries != NULL); + + rc = lod_layout_del_prep_layout(env, lo, th); + if (rc < 0) + GOTO(out, rc); + + /* Only do this if we didn't delete all components */ + if (lo->ldo_comp_cnt > 0) { + lo->ldo_mirrors[0].lme_end = lo->ldo_comp_cnt - 1; + lod_obj_inc_layout_gen(lo); + } + LASSERT(dt_object_exists(dt)); rc = dt_attr_get(env, next, attr); if (rc) @@ -6020,31 +6110,6 @@ static int lod_invalidate(const struct lu_env *env, struct dt_object *dt) return dt_invalidate(env, dt_object_child(dt)); } -static int lod_layout_data_init(struct lod_thread_info *info, __u32 comp_cnt) -{ - ENTRY; - - /* clear memory region that will be used for layout change */ - memset(&info->lti_layout_attr, 0, sizeof(struct lu_attr)); - info->lti_count = 0; - - if (info->lti_comp_size >= comp_cnt) - RETURN(0); - - if (info->lti_comp_size > 0) { - OBD_FREE(info->lti_comp_idx, - info->lti_comp_size * sizeof(__u32)); - info->lti_comp_size = 0; - } - - OBD_ALLOC(info->lti_comp_idx, comp_cnt * sizeof(__u32)); - if (!info->lti_comp_idx) - RETURN(-ENOMEM); - - info->lti_comp_size = comp_cnt; - RETURN(0); -} - static int lod_declare_instantiate_components(const struct lu_env *env, struct lod_object *lo, struct thandle *th) { -- 1.8.3.1