* 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)
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);
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);
/* 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;
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);
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);
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)
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;
}
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);
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;
lod_comp->llc_pool = NULL;
}
}
- OBD_FREE(comp_array, sizeof(*comp_array) * array_cnt);
+ OBD_FREE_PTR_ARRAY(comp_array, array_cnt);
RETURN(rc);
}
}
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);
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;
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);
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 */
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;
EXIT;
out:
if (rc)
- OBD_FREE(comp_array, sizeof(*comp_array) * new_cnt);
+ OBD_FREE_PTR_ARRAY(comp_array, new_cnt);
return rc;
}
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);
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;
}
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);
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 {
}
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;
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;
}
*/
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;
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];
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;
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;
(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;
}
}
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
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;
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
}
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);
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)
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);
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);
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);
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);
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);
}
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);
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;
}
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);
}
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);
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;
}