* 1. See if the stripe offset is specified by lum.
* 2. Then check if there is default stripe offset.
* 3. Finally choose MDS by name hash if the parent
- * is striped directory. (see lmv_locate_tgt()). */
+ * is striped directory. (see lmv_locate_tgt()).
+ *
+ * presently explicit MDT location is not supported
+ * for foreign dirs (as it can't be embedded into free
+ * format LMV, like with lum_stripe_offset), so we only
+ * rely on default stripe offset or then name hashing.
+ */
if (op_data->op_cli_flags & CLI_SET_MEA && lum != NULL &&
+ le32_to_cpu(lum->lum_magic != LMV_MAGIC_FOREIGN) &&
le32_to_cpu(lum->lum_stripe_offset) != (__u32)-1) {
*mds = le32_to_cpu(lum->lum_stripe_offset);
} else if (op_data->op_default_stripe_offset != (__u32)-1) {
*mds = op_data->op_default_stripe_offset;
op_data->op_mds = *mds;
/* Correct the stripe offset in lum */
- if (lum != NULL)
+ if (lum != NULL &&
+ le32_to_cpu(lum->lum_magic != LMV_MAGIC_FOREIGN))
lum->lum_stripe_offset = cpu_to_le32(*mds);
} else {
*mds = op_data->op_mds;
struct lmv_oinfo *oinfo;
struct lmv_tgt_desc *tgt;
+ /* foreign dir is not striped dir */
+ if (lsm && lsm->lsm_md_magic == LMV_MAGIC_FOREIGN)
+ return ERR_PTR(-ENODATA);
+
/* During creating VOLATILE file, it should honor the mdt
* index if the file under striped dir is being restored, see
* ct_restore(). */
ENTRY;
if (unlikely(lsm != NULL)) {
+ /* foreign dir is not striped dir */
+ if (lsm->lsm_md_magic == LMV_MAGIC_FOREIGN)
+ return -ENODATA;
+
rc = lmv_striped_read_page(exp, op_data, cb_op, offset, ppage);
RETURN(rc);
}
/* Free memmd */
if (lsm != NULL && lmm == NULL) {
int i;
+ struct lmv_foreign_md *lfm = (struct lmv_foreign_md *)lsm;
+
+ if (lfm->lfm_magic == LMV_MAGIC_FOREIGN) {
+ size_t lfm_size;
+
+ lfm_size = lfm->lfm_length + offsetof(typeof(*lfm),
+ lfm_value[0]);
+ OBD_FREE_LARGE(lfm, lfm_size);
+ RETURN(0);
+ }
for (i = 0; i < lsm->lsm_md_stripe_count; i++)
iput(lsm->lsm_md_oinfo[i].lmo_root);
RETURN(0);
}
+ /* foreign lmv case */
+ if (le32_to_cpu(lmm->lmv_magic) == LMV_MAGIC_FOREIGN) {
+ struct lmv_foreign_md *lfm = (struct lmv_foreign_md *)lsm;
+
+ if (lfm == NULL) {
+ OBD_ALLOC_LARGE(lfm, lmm_size);
+ if (lfm == NULL)
+ RETURN(-ENOMEM);
+ *lsmp = (struct lmv_stripe_md *)lfm;
+ }
+ lfm->lfm_magic = le32_to_cpu(lmm->lmv_foreign_md.lfm_magic);
+ lfm->lfm_length = le32_to_cpu(lmm->lmv_foreign_md.lfm_length);
+ lfm->lfm_type = le32_to_cpu(lmm->lmv_foreign_md.lfm_type);
+ lfm->lfm_flags = le32_to_cpu(lmm->lmv_foreign_md.lfm_flags);
+ memcpy(&lfm->lfm_value, &lmm->lmv_foreign_md.lfm_value,
+ lfm->lfm_length);
+ RETURN(lmm_size);
+ }
+
if (le32_to_cpu(lmm->lmv_magic) == LMV_MAGIC_STRIPE)
RETURN(-EPERM);
int rc;
int i;
+ /* foreign dir is not striped dir */
+ if (lsm->lsm_md_magic == LMV_MAGIC_FOREIGN)
+ return 0;
+
rc = lmv_revalidate_slaves(exp, lsm, cb_blocking, 0);
if (rc < 0)
return rc;