Whamcloud - gitweb
LU-12960 lod: don't set index for 2nd stripe if specific
[fs/lustre-release.git] / lustre / lod / lod_object.c
index d38bca0..fc9efb5 100644 (file)
@@ -1606,8 +1606,8 @@ static int lod_xattr_get(const struct lu_env *env, struct dt_object *dt,
                         * the FIDs of all shards of the striped directory. */
                        if (le32_to_cpu(lmv1->lmv_magic) == LMV_MAGIC_V1)
                                rc = lmv_mds_md_size(
-                                               le32_to_cpu(lmv1->lmv_stripe_count),
-                                               le32_to_cpu(lmv1->lmv_magic));
+                                       le32_to_cpu(lmv1->lmv_stripe_count),
+                                       le32_to_cpu(lmv1->lmv_magic));
                } else {
                        lmv1 = buf->lb_buf;
                        if (le32_to_cpu(lmv1->lmv_magic) != LMV_MAGIC_V1)
@@ -1818,8 +1818,7 @@ int lod_parse_dir_striping(const struct lu_env *env, struct lod_object *lo,
                RETURN(-EINVAL);
 
        LASSERT(lo->ldo_stripe == NULL);
-       OBD_ALLOC(stripe, sizeof(stripe[0]) *
-                 (le32_to_cpu(lmv1->lmv_stripe_count)));
+       OBD_ALLOC_PTR_ARRAY(stripe, le32_to_cpu(lmv1->lmv_stripe_count));
        if (stripe == NULL)
                RETURN(-ENOMEM);
 
@@ -2076,7 +2075,7 @@ static int lod_mdt_alloc_specific(const struct lu_env *env,
        int rc;
 
        master_index = lu_site2seq(lod2lu_dev(lod)->ld_site)->ss_node_id;
-       if (stripe_count > 1)
+       if (!is_specific && stripe_count > 1)
                /* Set the start index for the 2nd stripe allocation */
                mdt_indices[1] = (mdt_indices[0] + 1) %
                                        (lod->lod_remote_mdt_count + 1);
@@ -2109,7 +2108,7 @@ static int lod_mdt_alloc_specific(const struct lu_env *env,
 
                        /* Sigh, this index is not in the bitmap, let's check
                         * next available target */
-                       if (!cfs_bitmap_check(ltd->ltd_tgt_bitmap, idx) &&
+                       if (!test_bit(idx, ltd->ltd_tgt_bitmap) &&
                            idx != master_index)
                                continue;
 
@@ -2218,7 +2217,7 @@ static int lod_prep_md_striped_create(const struct lu_env *env,
 
        stripe_count = lo->ldo_dir_stripe_count;
 
-       OBD_ALLOC(stripes, sizeof(stripes[0]) * stripe_count);
+       OBD_ALLOC_PTR_ARRAY(stripes, stripe_count);
        if (!stripes)
                RETURN(-ENOMEM);
 
@@ -2242,7 +2241,7 @@ static int lod_prep_md_striped_create(const struct lu_env *env,
                int *idx_array;
                bool is_specific = false;
 
-               OBD_ALLOC(idx_array, sizeof(idx_array[0]) * stripe_count);
+               OBD_ALLOC_PTR_ARRAY(idx_array, stripe_count);
                if (!idx_array)
                        GOTO(out, rc = -ENOMEM);
 
@@ -2258,7 +2257,7 @@ static int lod_prep_md_striped_create(const struct lu_env *env,
                        lu_site2seq(lod2lu_dev(lod)->ld_site)->ss_node_id;
                rc = lod_mdt_alloc_specific(env, lo, stripes, idx_array,
                                            is_specific);
-               OBD_FREE(idx_array, sizeof(idx_array[0]) * stripe_count);
+               OBD_FREE_PTR_ARRAY(idx_array, stripe_count);
        }
 
        if (rc < 0)
@@ -2285,7 +2284,7 @@ out:
                dt_object_put(env, stripes[0]);
        for (i = 1; i < stripe_count; i++)
                LASSERT(!stripes[i]);
-       OBD_FREE(stripes, sizeof(stripes[0]) * stripe_count);
+       OBD_FREE_PTR_ARRAY(stripes, stripe_count);
 
        return rc;
 }
@@ -2743,7 +2742,7 @@ static int lod_declare_layout_add(const struct lu_env *env,
                RETURN(-EINVAL);
 
        array_cnt = lo->ldo_comp_cnt + comp_v1->lcm_entry_count;
-       OBD_ALLOC(comp_array, sizeof(*comp_array) * array_cnt);
+       OBD_ALLOC_PTR_ARRAY(comp_array, array_cnt);
        if (comp_array == NULL)
                RETURN(-ENOMEM);
 
@@ -2797,7 +2796,7 @@ static int lod_declare_layout_add(const struct lu_env *env,
                GOTO(error, rc);
        }
 
-       OBD_FREE(old_array, sizeof(*lod_comp) * old_array_cnt);
+       OBD_FREE_PTR_ARRAY(old_array, old_array_cnt);
 
        LASSERT(lo->ldo_mirror_count == 1);
        lo->ldo_mirrors[0].lme_end = array_cnt - 1;
@@ -2813,7 +2812,7 @@ error:
                        lod_comp->llc_pool = NULL;
                }
        }
-       OBD_FREE(comp_array, sizeof(*comp_array) * array_cnt);
+       OBD_FREE_PTR_ARRAY(comp_array, array_cnt);
        RETURN(rc);
 }
 
@@ -3207,13 +3206,13 @@ static int lod_layout_convert(struct lod_thread_info *info)
        }
 
        lcm = info->lti_ea_store;
+       memset(lcm, 0, sizeof(*lcm) + sizeof(*lcme));
        lcm->lcm_magic = cpu_to_le32(LOV_MAGIC_COMP_V1);
        lcm->lcm_size = cpu_to_le32(size);
        lcm->lcm_layout_gen = cpu_to_le32(le16_to_cpu(
                                                lmm_save->lmm_layout_gen));
        lcm->lcm_flags = cpu_to_le16(LCM_FL_NONE);
        lcm->lcm_entry_count = cpu_to_le16(1);
-       lcm->lcm_mirror_count = 0;
 
        lcme = &lcm->lcm_entries[0];
        lcme->lcme_flags = cpu_to_le32(LCME_FL_INIT);
@@ -3786,7 +3785,7 @@ static int lod_xattr_set_lmv(const struct lu_env *env, struct dt_object *dt,
        if (rc != 0)
                RETURN(rc);
 
-       attr->la_valid = LA_ATIME | LA_MTIME | LA_CTIME |
+       attr->la_valid = LA_ATIME | LA_MTIME | LA_CTIME | LA_FLAGS |
                         LA_MODE | LA_UID | LA_GID | LA_TYPE | LA_PROJID;
        dof->dof_type = DFT_DIR;
 
@@ -4202,7 +4201,7 @@ static int lod_layout_repeat_comp(const struct lu_env *env,
 
        CDEBUG(D_LAYOUT, "repeating component %d\n", index);
 
-       OBD_ALLOC(comp_array, sizeof(*comp_array) * new_cnt);
+       OBD_ALLOC_PTR_ARRAY(comp_array, new_cnt);
        if (comp_array == NULL)
                GOTO(out, rc = -ENOMEM);
 
@@ -4224,6 +4223,7 @@ static int lod_layout_repeat_comp(const struct lu_env *env,
        new_comp->llc_flags &= ~LCME_FL_INIT;
        new_comp->llc_stripe = NULL;
        new_comp->llc_stripes_allocated = 0;
+       new_comp->llc_ost_indices = NULL;
        new_comp->llc_stripe_offset = LOV_OFFSET_DEFAULT;
        /* for uninstantiated components, layout gen stores default stripe
         * offset */
@@ -4249,8 +4249,7 @@ static int lod_layout_repeat_comp(const struct lu_env *env,
                new_comp->llc_ostlist.op_array = op_array;
        }
 
-       OBD_FREE(lo->ldo_comp_entries,
-                sizeof(*comp_array) * lo->ldo_comp_cnt);
+       OBD_FREE_PTR_ARRAY(lo->ldo_comp_entries, lo->ldo_comp_cnt);
        lo->ldo_comp_entries = comp_array;
        lo->ldo_comp_cnt = new_cnt;
 
@@ -4264,7 +4263,7 @@ static int lod_layout_repeat_comp(const struct lu_env *env,
        EXIT;
 out:
        if (rc)
-               OBD_FREE(comp_array, sizeof(*comp_array) * new_cnt);
+               OBD_FREE_PTR_ARRAY(comp_array, new_cnt);
 
        return rc;
 }
@@ -4281,12 +4280,11 @@ static int lod_layout_data_init(struct lod_thread_info *info, __u32 comp_cnt)
                RETURN(0);
 
        if (info->lti_comp_size > 0) {
-               OBD_FREE(info->lti_comp_idx,
-                        info->lti_comp_size * sizeof(__u32));
+               OBD_FREE_PTR_ARRAY(info->lti_comp_idx, info->lti_comp_size);
                info->lti_comp_size = 0;
        }
 
-       OBD_ALLOC(info->lti_comp_idx, comp_cnt * sizeof(__u32));
+       OBD_ALLOC_PTR_ARRAY(info->lti_comp_idx, comp_cnt);
        if (!info->lti_comp_idx)
                RETURN(-ENOMEM);
 
@@ -4373,11 +4371,11 @@ static int lod_layout_del_prep_layout(const struct lu_env *env,
                        lu_object_put(env, &obj->do_lu);
                        lod_comp->llc_stripe[j] = NULL;
                }
-               OBD_FREE(lod_comp->llc_stripe, sizeof(*lod_comp->llc_stripe) *
-                                       lod_comp->llc_stripes_allocated);
+               OBD_FREE_PTR_ARRAY(lod_comp->llc_stripe,
+                                  lod_comp->llc_stripes_allocated);
                lod_comp->llc_stripe = NULL;
-               OBD_FREE(lod_comp->llc_ost_indices,
-                        sizeof(__u32) * lod_comp->llc_stripes_allocated);
+               OBD_FREE_PTR_ARRAY(lod_comp->llc_ost_indices,
+                                  lod_comp->llc_stripes_allocated);
                lod_comp->llc_ost_indices = NULL;
                lod_comp->llc_stripes_allocated = 0;
        }
@@ -4390,7 +4388,7 @@ static int lod_layout_del_prep_layout(const struct lu_env *env,
        if (info->lti_count > 0) {
                struct lod_layout_component *comp_array;
 
-               OBD_ALLOC(comp_array, sizeof(*comp_array) * info->lti_count);
+               OBD_ALLOC_PTR_ARRAY(comp_array, info->lti_count);
                if (comp_array == NULL)
                        GOTO(out, rc = -ENOMEM);
 
@@ -4400,8 +4398,7 @@ static int lod_layout_del_prep_layout(const struct lu_env *env,
                               sizeof(*comp_array));
                }
 
-               OBD_FREE(lo->ldo_comp_entries,
-                        sizeof(*comp_array) * lo->ldo_comp_cnt);
+               OBD_FREE_PTR_ARRAY(lo->ldo_comp_entries, lo->ldo_comp_cnt);
                lo->ldo_comp_entries = comp_array;
                lo->ldo_comp_cnt = info->lti_count;
        } else {
@@ -6294,7 +6291,9 @@ static int lod_invalidate(const struct lu_env *env, struct dt_object *dt)
 }
 
 static int lod_declare_instantiate_components(const struct lu_env *env,
-               struct lod_object *lo, struct thandle *th)
+                                             struct lod_object *lo,
+                                             struct thandle *th,
+                                             __u64 reserve)
 {
        struct lod_thread_info *info = lod_env_info(env);
        int i;
@@ -6305,7 +6304,7 @@ static int lod_declare_instantiate_components(const struct lu_env *env,
 
        for (i = 0; i < info->lti_count; i++) {
                rc = lod_qos_prep_create(env, lo, NULL, th,
-                                        info->lti_comp_idx[i]);
+                                        info->lti_comp_idx[i], reserve);
                if (rc)
                        break;
        }
@@ -6341,15 +6340,15 @@ static int lod_declare_instantiate_components(const struct lu_env *env,
  */
 static bool lod_sel_osts_allowed(const struct lu_env *env,
                                 struct lod_object *lo,
-                                int index, __u64 extension_size,
+                                int index, __u64 reserve,
                                 struct lu_extent *extent,
                                 struct lu_extent *comp_extent, int write)
 {
        struct lod_layout_component *lod_comp = &lo->ldo_comp_entries[index];
        struct lod_device *lod = lu2lod_dev(lo->ldo_obj.do_lu.lo_dev);
-       struct obd_statfs *sfs = &lod_env_info(env)->lti_osfs;
+       struct lod_thread_info *tinfo = lod_env_info(env);
+       struct obd_statfs *sfs = &tinfo->lti_osfs;
        __u64 available = 0;
-       __u64 size;
        bool ret = true;
        int i, rc;
 
@@ -6357,21 +6356,6 @@ static bool lod_sel_osts_allowed(const struct lu_env *env,
 
        LASSERT(lod_comp->llc_stripe_count != 0);
 
-       if (write == 0 ||
-           (extent->e_start == 0 && extent->e_end == OBD_OBJECT_EOF)) {
-               /* truncate or append */
-               size = extension_size;
-       } else {
-               /* In case of write op, check the real write extent,
-                * it may be larger than the extension_size */
-               size = roundup(min(extent->e_end, comp_extent->e_end) -
-                              max(extent->e_start, comp_extent->e_start),
-                              extension_size);
-       }
-       /* extension_size is file level, so we must divide by stripe count to
-        * compare it to available space on a single OST */
-       size /= lod_comp->llc_stripe_count;
-
        lod_getref(&lod->lod_ost_descs);
        for (i = 0; i < lod_comp->llc_stripe_count; i++) {
                int index = lod_comp->llc_ost_indices[i];
@@ -6398,7 +6382,7 @@ static bool lod_sel_osts_allowed(const struct lu_env *env,
                if (j < lod_comp->llc_stripe_count)
                        continue;
 
-               if (!cfs_bitmap_check(lod->lod_ost_bitmap, index)) {
+               if (!test_bit(index, lod->lod_ost_bitmap)) {
                        CDEBUG(D_LAYOUT, "ost %d no longer present\n", index);
                        ret = false;
                        break;
@@ -6412,9 +6396,9 @@ static bool lod_sel_osts_allowed(const struct lu_env *env,
                        break;
                }
 
-               if (sfs->os_state & OS_STATE_ENOSPC ||
-                   sfs->os_state & OS_STATE_READONLY ||
-                   sfs->os_state & OS_STATE_DEGRADED) {
+               if (sfs->os_state & OS_STATFS_ENOSPC ||
+                   sfs->os_state & OS_STATFS_READONLY ||
+                   sfs->os_state & OS_STATFS_DEGRADED) {
                        CDEBUG(D_LAYOUT, "ost %d is not availble for SEL "
                               "extension, state %u\n", index, sfs->os_state);
                        ret = false;
@@ -6432,11 +6416,11 @@ static bool lod_sel_osts_allowed(const struct lu_env *env,
                       (100ull * sfs->os_bavail) / sfs->os_blocks,
                       (100ull * sfs->os_bfree) / sfs->os_blocks);
 
-               if (size * repeated > available) {
+               if (reserve * repeated > available) {
                        ret = false;
                        CDEBUG(D_LAYOUT, "low space on ost %d, available %llu "
-                              "< extension size %llu\n", index, available,
-                              extension_size);
+                              "< extension size %llu repeated %d\n", index,
+                              available, reserve, repeated);
                        break;
                }
        }
@@ -6542,6 +6526,26 @@ static __u64 lod_extension_new_end(__u64 extension_size, __u64 extent_end,
        return new_end;
 }
 
+/**
+ * Calculate the exact reservation (per-OST extension_size) on the OSTs being
+ * instantiated. It needs to be calculated in advance and taken into account at
+ * the instantiation time, because otherwise lod_statfs_and_check() may consider
+ * an OST as OK, but SEL needs its extension_size to fit the free space and the
+ * OST may turn out to be low-on-space, thus inappropriate OST may be used and
+ * ENOSPC occurs.
+ *
+ * \param[in] lod_comp         lod component we are checking
+ *
+ * \retval     size to reserved on each OST of lod_comp's stripe.
+ */
+static __u64 lod_sel_stripe_reserved(struct lod_layout_component *lod_comp)
+{
+       /* extension_size is file level, so we must divide by stripe count to
+        * compare it to available space on a single OST */
+       return  lod_comp->llc_stripe_size * SEL_UNIT_SIZE /
+               lod_comp->llc_stripe_count;
+}
+
 /* As lod_sel_handler() could be re-entered for the same component several
  * times, this is the data for the next call. Fields could be changed to
  * component indexes when needed, (e.g. if there is no need to instantiate
@@ -6623,7 +6627,7 @@ static int lod_sel_handler(const struct lu_env *env,
        struct lod_layout_component *lod_comp;
        struct lod_layout_component *prev;
        struct lod_layout_component *next = NULL;
-       __u64 extension_size;
+       __u64 extension_size, reserve;
        __u64 new_end = 0;
        bool repeated;
        int change = 0;
@@ -6660,11 +6664,13 @@ static int lod_sel_handler(const struct lu_env *env,
                RETURN(-EINVAL);
        }
 
+       reserve = lod_sel_stripe_reserved(lod_comp);
+
        if (!prev->llc_stripe) {
                CDEBUG(D_LAYOUT, "Previous component not inited\n");
                info->lti_count = 1;
                info->lti_comp_idx[0] = index - 1;
-               rc = lod_declare_instantiate_components(env, lo, th);
+               rc = lod_declare_instantiate_components(env, lo, th, reserve);
                /* ENOSPC tells us we can't use this component.  If there is
                 * a next or we are repeating, we either spill over (next) or
                 * extend the original comp (repeat).  Otherwise, return the
@@ -6676,8 +6682,7 @@ static int lod_sel_handler(const struct lu_env *env,
        }
 
        if (sd->sd_force == 0 && rc == 0)
-               rc = !lod_sel_osts_allowed(env, lo, index - 1,
-                                          extension_size, extent,
+               rc = !lod_sel_osts_allowed(env, lo, index - 1, reserve, extent,
                                           &lod_comp->llc_extent, write);
 
        repeated = !!(sd->sd_repeat);
@@ -6991,7 +6996,7 @@ static int lod_declare_update_plain(const struct lu_env *env,
                RETURN(-EALREADY);
 
        lod_obj_inc_layout_gen(lo);
-       rc = lod_declare_instantiate_components(env, lo, th);
+       rc = lod_declare_instantiate_components(env, lo, th, 0);
        EXIT;
 out:
        if (rc)
@@ -7101,8 +7106,8 @@ static inline int lod_check_ost_avail(const struct lu_env *env,
 
        ost = OST_TGT(lod, idx);
        if (ost->ltd_statfs.os_state &
-               (OS_STATE_READONLY | OS_STATE_ENOSPC | OS_STATE_ENOINO |
-                OS_STATE_NOPRECREATE) ||
+               (OS_STATFS_READONLY | OS_STATFS_ENOSPC | OS_STATFS_ENOINO |
+                OS_STATFS_NOPRECREATE) ||
            ost->ltd_active == 0) {
                CDEBUG(D_LAYOUT, DFID ": mirror %d OST%d unavail, rc = %d\n",
                       PFID(lod_object_fid(lo)), index, idx, rc);
@@ -7408,7 +7413,7 @@ static int lod_declare_update_rdonly(const struct lu_env *env,
                lo->ldo_layout_gen = layout_version & 0xffff;
        }
 
-       rc = lod_declare_instantiate_components(env, lo, th);
+       rc = lod_declare_instantiate_components(env, lo, th, 0);
        if (rc)
                GOTO(out, rc);
 
@@ -7448,7 +7453,7 @@ static int lod_declare_update_write_pending(const struct lu_env *env,
                if (lo->ldo_mirrors[i].lme_stale)
                        continue;
 
-               LASSERTF(primary < 0, DFID " has multiple primary: %u / %u",
+               LASSERTF(primary < 0, DFID " has multiple primary: %u / %u\n",
                         PFID(lod_object_fid(lo)),
                         lo->ldo_mirrors[i].lme_id,
                         lo->ldo_mirrors[primary].lme_id);
@@ -7552,7 +7557,7 @@ static int lod_declare_update_write_pending(const struct lu_env *env,
                lo->ldo_flr_state = LCM_FL_SYNC_PENDING;
        }
 
-       rc = lod_declare_instantiate_components(env, lo, th);
+       rc = lod_declare_instantiate_components(env, lo, th, 0);
        if (rc)
                GOTO(out, rc);
 
@@ -7719,8 +7724,7 @@ static int lod_dir_declare_layout_attach(const struct lu_env *env,
 
        dof->dof_type = DFT_DIR;
 
-       OBD_ALLOC(stripes,
-                 sizeof(*stripes) * (lo->ldo_dir_stripe_count + stripe_count));
+       OBD_ALLOC_PTR_ARRAY(stripes, (lo->ldo_dir_stripe_count + stripe_count));
        if (!stripes)
                RETURN(-ENOMEM);
 
@@ -7811,8 +7815,8 @@ static int lod_dir_declare_layout_attach(const struct lu_env *env,
        }
 
        if (lo->ldo_stripe)
-               OBD_FREE(lo->ldo_stripe,
-                        sizeof(*stripes) * lo->ldo_dir_stripes_allocated);
+               OBD_FREE_PTR_ARRAY(lo->ldo_stripe,
+                                  lo->ldo_dir_stripes_allocated);
        lo->ldo_stripe = stripes;
        lo->ldo_dir_migrate_offset = lo->ldo_dir_stripe_count;
        lo->ldo_dir_migrate_hash = le32_to_cpu(lmv->lmv_hash_type);
@@ -7831,8 +7835,7 @@ out:
        while (i < lo->ldo_dir_stripe_count + stripe_count && stripes[i])
                dt_object_put(env, stripes[i++]);
 
-       OBD_FREE(stripes,
-                sizeof(*stripes) * (stripe_count + lo->ldo_dir_stripe_count));
+       OBD_FREE_PTR_ARRAY(stripes, stripe_count + lo->ldo_dir_stripe_count);
        return rc;
 }
 
@@ -8148,11 +8151,11 @@ static int lod_dir_layout_detach(const struct lu_env *env,
                if (dto)
                        dt_object_put(env, dto);
        }
-       OBD_FREE(lo->ldo_stripe,
-                sizeof(struct dt_object *) * lo->ldo_dir_stripes_allocated);
+       OBD_FREE_PTR_ARRAY(lo->ldo_stripe, lo->ldo_dir_stripes_allocated);
        lo->ldo_stripe = NULL;
        lo->ldo_dir_stripes_allocated = 0;
        lo->ldo_dir_stripe_count = 0;
+       dt->do_index_ops = &lod_index_ops;
 
        RETURN(rc);
 }
@@ -8509,7 +8512,7 @@ static int lod_object_init(const struct lu_env *env, struct lu_object *lo,
 
        if (ltd != NULL) {
                if (ltd->ltd_tgts_size > idx &&
-                   cfs_bitmap_check(ltd->ltd_tgt_bitmap, idx)) {
+                   test_bit(idx, ltd->ltd_tgt_bitmap)) {
                        tgt = LTD_TGT(ltd, idx);
 
                        LASSERT(tgt != NULL);
@@ -8633,13 +8636,11 @@ void lod_striping_free_nolock(const struct lu_env *env, struct lod_object *lo)
                                        lu_object_put(env,
                                               &lod_comp->llc_stripe[j]->do_lu);
                        }
-                       OBD_FREE(lod_comp->llc_stripe,
-                                sizeof(struct dt_object *) *
-                                lod_comp->llc_stripes_allocated);
+                       OBD_FREE_PTR_ARRAY(lod_comp->llc_stripe,
+                                          lod_comp->llc_stripes_allocated);
                        lod_comp->llc_stripe = NULL;
-                       OBD_FREE(lod_comp->llc_ost_indices,
-                                sizeof(__u32) *
-                                lod_comp->llc_stripes_allocated);
+                       OBD_FREE_PTR_ARRAY(lod_comp->llc_ost_indices,
+                                          lod_comp->llc_stripes_allocated);
                        lod_comp->llc_ost_indices = NULL;
                        lod_comp->llc_stripes_allocated = 0;
                }