From 46192db9ae1a3370365e868764817407289d0fd5 Mon Sep 17 00:00:00 2001 From: Di Wang Date: Wed, 16 Dec 2015 02:46:31 -0800 Subject: [PATCH] LU-7577 mdt: root inode checking for migration Do not migrate root inode, and add test case to verify it. Signed-off-by: Di Wang Change-Id: I8b7a4211d76cbfc1e1b095c6e8f94841d42bc50f Reviewed-on: http://review.whamcloud.com/17669 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Lai Siyao Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin --- lustre/llite/file.c | 30 +++++++++++++++--------------- lustre/mdd/mdd_dir.c | 23 +++++++++++++++++------ lustre/mdt/mdt_reint.c | 3 +++ lustre/tests/sanity.sh | 27 +++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 21 deletions(-) diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 0592d26..29689c2 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -3027,17 +3027,17 @@ int ll_migrate(struct inode *parent, struct file *file, int mdtidx, CERROR("%s: migrate %s , but fid "DFID" is insane\n", ll_get_fsname(parent->i_sb, NULL, 0), name, PFID(&op_data->op_fid3)); - GOTO(out_free, rc = -EINVAL); + GOTO(out_unlock, rc = -EINVAL); } rc = ll_get_mdt_idx_by_fid(ll_i2sbi(parent), &op_data->op_fid3); if (rc < 0) - GOTO(out_free, rc); + GOTO(out_unlock, rc); if (rc == mdtidx) { CDEBUG(D_INFO, "%s:"DFID" is already on MDT%d.\n", name, PFID(&op_data->op_fid3), mdtidx); - GOTO(out_free, rc = 0); + GOTO(out_unlock, rc = 0); } again: if (S_ISREG(child_inode->i_mode)) { @@ -3045,13 +3045,13 @@ again: if (IS_ERR(och)) { rc = PTR_ERR(och); och = NULL; - GOTO(out_free, rc); + GOTO(out_unlock, rc); } rc = ll_data_version(child_inode, &data_version, LL_DV_WR_FLUSH); if (rc != 0) - GOTO(out_free, rc); + GOTO(out_close, rc); op_data->op_handle = och->och_fh; op_data->op_data = och->och_mod; @@ -3071,11 +3071,11 @@ again: body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY); if (body == NULL) { ptlrpc_req_finished(request); - GOTO(out_free, rc = -EPROTO); + GOTO(out_close, rc = -EPROTO); } /* If the server does release layout lock, then we cleanup - * the client och here, otherwise release it in out_free: */ + * the client och here, otherwise release it in out_close: */ if (och != NULL && body->mbo_valid & OBD_MD_CLOSE_INTENT_EXECED) { obd_mod_put(och->och_mod); @@ -3093,15 +3093,15 @@ again: request = NULL; goto again; } -out_free: - if (child_inode != NULL) { - if (och != NULL) /* close the file */ - ll_lease_close(och, child_inode, NULL); +out_close: + if (och != NULL) /* close the file */ + ll_lease_close(och, child_inode, NULL); + if (rc == 0) clear_nlink(child_inode); - mutex_unlock(&child_inode->i_mutex); - iput(child_inode); - } - +out_unlock: + mutex_unlock(&child_inode->i_mutex); + iput(child_inode); +out_free: ll_finish_md_op_data(op_data); RETURN(rc); } diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index e7b72c0..864ff8a 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -1163,10 +1163,15 @@ struct lu_buf *mdd_links_get(const struct lu_env *env, int mdd_links_write(const struct lu_env *env, struct mdd_object *mdd_obj, struct linkea_data *ldata, struct thandle *handle) { - const struct lu_buf *buf = mdd_buf_get_const(env, ldata->ld_buf->lb_buf, - ldata->ld_leh->leh_len); + const struct lu_buf *buf; int rc; + if (ldata == NULL || ldata->ld_buf == NULL || + ldata->ld_leh == NULL) + return 0; + + buf = mdd_buf_get_const(env, ldata->ld_buf->lb_buf, + ldata->ld_leh->leh_len); if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_NO_LINKEA)) return 0; @@ -1951,7 +1956,8 @@ static int mdd_create_sanity_check(const struct lu_env *env, ENTRY; /* EEXIST check */ - if (mdd_is_dead_obj(obj)) + if (mdd_is_dead_obj(obj) || + pattr->la_flags & LUSTRE_SLAVE_DEAD_FL) RETURN(-ENOENT); /* @@ -3418,7 +3424,7 @@ static int mdd_declare_migrate_create(const struct lu_env *env, buf, 0, handle); if (rc != 0) return rc; - } else if (S_ISDIR(la->la_mode)) { + } else if (S_ISDIR(la->la_mode) && ldata != NULL) { rc = mdd_declare_links_add(env, mdd_tobj, handle, ldata, MLAO_IGNORE); if (rc != 0) @@ -3502,7 +3508,12 @@ static int mdd_migrate_create(const struct lu_env *env, } } else if (S_ISDIR(la->la_mode)) { rc = mdd_links_read(env, mdd_sobj, ldata); - if (rc < 0 && rc != -ENODATA) + if (rc == -ENODATA) { + /* ignore the non-linkEA error */ + ldata = NULL; + rc = 0; + } + if (rc < 0) RETURN(rc); } @@ -3542,7 +3553,7 @@ static int mdd_migrate_create(const struct lu_env *env, if (rc != 0) GOTO(stop_trans, rc); - if (S_ISDIR(la->la_mode)) { + if (S_ISDIR(la->la_mode) && ldata != NULL) { rc = mdd_links_write(env, mdd_tobj, ldata, handle); if (rc != 0) GOTO(stop_trans, rc); diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index 1dbae87..d18019b 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -1449,6 +1449,9 @@ static int mdt_reint_migrate_internal(struct mdt_thread_info *info, if (!fid_is_md_operative(old_fid)) GOTO(out_unlock_parent, rc = -EPERM); + if (lu_fid_eq(old_fid, &info->mti_mdt->mdt_md_root_fid)) + GOTO(out_unlock_parent, rc = -EPERM); + mold = mdt_object_find(info->mti_env, info->mti_mdt, old_fid); if (IS_ERR(mold)) GOTO(out_unlock_parent, rc = PTR_ERR(mold)); diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 3b77e07..ebb2495 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -13079,6 +13079,33 @@ test_230g() { } run_test 230g "migrate dir to non-exist MDT" +test_230h() { + [ $PARALLEL == "yes" ] && skip "skip parallel run" && return + [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return + [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.64) ] && + skip "Need MDS version at least 2.7.64" && return + local mdt_index + + mkdir -p $DIR/$tdir/migrate_dir + + $LFS migrate -m1 $DIR && + error "migrating mountpoint1 should fail" + + $LFS migrate -m1 $DIR/$tdir/.. && + error "migrating mountpoint2 should fail" + + $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. || + error "migrating $tdir fail" + + mdt_index=$($LFS getstripe -M $DIR/$tdir) + [ $mdt_index == 1 ] || error "$mdt_index != 1 after migration" + + mdt_index=$($LFS getstripe -M $DIR/$tdir/migrate_dir) + [ $mdt_index == 1 ] || error "$mdt_index != 1 after migration" + +} +run_test 230h "migrate .. and root" + test_231a() { # For simplicity this test assumes that max_pages_per_rpc -- 1.8.3.1