lmv->connected = 0;
lmv->conn_data = *data;
+ lmv->lmv_cache = localdata;
lmv->lmv_tgts_kobj = kobject_create_and_add("target_obds",
&obd->obd_kset.kobj);
}
rc = obd_connect(NULL, &mdc_exp, mdc_obd, &obd->obd_uuid,
- &lmv->conn_data, NULL);
+ &lmv->conn_data, lmv->lmv_cache);
if (rc) {
CERROR("target %s connect error %d\n", tgt->ltd_uuid.uuid, rc);
RETURN(rc);
if (remote_gf != NULL) {
struct getinfo_fid2path *ori_gf;
char *ptr;
+ int len;
ori_gf = (struct getinfo_fid2path *)karg;
if (strlen(ori_gf->gf_u.gf_path) + 1 +
ptr = ori_gf->gf_u.gf_path;
- memmove(ptr + strlen(gf->gf_u.gf_path) + 1, ptr,
- strlen(ori_gf->gf_u.gf_path));
-
- strncpy(ptr, gf->gf_u.gf_path,
- strlen(gf->gf_u.gf_path));
- ptr += strlen(gf->gf_u.gf_path);
- *ptr = '/';
+ len = strlen(gf->gf_u.gf_path);
+ /* move the current path to the right to release space
+ * for closer-to-root part */
+ memmove(ptr + len + 1, ptr, strlen(ori_gf->gf_u.gf_path));
+ memcpy(ptr, gf->gf_u.gf_path, len);
+ ptr[len] = '/';
}
CDEBUG(D_INFO, "%s: get path %s "DFID" rec: %llu ln: %u\n",
* 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;
break;
if (LNET_NETTYP(LNET_NIDNET(lnet_id.nid)) != LOLND) {
+ /* We dont need a full 64-bit modulus, just enough
+ * to distribute the requests across MDTs evenly.
+ */
lmv->lmv_statfs_start =
- lnet_id.nid % lmv->desc.ld_tgt_count;
+ (u32)lnet_id.nid % lmv->desc.ld_tgt_count;
break;
}
}
rc = obd_statfs(env, lmv->tgts[idx]->ltd_exp, temp,
max_age, flags);
if (rc) {
- CERROR("can't stat MDS #%d (%s), error %d\n", i,
- lmv->tgts[idx]->ltd_exp->exp_obd->obd_name,
+ CERROR("%s: can't stat MDS #%d: rc = %d\n",
+ lmv->tgts[idx]->ltd_exp->exp_obd->obd_name, i,
rc);
GOTO(out_free_temp, rc);
}
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(). */
}
oinfo = &op_data->op_mea1->lsm_md_oinfo[stripe_index];
+ if (!oinfo->lmo_root) {
+ rc = -ENOENT;
+ break;
+ }
+
tgt = lmv_get_target(ctxt->ldc_lmv, oinfo->lmo_mds, NULL);
if (IS_ERR(tgt)) {
rc = PTR_ERR(tgt);
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);
}
for (i = 0; i < stripe_count; i++) {
fid_le_to_cpu(&lsm->lsm_md_oinfo[i].lmo_fid,
&lmm1->lmv_stripe_fids[i]);
+ /*
+ * set default value -1, so lmv_locate_tgt() knows this stripe
+ * target is not initialized.
+ */
+ lsm->lsm_md_oinfo[i].lmo_mds = (u32)-1;
+ if (!fid_is_sane(&lsm->lsm_md_oinfo[i].lmo_fid))
+ continue;
+
rc = lmv_fld_lookup(lmv, &lsm->lsm_md_oinfo[i].lmo_fid,
&lsm->lsm_md_oinfo[i].lmo_mds);
- if (rc != 0)
+ if (rc == -ENOENT)
+ continue;
+
+ if (rc)
RETURN(rc);
+
CDEBUG(D_INFO, "unpack fid #%d "DFID"\n", i,
PFID(&lsm->lsm_md_oinfo[i].lmo_fid));
}
/* 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);
+ for (i = 0; i < lsm->lsm_md_stripe_count; i++) {
+ if (lsm->lsm_md_oinfo[i].lmo_root)
+ iput(lsm->lsm_md_oinfo[i].lmo_root);
+ }
lsm_size = lmv_stripe_md_size(lsm->lsm_md_stripe_count);
OBD_FREE(lsm, lsm_size);
*lsmp = NULL;
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);
*/
lsm_size = lmv_stripe_md_size(0);
- lsm_size = lmv_stripe_md_size(lmv_mds_md_stripe_count_get(lmm));
if (lsm == NULL) {
OBD_ALLOC(lsm, lsm_size);
if (lsm == NULL)
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;
for (i = 0; i < lsm->lsm_md_stripe_count; i++) {
struct inode *inode = lsm->lsm_md_oinfo[i].lmo_root;
+ if (!inode)
+ continue;
+
CDEBUG(D_INFO,
"" DFID " size %llu, blocks %llu nlink %u, atime %lld ctime %lld, mtime %lld.\n",
PFID(&lsm->lsm_md_oinfo[i].lmo_fid),