struct obd_device *pool_lobd; /* owner */
};
-#define pool_tgt_size(p) ((p)->pool_obds.op_size)
#define pool_tgt_count(p) ((p)->pool_obds.op_count)
#define pool_tgt_array(p) ((p)->pool_obds.op_array)
#define pool_tgt_rw_sem(p) ((p)->pool_obds.op_rw_sem)
struct thandle *th, int stripe_idx,
struct lod_obj_stripe_cb_data *data);
/* lod_qos.c */
+int lod_prepare_inuse(const struct lu_env *env, struct lod_object *lo);
int lod_prepare_create(const struct lu_env *env, struct lod_object *lo,
struct lu_attr *attr, const struct lu_buf *buf,
struct thandle *th);
struct lod_layout_component *entry,
bool is_dir)
{
+ struct lod_device *lod = lu2lod_dev(lod2lu_obj(lo)->lo_dev);
+
if (is_dir)
return 0;
else if (lod_comp_inited(entry))
return entry->llc_stripenr;
+ else if ((__u16)-1 == entry->llc_stripenr)
+ return lod->lod_desc.ld_tgt_count;
else
- return lod_get_stripecnt(lu2lod_dev(lod2lu_obj(lo)->lo_dev), lo,
- entry->llc_stripenr);
+ return lod_get_stripecnt(lod, lo, entry->llc_stripenr);
}
static int lod_comp_md_size(struct lod_object *lo, bool is_dir)
continue;
extent = &lod_comp->llc_extent;
+ CDEBUG(D_INFO, "%lld [%lld, %lld)\n",
+ size, extent->e_start, extent->e_end);
if (!lo->ldo_is_composite ||
(size >= extent->e_start && size < extent->e_end)) {
objects = lod_comp->llc_stripe;
return dt_invalidate(env, dt_object_child(dt));
}
-/**
- * Resize per-thread ost list to hold OST target index list already used.
- *
- * \param[in,out] inuse structure contains ost list array
- * \param[in] cnt total stripe count of all components
- * \param[in] max array's max size if @max > 0
- *
- * \retval 0 on success
- * \retval -ENOMEM reallocation failed
- */
-int lod_inuse_resize(struct ost_pool *inuse, __u16 cnt, __u16 max)
-{
- __u32 *array;
- __u32 new = cnt * sizeof(__u32);
-
- inuse->op_count = 0;
-
- if (new <= inuse->op_size)
- return 0;
-
- if (max)
- new = min_t(__u32, new, max);
- OBD_ALLOC(array, new);
- if (!array)
- return -ENOMEM;
-
- if (inuse->op_array)
- OBD_FREE(inuse->op_array, inuse->op_size);
-
- inuse->op_array = array;
- inuse->op_size = new;
-
- return 0;
-}
-
static int lod_declare_layout_change(const struct lu_env *env,
struct dt_object *dt,
struct layout_intent *layout,
struct lod_object *lo = lod_dt_obj(dt);
struct lod_device *d = lu2lod_dev(dt->do_lu.lo_dev);
struct dt_object *next = dt_object_child(dt);
- struct lod_obj_stripe_cb_data data;
struct ost_pool *inuse = &info->lti_inuse_osts;
struct lod_layout_component *lod_comp;
struct lov_comp_md_v1 *comp_v1 = NULL;
bool replay = false;
bool need_create = false;
int i, rc;
- __u32 stripe_cnt = 0;
ENTRY;
if (!S_ISREG(dt->do_lu.lo_header->loh_attr) || !dt_object_exists(dt) ||
GOTO(out, rc);
/* Prepare inuse array for composite file */
- for (i = 0; i < lo->ldo_comp_cnt; i++)
- stripe_cnt += lod_comp_entry_stripecnt(lo,
- &lo->ldo_comp_entries[i],
- false);
- rc = lod_inuse_resize(inuse, stripe_cnt, d->lod_osd_max_easize);
- if (rc)
- GOTO(out, rc);
-
- data.locd_inuse = inuse;
- rc = lod_obj_for_each_stripe(env, lo, NULL,
- lod_obj_stripe_set_inuse_cb,
- &data);
+ rc = lod_prepare_inuse(env, lo);
if (rc)
GOTO(out, rc);
}
op->op_array = NULL;
op->op_count = 0;
init_rwsem(&op->op_rw_sem);
- op->op_size = count;
- OBD_ALLOC(op->op_array, op->op_size * sizeof(op->op_array[0]));
+ op->op_size = count * sizeof(op->op_array[0]);
+ OBD_ALLOC(op->op_array, op->op_size);
if (op->op_array == NULL) {
op->op_size = 0;
RETURN(-ENOMEM);
int lod_ost_pool_extend(struct ost_pool *op, unsigned int min_count)
{
__u32 *new;
- int new_size;
+ __u32 new_size;
LASSERT(min_count != 0);
- if (op->op_count < op->op_size)
+ if (op->op_count * sizeof(op->op_array[0]) < op->op_size)
return 0;
- new_size = max(min_count, 2 * op->op_size);
- OBD_ALLOC(new, new_size * sizeof(op->op_array[0]));
+ new_size = max_t(__u32, min_count * sizeof(op->op_array[0]),
+ 2 * op->op_size);
+ OBD_ALLOC(new, new_size);
if (new == NULL)
return -ENOMEM;
/* copy old array to new one */
- memcpy(new, op->op_array, op->op_size * sizeof(op->op_array[0]));
- OBD_FREE(op->op_array, op->op_size * sizeof(op->op_array[0]));
+ memcpy(new, op->op_array, op->op_size);
+ OBD_FREE(op->op_array, op->op_size);
op->op_array = new;
op->op_size = new_size;
down_write(&op->op_rw_sem);
- OBD_FREE(op->op_array, op->op_size * sizeof(op->op_array[0]));
+ OBD_FREE(op->op_array, op->op_size);
op->op_array = NULL;
op->op_count = 0;
op->op_size = 0;
if (inuse->op_size == 0)
return 0;
- LASSERT(inuse->op_count <= inuse->op_size);
+ LASSERT(inuse->op_count * sizeof(inuse->op_array[0]) <= inuse->op_size);
for (j = 0; j < inuse->op_count; j++) {
if (inuse->op_array[j] == ost)
return 1;
static inline void lod_comp_ost_in_use(struct ost_pool *inuse, int ost)
{
LASSERT(inuse != NULL);
- if (inuse->op_size && !lod_comp_is_ost_used(inuse, ost)) {
- LASSERT(inuse->op_count < inuse->op_size);
+ if (inuse->op_size && !lod_comp_is_ost_used(inuse, ost)) {
+ LASSERT(inuse->op_count * sizeof(inuse->op_array[0]) <
+ inuse->op_size);
inuse->op_array[inuse->op_count] = ost;
inuse->op_count++;
}
continue;
QOS_DEBUG("stripe=%d to idx=%d\n", nfound, idx);
-
/*
* do not put >1 objects on a single OST
*/
if (lod_qos_is_ost_used(env, idx, nfound) ||
lod_comp_is_ost_used(inuse, idx))
continue;
- lod_qos_ost_in_use(env, nfound, idx);
- lod_comp_ost_in_use(inuse, idx);
o = lod_qos_declare_object_on(env, lod, idx, th);
if (IS_ERR(o)) {
idx, (int) PTR_ERR(o));
continue;
}
+
+ lod_qos_ost_in_use(env, nfound, idx);
+ lod_comp_ost_in_use(inuse, idx);
stripe[nfound++] = o;
lod_qos_used(lod, osts, idx, &total_weight);
rc = 0;
return 0;
}
+/**
+ * Resize per-thread ost list to hold OST target index list already used.
+ *
+ * \param[in,out] inuse structure contains ost list array
+ * \param[in] cnt total stripe count of all components
+ * \param[in] max array's max size if @max > 0
+ *
+ * \retval 0 on success
+ * \retval -ENOMEM reallocation failed
+ */
+static int lod_inuse_resize(struct ost_pool *inuse, __u16 cnt, __u16 max)
+{
+ __u32 *array;
+ __u32 new = cnt * sizeof(inuse->op_array[0]);
+
+ inuse->op_count = 0;
+
+ if (new <= inuse->op_size)
+ return 0;
+
+ if (max)
+ new = min_t(__u32, new, max);
+
+ OBD_ALLOC(array, new);
+ if (!array)
+ return -ENOMEM;
+
+ if (inuse->op_array)
+ OBD_FREE(inuse->op_array, inuse->op_size);
+
+ inuse->op_array = array;
+ inuse->op_size = new;
+
+ return 0;
+}
+
+int lod_prepare_inuse(const struct lu_env *env, struct lod_object *lo)
+{
+ struct lod_thread_info *info = lod_env_info(env);
+ struct lod_device *d = lu2lod_dev(lod2lu_obj(lo)->lo_dev);
+ struct ost_pool *inuse = &info->lti_inuse_osts;
+ struct lod_obj_stripe_cb_data data;
+ __u32 stripe_cnt = 0;
+ int i;
+ int rc;
+
+ for (i = 0; i < lo->ldo_comp_cnt; i++)
+ stripe_cnt += lod_comp_entry_stripecnt(lo,
+ &lo->ldo_comp_entries[i], false);
+ rc = lod_inuse_resize(inuse, stripe_cnt, d->lod_osd_max_easize);
+ if (rc)
+ return rc;
+
+ data.locd_inuse = inuse;
+ return lod_obj_for_each_stripe(env, lo, NULL,
+ lod_obj_stripe_set_inuse_cb, &data);
+}
+
int lod_prepare_create(const struct lu_env *env, struct lod_object *lo,
struct lu_attr *attr, const struct lu_buf *buf,
struct thandle *th)
{
+ struct lod_thread_info *info = lod_env_info(env);
struct lod_device *d = lu2lod_dev(lod2lu_obj(lo)->lo_dev);
- struct ost_pool inuse = { 0 };
+ struct ost_pool inuse_osts = { 0 };
+ struct ost_pool *inuse = &inuse_osts;
+ uint64_t size = 0;
+ int i;
int rc;
ENTRY;
if (rc)
RETURN(rc);
- /* prepare OST object creation for the 1st comp. */
- rc = lod_qos_prep_create(env, lo, attr, th, 0, &inuse);
+ if (attr->la_valid & LA_SIZE)
+ size = attr->la_size;
+
+ /* only prepare inuse if multiple components to be created */
+ if (size && lo->ldo_is_composite) {
+ rc = lod_prepare_inuse(env, lo);
+ if (rc)
+ RETURN(rc);
+ inuse = &info->lti_inuse_osts;
+ }
+
+ /**
+ * prepare OST object creation for the component covering file's
+ * size, the 1st component (including plain layout file) is always
+ * instantiated.
+ */
+ for (i = 0; i < lo->ldo_comp_cnt; i++) {
+ struct lod_layout_component *lod_comp;
+ struct lu_extent *extent;
+
+ lod_comp = &lo->ldo_comp_entries[i];
+ extent = &lod_comp->llc_extent;
+ CDEBUG(D_QOS, "%lld [%lld, %lld)\n",
+ size, extent->e_start, extent->e_end);
+ if (!lo->ldo_is_composite || size >= extent->e_start) {
+ rc = lod_qos_prep_create(env, lo, attr, th, i, inuse);
+ if (rc)
+ break;
+ }
+ }
RETURN(rc);
}
})
#endif
-#define pool_tgt_size(p) ((p)->pool_obds.op_size)
#define pool_tgt_count(p) ((p)->pool_obds.op_count)
#define pool_tgt_array(p) ((p)->pool_obds.op_array)
#define pool_tgt_rw_sem(p) ((p)->pool_obds.op_rw_sem)
LASSERT(sub->sub_env == NULL);
ENTRY;
- if (unlikely(lov_r0(lov, index)->lo_sub[stripe] == NULL))
+ if (unlikely(!lov_r0(lov, index)->lo_sub ||
+ !lov_r0(lov, index)->lo_sub[stripe]))
RETURN(-EIO);
/* obtain new environment */
#define LOV_POOL_INIT_COUNT 2
int lov_ost_pool_init(struct ost_pool *op, unsigned int count)
{
- ENTRY;
+ ENTRY;
- if (count == 0)
- count = LOV_POOL_INIT_COUNT;
- op->op_array = NULL;
- op->op_count = 0;
+ if (count == 0)
+ count = LOV_POOL_INIT_COUNT;
+ op->op_array = NULL;
+ op->op_count = 0;
init_rwsem(&op->op_rw_sem);
- op->op_size = count;
- OBD_ALLOC(op->op_array, op->op_size * sizeof(op->op_array[0]));
- if (op->op_array == NULL) {
- op->op_size = 0;
- RETURN(-ENOMEM);
- }
- EXIT;
- return 0;
+ op->op_size = count * sizeof(op->op_array[0]);
+ OBD_ALLOC(op->op_array, op->op_size);
+ if (op->op_array == NULL) {
+ op->op_size = 0;
+ RETURN(-ENOMEM);
+ }
+ EXIT;
+ return 0;
}
/* Caller must hold write op_rwlock */
int lov_ost_pool_extend(struct ost_pool *op, unsigned int min_count)
{
- __u32 *new;
- int new_size;
-
- LASSERT(min_count != 0);
-
- if (op->op_count < op->op_size)
- return 0;
-
- new_size = max(min_count, 2 * op->op_size);
- OBD_ALLOC(new, new_size * sizeof(op->op_array[0]));
- if (new == NULL)
- return -ENOMEM;
-
- /* copy old array to new one */
- memcpy(new, op->op_array, op->op_size * sizeof(op->op_array[0]));
- OBD_FREE(op->op_array, op->op_size * sizeof(op->op_array[0]));
- op->op_array = new;
- op->op_size = new_size;
- return 0;
+ __u32 *new;
+ __u32 new_size;
+
+ LASSERT(min_count != 0);
+
+ if (op->op_count * sizeof(op->op_array[0]) < op->op_size)
+ return 0;
+
+ new_size = max_t(__u32, min_count * sizeof(op->op_array[0]),
+ 2 * op->op_size);
+ OBD_ALLOC(new, new_size);
+ if (new == NULL)
+ return -ENOMEM;
+
+ /* copy old array to new one */
+ memcpy(new, op->op_array, op->op_size);
+ OBD_FREE(op->op_array, op->op_size);
+ op->op_array = new;
+ op->op_size = new_size;
+ return 0;
}
int lov_ost_pool_add(struct ost_pool *op, __u32 idx, unsigned int min_count)
int lov_ost_pool_free(struct ost_pool *op)
{
- ENTRY;
+ ENTRY;
- if (op->op_size == 0)
- RETURN(0);
+ if (op->op_size == 0)
+ RETURN(0);
down_write(&op->op_rw_sem);
- OBD_FREE(op->op_array, op->op_size * sizeof(op->op_array[0]));
- op->op_array = NULL;
- op->op_count = 0;
- op->op_size = 0;
+ OBD_FREE(op->op_array, op->op_size);
+ op->op_array = NULL;
+ op->op_count = 0;
+ op->op_size = 0;
up_write(&op->op_rw_sem);
- RETURN(0);
+ RETURN(0);
}
__u64 size = io->u.ci_setattr.sa_attr.lvb_size;
unsigned int ia_valid = io->u.ci_setattr.sa_valid;
int result = 0;
+ ENTRY;
/* truncate cache dirty pages first */
if (cl_io_is_trunc(io))
cbargs->opc_rpc_sent = result == 0;
}
- return result;
+ RETURN(result);
}
static void osc_io_setattr_end(const struct lu_env *env,