lname, ldata, handle);
if (rc != 0)
GOTO(stop_trans, rc);
+
+ /* linkea update might decrease the source object
+ * nlink, let's get the attr again after ref_del */
+ rc = mdd_la_get(env, mdd_sobj, so_attr);
+ if (rc != 0)
+ GOTO(stop_trans, rc);
}
if (S_ISREG(so_attr->la_mode)) {
RETURN(rc);
}
+static int mdd_fld_lookup(const struct lu_env *env, struct mdd_device *mdd,
+ const struct lu_fid *fid, __u32 *mdt_index)
+{
+ struct lu_seq_range *range = &mdd_env_info(env)->mti_range;
+ struct seq_server_site *ss;
+ int rc;
+
+ ss = mdd->mdd_md_dev.md_lu_dev.ld_site->ld_seq_site;
+
+ range->lsr_flags = LU_SEQ_RANGE_MDT;
+ rc = fld_server_lookup(env, ss->ss_server_fld, fid->f_seq, range);
+ if (rc != 0)
+ return rc;
+
+ *mdt_index = range->lsr_index;
+
+ return 0;
+}
/**
* Check whether we should migrate the file/dir
* return val
{
struct mdd_thread_info *info = mdd_env_info(env);
struct linkea_data *ldata = &info->mti_link_data;
+ struct mdd_device *mdd = mdo2mdd(&pobj->mod_obj);
int mgr_easize;
struct lu_buf *mgr_buf;
int count;
int rc;
-
+ __u64 mdt_index;
ENTRY;
mgr_easize = lmv_mds_md_size(2, LMV_MAGIC_V1);
RETURN(rc);
}
+ mdt_index = mdd->mdd_md_dev.md_lu_dev.ld_site->ld_seq_site->ss_node_id;
/* If there are still links locally, then the file will not be
* migrated. */
LASSERT(ldata->ld_leh != NULL);
ldata->ld_lee = (struct link_ea_entry *)(ldata->ld_leh + 1);
for (count = 0; count < ldata->ld_leh->leh_reccount; count++) {
- struct mdd_device *mdd = mdo2mdd(&sobj->mod_obj);
- struct mdd_object *lpobj;
struct lu_name lname;
struct lu_fid fid;
+ __u32 parent_mdt_index;
linkea_entry_unpack(ldata->ld_lee, &ldata->ld_reclen,
&lname, &fid);
ldata->ld_lee = (struct link_ea_entry *)((char *)ldata->ld_lee +
ldata->ld_reclen);
- lpobj = mdd_object_find(env, mdd, &fid);
- if (IS_ERR(lpobj)) {
- CWARN("%s: cannot find obj "DFID": rc = %ld\n",
- mdd2obd_dev(mdd)->obd_name, PFID(&fid),
- PTR_ERR(lpobj));
- continue;
- }
- if (!mdd_object_exists(lpobj) || mdd_object_remote(lpobj)) {
- CDEBUG(D_INFO, DFID"%.*s: is on remote MDT.\n",
- PFID(&fid), lname.ln_namelen, lname.ln_name);
- mdd_object_put(env, lpobj);
+ rc = mdd_fld_lookup(env, mdd, &fid, &parent_mdt_index);
+ if (rc != 0)
+ RETURN(rc);
+
+ /* Migrate the object only if none of its parents are on the
+ * current MDT. */
+ if (parent_mdt_index != mdt_index)
continue;
- }
CDEBUG(D_INFO, DFID"still has local entry %.*s "DFID"\n",
PFID(mdd_object_fid(sobj)), lname.ln_namelen,
lname.ln_name, PFID(&fid));
- mdd_object_put(env, lpobj);
rc = 1;
break;
}
struct mdd_object *mdd_pobj = md2mdd_obj(pobj);
struct mdd_device *mdd = mdo2mdd(pobj);
struct mdd_object *mdd_sobj = md2mdd_obj(sobj);
- struct mdd_object *mdd_tobj = NULL;
+ struct mdd_object *mdd_tobj = md2mdd_obj(tobj);
struct lu_attr *so_attr = MDD_ENV_VAR(env, cattr);
struct lu_attr *pattr = MDD_ENV_VAR(env, pattr);
int rc;
/* step 1: Check whether the orphan object has been created, and create
* orphan object on the remote MDT if needed */
- mdd_tobj = md2mdd_obj(tobj);
if (!mdd_object_exists(mdd_tobj)) {
rc = mdd_migrate_create(env, mdd_pobj, mdd_sobj, mdd_tobj,
lname, so_attr);
linkea_entry_unpack(ldata.ld_lee, &ldata.ld_reclen,
&name, &fid);
- ldata.ld_lee = (struct link_ea_entry *)((char *)ldata.ld_lee +
- ldata.ld_reclen);
mdt_pobj = mdt_object_find(info->mti_env, mdt, &fid);
if (IS_ERR(mdt_pobj)) {
CWARN("%s: cannot find obj "DFID": rc = %ld\n",
mdt_obd_name(mdt), PFID(&fid), PTR_ERR(mdt_pobj));
- continue;
+ goto next;
}
if (!mdt_object_exists(mdt_pobj)) {
CDEBUG(D_INFO, "%s: obj "DFID" does not exist\n",
mdt_obd_name(mdt), PFID(&fid));
mdt_object_put(info->mti_env, mdt_pobj);
- continue;
+ goto next;
+ }
+
+ /* Check if the object already exists in the list */
+ list_for_each_entry(mll, lock_list, mll_list) {
+ if (mll->mll_obj == mdt_pobj) {
+ mdt_object_put(info->mti_env, mdt_pobj);
+ goto next;
+ }
}
if (mdt_pobj == pobj) {
CDEBUG(D_INFO, "%s: skipping parent obj "DFID"\n",
mdt_obd_name(mdt), PFID(&fid));
mdt_object_put(info->mti_env, mdt_pobj);
- continue;
+ goto next;
}
OBD_ALLOC_PTR(mll);
INIT_LIST_HEAD(&mll->mll_list);
mll->mll_obj = mdt_pobj;
list_add_tail(&mll->mll_list, lock_list);
+next:
+ ldata.ld_lee = (struct link_ea_entry *)((char *)ldata.ld_lee +
+ ldata.ld_reclen);
+
}
out:
if (rc != 0)
rm -rf $DIR/$tdir || error "rm dir failed after migration"
}
-run_test 230e "migrate mulitple link files"
+run_test 230e "migrate mulitple local link files"
+
+test_230f() {
+ [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
+ [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
+ local a_fid
+ local ln_fid
+
+ mkdir -p $DIR/$tdir
+ mkdir $DIR/$tdir/migrate_dir
+ $LFS mkdir -i1 $DIR/$tdir/other_dir
+ touch $DIR/$tdir/migrate_dir/a
+ ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
+ ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
+
+ # a should be migrated to MDT1, since no other links on MDT0
+ $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
+ error "migrate dir fails"
+ mdt_index=$($LFS getstripe -M $DIR/$tdir/migrate_dir)
+ [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
+ mdt_index=$($LFS getstripe -M $DIR/$tdir/migrate_dir/a)
+ [ $mdt_index == 1 ] || error "a is not on MDT1"
+
+ # a should stay on MDT1, because it is a mulitple link file
+ $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
+ error "migrate dir fails"
+ mdt_index=$($LFS getstripe -M $DIR/$tdir/migrate_dir/a)
+ [ $mdt_index == 1 ] || error "a is not on MDT1"
+
+ $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
+ error "migrate dir fails"
+
+ a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
+ ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
+ [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
+
+ rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
+ rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
+
+ # a should be migrated to MDT0, since no other links on MDT1
+ $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
+ error "migrate dir fails"
+ mdt_index=$($LFS getstripe -M $DIR/$tdir/migrate_dir/a)
+ [ $mdt_index == 0 ] || error "a is not on MDT0"
+
+ rm -rf $DIR/$tdir || error "rm dir failed after migration"
+}
+run_test 230f "migrate mulitple remote link files"
test_231a()
{