#define ltd_mdt ltd_tgt
#define lod_mdt_desc lod_tgt_desc
+struct lod_layout_component {
+ struct lu_extent llc_extent;
+ __u32 llc_id;
+ __u32 llc_flags;
+ __u32 llc_stripe_size;
+ __u32 llc_pattern;
+ __u16 llc_layout_gen;
+ __u16 llc_stripe_offset;
+ __u16 llc_stripenr;
+ __u16 llc_stripes_allocated;
+ char *llc_pool;
+ struct dt_object **llc_stripe;
+};
+
struct lod_default_striping {
/* default LOV */
- __u32 lds_def_stripe_size;
- __u16 lds_def_stripenr;
- __u16 lds_def_stripe_offset;
- char lds_def_pool[LOV_MAXPOOLNAME + 1];
+ /* current layout component count */
+ __u16 lds_def_comp_cnt;
+ /* the largest comp count ever used */
+ __u32 lds_def_comp_size_cnt;
+ struct lod_layout_component *lds_def_comp_entries;
/* default LMV */
- __u32 lds_dir_def_stripenr;
- __u32 lds_dir_def_stripe_offset;
- __u32 lds_dir_def_hash_type;
- /* flags whether default striping is set */
- __u32 lds_def_striping_set:1,
- lds_dir_def_striping_set:1;
+ __u32 lds_dir_def_stripenr;
+ __u32 lds_dir_def_stripe_offset;
+ __u32 lds_dir_def_hash_type;
+ /* default file striping flags (LOV) */
+ __u32 lds_def_striping_set:1,
+ lds_def_striping_is_composite:1,
+ /* default dir striping flags (LMV) */
+ lds_dir_def_striping_set:1;
};
struct lod_object {
- struct dt_object ldo_obj;
+ struct dt_object ldo_obj;
union {
- /* file stripe */
+ /* file stripe (LOV) */
struct {
- /*
- * don't change field order, because both file and
- * directory use ldo_stripenr/ldo_stripes_allocated
- * to access stripe number.
- */
- __u16 ldo_stripenr;
- __u16 ldo_stripes_allocated;
- __u16 ldo_layout_gen;
- __u16 ldo_released_stripenr;
- __u32 ldo_pattern;
- __u32 ldo_stripe_size;
- __u16 ldo_stripe_offset;
- char *ldo_pool;
+ __u32 ldo_layout_gen;
+ /* Layout component count for a regular file.
+ * It equals to 1 for non-composite layout. */
+ __u16 ldo_comp_cnt;
+ __u32 ldo_is_composite:1,
+ ldo_comp_cached:1;
};
- /* directory stripe */
+ /* directory stripe (LMV) */
struct {
- __u16 ldo_dir_stripenr;
- __u16 ldo_dir_stripes_allocated;
- __u32 ldo_dir_stripe_offset;
- __u32 ldo_dir_hash_type;
- __u32 ldo_dir_slave_stripe:1,
- ldo_dir_striped:1;
+ /* Slave stripe count for striped directory. */
+ __u16 ldo_dir_stripenr;
+ /* How many stripes allocated for a striped directory */
+ __u16 ldo_dir_stripes_allocated;
+ __u32 ldo_dir_stripe_offset;
+ __u32 ldo_dir_hash_type;
+ /* Is a slave stripe of striped directory? */
+ __u32 ldo_dir_slave_stripe:1,
+ ldo_dir_striped:1;
/*
* default striping is not cached, so this field is
* invalid after create, make sure it's used by
* lod_dir_striping_create_internal() only.
*/
- struct lod_default_striping *ldo_def_striping;
+ struct lod_default_striping *ldo_def_striping;
};
};
- struct dt_object **ldo_stripe;
+ /* file stripe (LOV) */
+ struct lod_layout_component *ldo_comp_entries;
+ /* slave stripes of striped directory (LMV)*/
+ struct dt_object **ldo_stripe;
};
-static inline int lod_object_set_pool(struct lod_object *lo, const char *pool)
+static inline int lod_set_pool(char **pool, const char *new_pool)
{
int len;
- if (lo->ldo_pool != NULL) {
- len = strlen(lo->ldo_pool) + 1;
- OBD_FREE(lo->ldo_pool, len);
- lo->ldo_pool = NULL;
+ if (*pool == new_pool)
+ return 0;
+
+ if (*pool != NULL) {
+ len = strlen(*pool) + 1;
+ OBD_FREE(*pool, len);
+ *pool = NULL;
}
- if (pool != NULL) {
- len = strlen(pool) + 1;
- OBD_ALLOC(lo->ldo_pool, len);
- if (lo->ldo_pool == NULL)
+ if (new_pool != NULL) {
+ len = strlen(new_pool) + 1;
+ OBD_ALLOC(*pool, len);
+ if (*pool == NULL)
return -ENOMEM;
- strlcpy(lo->ldo_pool, pool, len);
+ strlcpy(*pool, new_pool, len);
}
return 0;
}
+static inline int lod_set_def_pool(struct lod_default_striping *lds,
+ int i, const char *new_pool)
+{
+ return lod_set_pool(&lds->lds_def_comp_entries[i].llc_pool,
+ new_pool);
+}
+
+static inline int lod_obj_set_pool(struct lod_object *lo, int i,
+ const char *new_pool)
+{
+ return lod_set_pool(&lo->ldo_comp_entries[i].llc_pool,
+ new_pool);
+}
+
+/*
+ * Layout generation is used to generate unique component ID, to check ID
+ * collision, we preserve the highest bit of the layout generation when it
+ * wrapped.
+ */
+static inline void lod_obj_inc_layout_gen(struct lod_object *lo)
+{
+ __u32 preserve = lo->ldo_layout_gen & LCME_ID_NONE;
+ lo->ldo_layout_gen++;
+ lo->ldo_layout_gen |= preserve;
+ /* Zero is not a valid component ID */
+ if (unlikely((lo->ldo_layout_gen & LCME_ID_MASK) == 0))
+ lo->ldo_layout_gen++;
+}
+
struct lod_it {
struct dt_object *lit_obj; /* object from the layer below */
/* stripe offset of iteration */
struct dt_object, do_lu);
}
+static inline bool lod_obj_is_striped(struct dt_object *dt)
+{
+ struct lod_object *lo = lod_dt_obj(dt);
+ int i;
+
+ if (!dt_object_exists(dt_object_child(dt)))
+ return false;
+
+ if (S_ISDIR(dt->do_lu.lo_header->loh_attr))
+ return lo->ldo_dir_stripenr != 0;
+
+ for (i = 0; i < lo->ldo_comp_cnt; i++) {
+ if (lo->ldo_comp_entries[i].llc_stripe == NULL)
+ continue;
+ LASSERT(lo->ldo_comp_entries[i].llc_stripenr > 0);
+ return true;
+ }
+ return false;
+}
+
extern struct lu_context_key lod_thread_key;
static inline struct lod_thread_info *lod_env_info(const struct lu_env *env)
int lod_parse_dir_striping(const struct lu_env *env, struct lod_object *lo,
const struct lu_buf *buf);
int lod_initialize_objects(const struct lu_env *env, struct lod_object *mo,
- struct lov_ost_data_v1 *objs);
+ struct lov_ost_data_v1 *objs, int index);
int lod_verify_striping(struct lod_device *d, const struct lu_buf *buf,
- bool is_from_disk);
-int lod_generate_and_set_lovea(const struct lu_env *env,
- struct lod_object *mo, struct thandle *th);
+ bool is_from_disk, __u64 start);
+int lod_generate_lovea(const struct lu_env *env, struct lod_object *lo,
+ struct lov_mds_md *lmm, int *lmm_size, bool is_dir);
int lod_ea_store_resize(struct lod_thread_info *info, size_t size);
+int lod_def_striping_comp_resize(struct lod_default_striping *lds, __u16 count);
+void lod_free_def_comp_entries(struct lod_default_striping *lds);
+void lod_free_comp_entries(struct lod_object *lo);
+int lod_alloc_comp_entries(struct lod_object *lo, int cnt);
+
/* lod_pool.c */
int lod_ost_pool_add(struct ost_pool *op, __u32 idx, unsigned int min_count);
int lod_ost_pool_remove(struct ost_pool *op, __u32 idx);
int lod_pool_remove(struct obd_device *obd, char *poolname, char *ostname);
/* lod_qos.c */
-int lod_qos_prep_create(const struct lu_env *env, struct lod_object *lo,
- struct lu_attr *attr, const struct lu_buf *buf,
- struct thandle *th);
+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);
int qos_add_tgt(struct lod_device*, struct lod_tgt_desc *);
int qos_del_tgt(struct lod_device *, struct lod_tgt_desc *);
void lod_qos_rr_init(struct lod_qos_rr *lqr);
+int lod_use_defined_striping(const struct lu_env *, struct lod_object *,
+ const struct lu_buf *);
/* lproc_lod.c */
int lod_procfs_init(struct lod_device *lod);
struct thandle *th);
void lod_object_free_striping(const struct lu_env *env, struct lod_object *lo);
+struct lod_obj_stripe_cb_data {
+ union {
+ const struct lu_attr *locd_attr;
+ struct ost_pool *locd_inuse;
+ };
+ bool locd_declare;
+};
+
+typedef int (*lod_obj_stripe_cb_t)(const struct lu_env *env,
+ struct lod_object *lo, struct dt_object *dt,
+ struct thandle *th, int stripe_idx,
+ struct lod_obj_stripe_cb_data *data);
+
+int lod_obj_for_each_stripe(const struct lu_env *env, struct lod_object *lo,
+ struct thandle *th, lod_obj_stripe_cb_t cb,
+ struct lod_obj_stripe_cb_data *data);
+
/* lod_sub_object.c */
struct thandle *lod_sub_get_thandle(const struct lu_env *env,
struct thandle *th,