X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Flmv%2Flmv_obd.c;h=8278969d5133b302e6ab5bd04160d007cd048e41;hp=e785fd965e930f2d18e47aaa4a516b33ae4130c2;hb=a24f6153292753bf6e40f5638930d6cffa78e1ac;hpb=3bfb6107ba4e92d8aa02e842502bc44bac7b8b43;ds=sidebyside diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index e785fd9..8278969 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -212,6 +212,7 @@ static int lmv_connect(const struct lu_env *env, 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); @@ -310,7 +311,7 @@ int lmv_connect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt) } 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); @@ -659,6 +660,7 @@ repeat_fid2path: 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 + @@ -667,13 +669,12 @@ repeat_fid2path: 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", @@ -1175,15 +1176,23 @@ static int lmv_placement_policy(struct obd_device *obd, * 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; @@ -1373,8 +1382,11 @@ static int lmv_select_statfs_mdt(struct lmv_obd *lmv, __u32 flags) 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; } } @@ -1407,8 +1419,8 @@ static int lmv_statfs(const struct lu_env *env, struct obd_export *exp, 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); } @@ -1629,6 +1641,10 @@ lmv_locate_tgt(struct lmv_obd *lmv, struct md_op_data *op_data, 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(). */ @@ -2425,6 +2441,11 @@ static struct lu_dirent *stripe_dirent_load(struct lmv_dir_ctxt *ctxt, } 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); @@ -2692,6 +2713,10 @@ int lmv_read_page(struct obd_export *exp, struct md_op_data *op_data, 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); } @@ -2981,10 +3006,22 @@ static int lmv_unpack_md_v1(struct obd_export *exp, struct lmv_stripe_md *lsm, 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)); } @@ -3007,15 +3044,46 @@ static int lmv_unpackmd(struct obd_export *exp, struct lmv_stripe_md **lsmp, /* 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); @@ -3037,7 +3105,6 @@ static int lmv_unpackmd(struct obd_export *exp, struct lmv_stripe_md **lsmp, */ 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) @@ -3340,6 +3407,10 @@ static int lmv_merge_attr(struct obd_export *exp, 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; @@ -3347,12 +3418,15 @@ static int lmv_merge_attr(struct obd_export *exp, for (i = 0; i < lsm->lsm_md_stripe_count; i++) { struct inode *inode = lsm->lsm_md_oinfo[i].lmo_root; - CDEBUG(D_INFO, ""DFID" size %llu, blocks %llu nlink %u," - " atime %lu ctime %lu, mtime %lu.\n", + 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), i_size_read(inode), (unsigned long long)inode->i_blocks, - inode->i_nlink, LTIME_S(inode->i_atime), - LTIME_S(inode->i_ctime), LTIME_S(inode->i_mtime)); + inode->i_nlink, (s64)inode->i_atime.tv_sec, + (s64)inode->i_ctime.tv_sec, (s64)inode->i_mtime.tv_sec); /* for slave stripe, it needs to subtract nlink for . and .. */ if (i != 0) @@ -3363,14 +3437,14 @@ static int lmv_merge_attr(struct obd_export *exp, attr->cat_size += i_size_read(inode); attr->cat_blocks += inode->i_blocks; - if (attr->cat_atime < LTIME_S(inode->i_atime)) - attr->cat_atime = LTIME_S(inode->i_atime); + if (attr->cat_atime < inode->i_atime.tv_sec) + attr->cat_atime = inode->i_atime.tv_sec; - if (attr->cat_ctime < LTIME_S(inode->i_ctime)) - attr->cat_ctime = LTIME_S(inode->i_ctime); + if (attr->cat_ctime < inode->i_ctime.tv_sec) + attr->cat_ctime = inode->i_ctime.tv_sec; - if (attr->cat_mtime < LTIME_S(inode->i_mtime)) - attr->cat_mtime = LTIME_S(inode->i_mtime); + if (attr->cat_mtime < inode->i_mtime.tv_sec) + attr->cat_mtime = inode->i_mtime.tv_sec; } return 0; }