From 062275772df6ba9027710048f2c1ee26e5574a51 Mon Sep 17 00:00:00 2001 From: Wang Di Date: Thu, 10 Jul 2014 01:57:45 -0700 Subject: [PATCH] LU-4691 lmv: honor MDT index when creating volatile file LMV should honor MDT index embedded in the name of volatile file, then during hsm restore, the file under striped dir can be restored to the right MDT. Add test 405 in sanity-hsm to verify it. Change-Id: I05170beee5255cf6581a2ea43edb6cc434a7cf8e Signed-off-by: Wang Di Reviewed-on: http://review.whamcloud.com/10866 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Henri Doreau Reviewed-by: Oleg Drokin --- lustre/include/lustre/lustre_user.h | 1 + lustre/include/lustre/lustreapi.h | 2 ++ lustre/llite/dir.c | 19 +++++++++++++- lustre/llite/llite_lib.c | 6 +++-- lustre/lmv/lmv_fld.c | 15 +++++------ lustre/lmv/lmv_internal.h | 5 ++++ lustre/lmv/lmv_obd.c | 47 +++++++++++++++++++++++++++++++--- lustre/tests/sanity-hsm.sh | 50 +++++++++++++++++++++++++++++++++++++ lustre/utils/lhsmtool_posix.c | 40 +++++++++++++++++++++++------ lustre/utils/liblustreapi.c | 14 +++++++++++ 10 files changed, 179 insertions(+), 20 deletions(-) diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index 8b612a3..10d1833 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -264,6 +264,7 @@ struct ost_id { #define LL_IOC_HSM_IMPORT _IOWR('f', 245, struct hsm_user_import) #define LL_IOC_LMV_SET_DEFAULT_STRIPE _IOWR('f', 246, struct lmv_user_md) #define LL_IOC_MIGRATE _IOR('f', 247, int) +#define LL_IOC_FID2MDTIDX _IOWR('f', 248, struct lu_fid) #define LL_STATFS_LMV 1 #define LL_STATFS_LOV 2 diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index 6362797..40dd522 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -271,6 +271,8 @@ extern int llapi_ls(int argc, char *argv[]); extern int llapi_fid2path(const char *device, const char *fidstr, char *path, int pathlen, long long *recno, int *linkno); extern int llapi_path2fid(const char *path, lustre_fid *fid); +extern int llapi_get_mdt_index_by_fid(int fd, const lustre_fid *fid, + int *mdt_index); extern int llapi_fd2fid(const int fd, lustre_fid *fid); extern int llapi_chomp_string(char *buf); diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 3fcaa6b..7a761b2 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -1650,8 +1650,25 @@ out_rmdir: rc = copy_and_ioctl(cmd, sbi->ll_md_exp, (void *)arg, sizeof(struct ioc_changelog)); RETURN(rc); - case OBD_IOC_FID2PATH: + case OBD_IOC_FID2PATH: RETURN(ll_fid2path(inode, (void *)arg)); + case LL_IOC_FID2MDTIDX: { + struct obd_export *exp = ll_i2mdexp(inode); + struct lu_fid fid; + __u32 index; + + if (copy_from_user(&fid, (const struct lu_fid __user *)arg, + sizeof(fid))) + RETURN(-EFAULT); + + /* Call mdc_iocontrol */ + rc = obd_iocontrol(LL_IOC_FID2MDTIDX, exp, sizeof(fid), &fid, + &index); + if (rc != 0) + RETURN(rc); + + RETURN(index); + } case LL_IOC_HSM_REQUEST: { struct hsm_user_request *hur; ssize_t totalsize; diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 7e49c90..6417d55 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -2586,9 +2586,11 @@ struct md_op_data * ll_prep_md_op_data(struct md_op_data *op_data, op_data->op_bias = 0; op_data->op_cli_flags = 0; if ((opc == LUSTRE_OPC_CREATE) && (name != NULL) && - filename_is_volatile(name, namelen, NULL)) + filename_is_volatile(name, namelen, &op_data->op_mds)) { op_data->op_bias |= MDS_CREATE_VOLATILE; - op_data->op_mds = 0; + } else { + op_data->op_mds = 0; + } op_data->op_data = data; /* When called by ll_setattr_raw, file is i1. */ diff --git a/lustre/lmv/lmv_fld.c b/lustre/lmv/lmv_fld.c index 9f97d75..80f37a3 100644 --- a/lustre/lmv/lmv_fld.c +++ b/lustre/lmv/lmv_fld.c @@ -53,19 +53,20 @@ #include #include "lmv_internal.h" -int lmv_fld_lookup(struct lmv_obd *lmv, - const struct lu_fid *fid, - mdsno_t *mds) +int lmv_fld_lookup(struct lmv_obd *lmv, const struct lu_fid *fid, + mdsno_t *mds) { + struct obd_device *obd = lmv2obd_dev(lmv); int rc; ENTRY; - /* FIXME: Currently ZFS still use local seq for ROOT unfortunately, and * this fid_is_local check should be removed once LU-2240 is fixed */ - LASSERTF((fid_seq_in_fldb(fid_seq(fid)) || - fid_seq_is_local_file(fid_seq(fid))) && - fid_is_sane(fid), DFID" is insane!\n", PFID(fid)); + if (!fid_is_sane(fid) || !(fid_seq_in_fldb(fid_seq(fid)) || + fid_seq_is_local_file(fid_seq(fid)))) { + CERROR("%s: invalid FID "DFID"\n", obd->obd_name, PFID(fid)); + RETURN(-EINVAL); + } rc = fld_client_lookup(&lmv->lmv_fld, fid_seq(fid), mds, LU_SEQ_RANGE_MDT, NULL); diff --git a/lustre/lmv/lmv_internal.h b/lustre/lmv/lmv_internal.h index 63b55bc..b6245b3 100644 --- a/lustre/lmv/lmv_internal.h +++ b/lustre/lmv/lmv_internal.h @@ -73,6 +73,11 @@ int lmv_revalidate_slaves(struct obd_export *exp, struct mdt_body *mbody, ldlm_blocking_callback cb_blocking, int extra_lock_flags); +static inline struct obd_device *lmv2obd_dev(struct lmv_obd *lmv) +{ + return container_of0(lmv, struct obd_device, u.lmv); +} + static inline struct lmv_tgt_desc * lmv_get_target(struct lmv_obd *lmv, mdsno_t mdt_idx, int *index) { diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index 745c215..3b4662a 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -1120,6 +1120,19 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp, rc = obd_iocontrol(cmd, tgt->ltd_exp, len, karg, uarg); break; } + case LL_IOC_FID2MDTIDX: { + struct lu_fid *fid = karg; + int mdt_index; + + rc = lmv_fld_lookup(lmv, fid, &mdt_index); + if (rc != 0) + RETURN(rc); + + /* Note: this is from llite(see ll_dir_ioctl()), @uarg does not + * point to user space memory for FID2MDTIDX. */ + *(__u32 *)uarg = mdt_index; + break; + } case OBD_IOC_FID2PATH: { rc = lmv_fid2path(exp, len, karg, uarg); break; @@ -1807,13 +1820,41 @@ lmv_locate_target_for_name(struct lmv_obd *lmv, struct lmv_stripe_md *lsm, * retval pointer to the lmv_tgt_desc if succeed. * ERR_PTR(errno) if failed. */ -struct lmv_tgt_desc -*lmv_locate_mds(struct lmv_obd *lmv, struct md_op_data *op_data, - struct lu_fid *fid) +struct lmv_tgt_desc* +lmv_locate_mds(struct lmv_obd *lmv, struct md_op_data *op_data, + struct lu_fid *fid) { struct lmv_stripe_md *lsm = op_data->op_mea1; struct lmv_tgt_desc *tgt; + /* During creating VOLATILE file, it should honor the mdt + * index if the file under striped dir is being restored, see + * ct_restore(). */ + if (op_data->op_bias & MDS_CREATE_VOLATILE && + (int)op_data->op_mds != -1 && lsm != NULL) { + int i; + tgt = lmv_get_target(lmv, op_data->op_mds, NULL); + if (IS_ERR(tgt)) + return tgt; + + /* refill the right parent fid */ + for (i = 0; i < lsm->lsm_md_stripe_count; i++) { + struct lmv_oinfo *oinfo; + + oinfo = &lsm->lsm_md_oinfo[i]; + if (oinfo->lmo_mds == op_data->op_mds) { + *fid = oinfo->lmo_fid; + break; + } + } + + /* Hmm, can not find the stripe by mdt_index(op_mds) */ + if (i == lsm->lsm_md_stripe_count) + tgt = ERR_PTR(-EINVAL); + + return tgt; + } + if (lsm == NULL || op_data->op_namelen == 0) { tgt = lmv_find_target(lmv, fid); if (IS_ERR(tgt)) diff --git a/lustre/tests/sanity-hsm.sh b/lustre/tests/sanity-hsm.sh index 954f195..aa7ac3b 100755 --- a/lustre/tests/sanity-hsm.sh +++ b/lustre/tests/sanity-hsm.sh @@ -4090,6 +4090,56 @@ test_404() { } run_test 404 "Inactive MDT does not block requests for active MDTs" +test_405() { + [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return + + copytool_setup + + mkdir -p $DIR/$tdir + + local striped_dir=$DIR/$tdir/striped_dir + + # create striped dir on all of MDTs + $LFS mkdir -i 0 -c $MDSCOUNT $striped_dir || error "lfs mkdir" + + local fid1=$(make_small_sync $striped_dir/${tfile}_0) + local fid2=$(make_small_sync $striped_dir/${tfile}_1) + local fid3=$(make_small_sync $striped_dir/${tfile}_2) + local fid4=$(make_small_sync $striped_dir/${tfile}_3) + + local idx1=$($LFS getstripe -M $striped_dir/${tfile}_0) + local idx2=$($LFS getstripe -M $striped_dir/${tfile}_1) + local idx3=$($LFS getstripe -M $striped_dir/${tfile}_2) + local idx4=$($LFS getstripe -M $striped_dir/${tfile}_3) + + # check that compound requests are shunt to the rights MDTs + $LFS hsm_archive $striped_dir/${tfile}_0 $striped_dir/${tfile}_1 \ + $striped_dir/${tfile}_2 $striped_dir/${tfile}_3 || + error "lfs hsm_archive" + + wait_request_state $fid1 ARCHIVE SUCCEED $idx1 && + echo "archive successful on $fid1" + wait_request_state $fid2 ARCHIVE SUCCEED $idx2 && + echo "archive successful on $fid2" + wait_request_state $fid3 ARCHIVE SUCCEED $idx3 && + echo "archive successful on $fid3" + wait_request_state $fid4 ARCHIVE SUCCEED $idx4 && + echo "archive successful on $fid4" + + $LFS hsm_release $striped_dir/${tfile}_0 || error "lfs hsm_release 1" + $LFS hsm_release $striped_dir/${tfile}_1 || error "lfs hsm_release 2" + $LFS hsm_release $striped_dir/${tfile}_2 || error "lfs hsm_release 3" + $LFS hsm_release $striped_dir/${tfile}_3 || error "lfs hsm_release 4" + + cat $striped_dir/${tfile}_0 > /dev/null || error "cat ${tfile}_0 failed" + cat $striped_dir/${tfile}_1 > /dev/null || error "cat ${tfile}_1 failed" + cat $striped_dir/${tfile}_2 > /dev/null || error "cat ${tfile}_2 failed" + cat $striped_dir/${tfile}_3 > /dev/null || error "cat ${tfile}_3 failed" + + copytool_cleanup +} +run_test 405 "archive and release under striped directory" + copytool_cleanup complete $SECONDS diff --git a/lustre/utils/lhsmtool_posix.c b/lustre/utils/lhsmtool_posix.c index ff157dc..dd85559 100644 --- a/lustre/utils/lhsmtool_posix.c +++ b/lustre/utils/lhsmtool_posix.c @@ -85,6 +85,7 @@ struct options { enum ct_action o_action; char *o_event_fifo; char *o_mnt; + int o_mnt_fd; char *o_hsm_root; char *o_src; /* for import, or rebind */ char *o_dst; /* for import, or rebind */ @@ -331,6 +332,7 @@ static int ct_parseopts(int argc, char * const *argv) } opt.o_mnt = argv[optind]; + opt.o_mnt_fd = -1; CT_TRACE("action=%d src=%s dst=%s mount_point=%s", opt.o_action, opt.o_src, opt.o_dst, opt.o_mnt); @@ -1084,7 +1086,7 @@ static int ct_restore(const struct hsm_action_item *hai, const long hal_flags) int hp_flags = 0; int src_fd = -1; int dst_fd = -1; - int mdt_index = -1; /* Not implemented */ + int mdt_index = -1; int open_flags = 0; bool set_lovea; struct lu_fid dfid; @@ -1096,6 +1098,13 @@ static int ct_restore(const struct hsm_action_item *hai, const long hal_flags) /* build backend file name from released file FID */ ct_path_archive(src, sizeof(src), opt.o_hsm_root, &hai->hai_fid); + rc = llapi_get_mdt_index_by_fid(opt.o_mnt_fd, &hai->hai_fid, + &mdt_index); + if (rc < 0) { + CT_ERROR(rc, "cannot get mdt index "DFID"", + PFID(&hai->hai_fid)); + return rc; + } /* restore loads and sets the LOVEA w/o interpreting it to avoid * dependency on the structure format. */ rc = ct_load_stripe(src, lov_buf, &lov_size); @@ -1861,6 +1870,14 @@ static int ct_setup(void) return rc; } + opt.o_mnt_fd = open(opt.o_mnt, O_RDONLY); + if (opt.o_mnt_fd < 0) { + rc = -errno; + CT_ERROR(rc, "cannot open mount point at '%s'", + opt.o_mnt); + return rc; + } + return rc; } @@ -1868,13 +1885,22 @@ static int ct_cleanup(void) { int rc; - if (arc_fd < 0) - return 0; + if (opt.o_mnt_fd >= 0) { + rc = close(opt.o_mnt_fd); + if (rc < 0) { + rc = -errno; + CT_ERROR(rc, "cannot close mount point"); + return rc; + } + } - if (close(arc_fd) < 0) { - rc = -errno; - CT_ERROR(rc, "cannot close archive root directory"); - return rc; + if (arc_fd >= 0) { + rc = close(arc_fd); + if (rc < 0) { + rc = -errno; + CT_ERROR(rc, "cannot close archive root directory"); + return rc; + } } return 0; diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 936ddc8..2ebdc58 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -4362,6 +4362,20 @@ static int fid_from_lma(const char *path, const int fd, lustre_fid *fid) return 0; } +int llapi_get_mdt_index_by_fid(int fd, const lustre_fid *fid, + int *mdt_index) +{ + int rc; + + rc = ioctl(fd, LL_IOC_FID2MDTIDX, fid); + if (rc < 0) + return -errno; + + *mdt_index = rc; + + return rc; +} + int llapi_fd2fid(const int fd, lustre_fid *fid) { int rc; -- 1.8.3.1