RETURN(0);
}
+/*
+ * generate and write LOV EA for given striped object
+ */
+int lod_generate_and_set_lovea(const struct lu_env *env,
+ struct lod_object *lo, struct thandle *th)
+{
+ struct lod_thread_info *info = lod_env_info(env);
+ struct dt_object *next = dt_object_child(&lo->ldo_obj);
+ const struct lu_fid *fid = lu_object_fid(&lo->ldo_obj.do_lu);
+ struct lov_mds_md_v1 *lmm;
+ struct lov_ost_data_v1 *objs;
+ __u32 magic;
+ int i, rc, lmm_size;
+ ENTRY;
+
+ LASSERT(lo);
+ LASSERT(lo->ldo_stripenr > 0);
+
+ magic = lo->ldo_pool ? LOV_MAGIC_V3 : LOV_MAGIC_V1;
+ lmm_size = lov_mds_md_size(lo->ldo_stripenr, magic);
+ if (info->lti_ea_store_size < lmm_size) {
+ rc = lod_ea_store_resize(info, lmm_size);
+ if (rc)
+ RETURN(rc);
+ }
+
+ lmm = info->lti_ea_store;
+
+ lmm->lmm_magic = cpu_to_le32(magic);
+ lmm->lmm_pattern = cpu_to_le32(LOV_PATTERN_RAID0);
+ lmm->lmm_object_id = cpu_to_le64(fid_ver_oid(fid));
+ lmm->lmm_object_seq = cpu_to_le64(fid_seq(fid));
+ lmm->lmm_stripe_size = cpu_to_le32(lo->ldo_stripe_size);
+ lmm->lmm_stripe_count = cpu_to_le16(lo->ldo_stripenr);
+ lmm->lmm_layout_gen = 0;
+ if (magic == LOV_MAGIC_V1) {
+ objs = &lmm->lmm_objects[0];
+ } else {
+ struct lov_mds_md_v3 *v3 = (struct lov_mds_md_v3 *) lmm;
+ strncpy(v3->lmm_pool_name, lo->ldo_pool, LOV_MAXPOOLNAME);
+ objs = &v3->lmm_objects[0];
+ }
+
+ for (i = 0; i < lo->ldo_stripenr; i++) {
+ const struct lu_fid *fid;
+
+ LASSERT(lo->ldo_stripe[i]);
+ fid = lu_object_fid(&lo->ldo_stripe[i]->do_lu);
+
+ rc = fid_ostid_pack(fid, &info->lti_ostid);
+ LASSERT(rc == 0);
+ LASSERT(info->lti_ostid.oi_seq == FID_SEQ_OST_MDT0);
+
+ objs[i].l_object_id = cpu_to_le64(info->lti_ostid.oi_id);
+ objs[i].l_object_seq = cpu_to_le64(info->lti_ostid.oi_seq);
+ objs[i].l_ost_gen = cpu_to_le32(1);
+ objs[i].l_ost_idx = cpu_to_le32(fid_idif_ost_idx(fid));
+ }
+
+ info->lti_buf.lb_buf = lmm;
+ info->lti_buf.lb_len = lmm_size;
+ rc = dt_xattr_set(env, next, &info->lti_buf, XATTR_NAME_LOV, 0,
+ th, BYPASS_CAPA);
+
+ RETURN(rc);
+}
+
int lod_get_lov_ea(const struct lu_env *env, struct lod_object *lo)
{
struct lod_thread_info *info = lod_env_info(env);
struct thandle *th)
{
struct dt_object *next = dt_object_child(dt);
+ struct lu_attr *attr = &lod_env_info(env)->lti_attr;
+ __u32 mode;
int rc;
ENTRY;
+ /*
+ * allow to declare predefined striping on a new (!mode) object
+ * which is supposed to be replay of regular file creation
+ * (when LOV setting is declared)
+ */
+ mode = dt->do_lu.lo_header->loh_attr & S_IFMT;
+ if ((S_ISREG(mode) || !mode) && !strcmp(name, XATTR_NAME_LOV)) {
+ /*
+ * this is a request to manipulate object's striping
+ */
+ if (dt_object_exists(dt)) {
+ rc = dt_attr_get(env, next, attr, BYPASS_CAPA);
+ if (rc)
+ RETURN(rc);
+ } else {
+ memset(attr, 0, sizeof(attr));
+ attr->la_valid = LA_TYPE | LA_MODE;
+ attr->la_mode = S_IFREG;
+ }
+ rc = lod_declare_striped_object(env, dt, attr, buf, th);
+ if (rc)
+ RETURN(rc);
+ }
+
rc = dt_declare_xattr_set(env, next, buf, name, fl, th);
RETURN(rc);
else
rc = dt_xattr_set(env, next, buf, name, fl, th, capa);
+ } else if (S_ISREG(attr) && !strcmp(name, XATTR_NAME_LOV)) {
+ /*
+ * XXX: check striping match what we already have
+ * during req replay, declare_xattr_set() defines striping,
+ * then create() does the work
+ */
+ rc = lod_striping_create(env, dt, NULL, NULL, th);
+ RETURN(rc);
} else {
/*
* behave transparantly for all other EAs
EXIT;
}
+/**
+ * Create declaration of striped object
+ */
+int lod_declare_striped_object(const struct lu_env *env, struct dt_object *dt,
+ struct lu_attr *attr,
+ const struct lu_buf *lovea, struct thandle *th)
+{
+ struct lod_thread_info *info = lod_env_info(env);
+ struct dt_object *next = dt_object_child(dt);
+ struct lod_object *lo = lod_dt_obj(dt);
+ int rc;
+ ENTRY;
+
+ if (OBD_FAIL_CHECK(OBD_FAIL_MDS_ALLOC_OBDO)) {
+ /* failed to create striping, let's reset
+ * config so that others don't get confused */
+ lod_object_free_striping(env, lo);
+ GOTO(out, rc = -ENOMEM);
+ }
+
+ /* XXX: there will be a call to QoS here */
+ RETURN(0);
+
+ /*
+ * declare storage for striping data
+ */
+ info->lti_buf.lb_len = lov_mds_md_size(lo->ldo_stripenr,
+ lo->ldo_pool ? LOV_MAGIC_V3 : LOV_MAGIC_V1);
+ rc = dt_declare_xattr_set(env, next, &info->lti_buf, XATTR_NAME_LOV,
+ 0, th);
+ if (rc)
+ GOTO(out, rc);
+
+out:
+ RETURN(rc);
+}
+
static int lod_declare_object_create(const struct lu_env *env,
struct dt_object *dt,
struct lu_attr *attr,
if (dof->dof_type == DFT_SYM)
dt->do_body_ops = &lod_body_lnk_ops;
- if (dof->dof_type == DFT_DIR && lo->ldo_striping_cached) {
+ /*
+ * it's lod_ah_init() who has decided the object will striped
+ */
+ if (dof->dof_type == DFT_REGULAR) {
+ /* callers don't want stripes */
+ /* XXX: all tricky interactions with ->ah_make_hint() decided
+ * to use striping, then ->declare_create() behaving differently
+ * should be cleaned */
+ if (dof->u.dof_reg.striped == 0)
+ lo->ldo_stripenr = 0;
+ if (lo->ldo_stripenr > 0)
+ rc = lod_declare_striped_object(env, dt, attr,
+ NULL, th);
+ } else if (dof->dof_type == DFT_DIR && lo->ldo_striping_cached) {
struct lod_thread_info *info = lod_env_info(env);
info->lti_buf.lb_buf = NULL;
RETURN(rc);
}
+int lod_striping_create(const struct lu_env *env, struct dt_object *dt,
+ struct lu_attr *attr, struct dt_object_format *dof,
+ struct thandle *th)
+{
+ struct lod_object *lo = lod_dt_obj(dt);
+ int rc = 0, i;
+ ENTRY;
+
+ LASSERT(lo->ldo_stripe);
+ LASSERT(lo->ldo_stripe > 0);
+ LASSERT(lo->ldo_striping_cached == 0);
+
+ /* create all underlying objects */
+ for (i = 0; i < lo->ldo_stripenr; i++) {
+ LASSERT(lo->ldo_stripe[i]);
+ rc = dt_create(env, lo->ldo_stripe[i], attr, NULL, dof, th);
+
+ if (rc)
+ break;
+ }
+ if (rc == 0)
+ rc = lod_generate_and_set_lovea(env, lo, th);
+
+ RETURN(rc);
+}
+
static int lod_object_create(const struct lu_env *env, struct dt_object *dt,
struct lu_attr *attr,
struct dt_allocation_hint *hint,
struct dt_object_format *dof, struct thandle *th)
{
struct dt_object *next = dt_object_child(dt);
+ struct lod_object *lo = lod_dt_obj(dt);
int rc;
ENTRY;
if (rc == 0) {
if (S_ISDIR(dt->do_lu.lo_header->loh_attr))
rc = lod_store_def_striping(env, dt, th);
+ else if (lo->ldo_stripe)
+ rc = lod_striping_create(env, dt, attr, dof, th);
}
RETURN(rc);