+static int lod_dir_declare_create_stripes(const struct lu_env *env,
+ struct dt_object *dt,
+ struct lu_attr *attr,
+ struct dt_object_format *dof,
+ struct thandle *th)
+{
+ struct lod_thread_info *info = lod_env_info(env);
+ struct lu_buf lmv_buf;
+ struct lu_buf slave_lmv_buf;
+ struct lmv_mds_md_v1 *lmm;
+ struct lmv_mds_md_v1 *slave_lmm = NULL;
+ struct dt_insert_rec *rec = &info->lti_dt_rec;
+ struct lod_object *lo = lod_dt_obj(dt);
+ int rc;
+ __u32 i;
+ ENTRY;
+
+ rc = lod_prep_lmv_md(env, dt, &lmv_buf);
+ if (rc != 0)
+ GOTO(out, rc);
+ lmm = lmv_buf.lb_buf;
+
+ OBD_ALLOC_PTR(slave_lmm);
+ if (slave_lmm == NULL)
+ GOTO(out, rc = -ENOMEM);
+
+ lod_prep_slave_lmv_md(slave_lmm, lmm);
+ slave_lmv_buf.lb_buf = slave_lmm;
+ slave_lmv_buf.lb_len = sizeof(*slave_lmm);
+
+ if (!dt_try_as_dir(env, dt_object_child(dt)))
+ GOTO(out, rc = -EINVAL);
+
+ rec->rec_type = S_IFDIR;
+ for (i = 0; i < lo->ldo_stripenr; i++) {
+ struct dt_object *dto = lo->ldo_stripe[i];
+ char *stripe_name = info->lti_key;
+ struct lu_name *sname;
+ struct linkea_data ldata = { NULL };
+ struct lu_buf linkea_buf;
+
+ rc = lod_sub_object_declare_create(env, dto, attr, NULL,
+ dof, th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ if (!dt_try_as_dir(env, dto))
+ GOTO(out, rc = -EINVAL);
+
+ rc = lod_sub_object_declare_ref_add(env, dto, th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ rec->rec_fid = lu_object_fid(&dto->do_lu);
+ rc = lod_sub_object_declare_insert(env, dto,
+ (const struct dt_rec *)rec,
+ (const struct dt_key *)dot, th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ /* master stripe FID will be put to .. */
+ rec->rec_fid = lu_object_fid(&dt->do_lu);
+ rc = lod_sub_object_declare_insert(env, dto,
+ (const struct dt_rec *)rec,
+ (const struct dt_key *)dotdot,
+ th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ if (!OBD_FAIL_CHECK(OBD_FAIL_LFSCK_LOST_SLAVE_LMV) ||
+ cfs_fail_val != i) {
+ if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_BAD_SLAVE_LMV) &&
+ cfs_fail_val == i)
+ slave_lmm->lmv_master_mdt_index =
+ cpu_to_le32(i + 1);
+ else
+ slave_lmm->lmv_master_mdt_index =
+ cpu_to_le32(i);
+ rc = lod_sub_object_declare_xattr_set(env, dto,
+ &slave_lmv_buf, XATTR_NAME_LMV, 0, th);
+ if (rc != 0)
+ GOTO(out, rc);
+ }
+
+ if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_BAD_SLAVE_NAME) &&
+ cfs_fail_val == i)
+ snprintf(stripe_name, sizeof(info->lti_key), DFID":%u",
+ PFID(lu_object_fid(&dto->do_lu)), i + 1);
+ else
+ snprintf(stripe_name, sizeof(info->lti_key), DFID":%u",
+ PFID(lu_object_fid(&dto->do_lu)), i);
+
+ sname = lod_name_get(env, stripe_name, strlen(stripe_name));
+ rc = linkea_links_new(&ldata, &info->lti_linkea_buf,
+ sname, lu_object_fid(&dt->do_lu));
+ if (rc != 0)
+ GOTO(out, rc);
+
+ linkea_buf.lb_buf = ldata.ld_buf->lb_buf;
+ linkea_buf.lb_len = ldata.ld_leh->leh_len;
+ rc = lod_sub_object_declare_xattr_set(env, dto, &linkea_buf,
+ XATTR_NAME_LINK, 0, th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ rec->rec_fid = lu_object_fid(&dto->do_lu);
+ rc = lod_sub_object_declare_insert(env, dt_object_child(dt),
+ (const struct dt_rec *)rec,
+ (const struct dt_key *)stripe_name,
+ th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ rc = lod_sub_object_declare_ref_add(env, dt_object_child(dt),
+ th);
+ if (rc != 0)
+ GOTO(out, rc);
+ }
+
+ rc = lod_sub_object_declare_xattr_set(env, dt_object_child(dt),
+ &lmv_buf, XATTR_NAME_LMV, 0, th);
+ if (rc != 0)
+ GOTO(out, rc);
+out:
+ if (slave_lmm != NULL)
+ OBD_FREE_PTR(slave_lmm);
+
+ RETURN(rc);
+}
+