From 2dae2b8ffb8f3238f240e0e59987e93ce3e31d86 Mon Sep 17 00:00:00 2001 From: Lai Siyao Date: Thu, 22 Dec 2016 23:46:40 +0800 Subject: [PATCH] LU-8777 mdt: add parameter to disable remote/striped dir Restore mdt_enable_remote_dir to enable/disable remote directory feature, and also add mdt_enable_striped_dir and mdt_enable_dir_migration for striped directory and directory migration. Enable remote directory, striped directory and directory migration by default. Add sanity.sh 417. Signed-off-by: Lai Siyao Change-Id: I583dbc5a5eb54de02c8a4459092d4a3f3b24b262 Reviewed-on: https://review.whamcloud.com/24498 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Jian Yu Reviewed-by: Oleg Drokin --- lustre/mdt/mdt_handler.c | 4 +- lustre/mdt/mdt_internal.h | 5 +- lustre/mdt/mdt_lproc.c | 61 ++++++++++++++++ lustre/mdt/mdt_reint.c | 162 ++++++++++++++++------------------------- lustre/mdt/mdt_xattr.c | 11 ++- lustre/tests/sanity.sh | 37 +++++++++- lustre/tests/test-framework.sh | 20 ----- 7 files changed, 176 insertions(+), 124 deletions(-) diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 94a675a..7d15b33 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -5073,7 +5073,9 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m, INIT_LIST_HEAD(&m->mdt_squash.rsi_nosquash_nids); init_rwsem(&m->mdt_squash.rsi_sem); spin_lock_init(&m->mdt_lock); - m->mdt_enable_remote_dir = 0; + m->mdt_enable_remote_dir = 1; + m->mdt_enable_striped_dir = 1; + m->mdt_enable_dir_migration = 1; m->mdt_enable_remote_dir_gid = 0; atomic_set(&m->mdt_mds_mds_conns, 0); diff --git a/lustre/mdt/mdt_internal.h b/lustre/mdt/mdt_internal.h index f448f31..35744bf 100644 --- a/lustre/mdt/mdt_internal.h +++ b/lustre/mdt/mdt_internal.h @@ -249,8 +249,12 @@ struct mdt_device { unsigned int mdt_capa_conf:1, /* Enable remote dir on non-MDT0 */ mdt_enable_remote_dir:1, + mdt_enable_striped_dir:1, + mdt_enable_dir_migration:1, mdt_skip_lfsck:1; + /* user with gid can create remote/striped + * dir, and set default dir stripe */ gid_t mdt_enable_remote_dir_gid; /* lock for osfs and md_root */ @@ -890,7 +894,6 @@ int mdt_links_read(struct mdt_thread_info *info, struct linkea_data *ldata); int mdt_close_internal(struct mdt_thread_info *info, struct ptlrpc_request *req, struct mdt_body *repbody); -int mdt_remote_dir_permission(struct mdt_thread_info *info); static inline struct mdt_device *mdt_dev(struct lu_device *d) { diff --git a/lustre/mdt/mdt_lproc.c b/lustre/mdt/mdt_lproc.c index b41eeee..da3c529 100644 --- a/lustre/mdt/mdt_lproc.c +++ b/lustre/mdt/mdt_lproc.c @@ -656,6 +656,63 @@ mdt_enable_remote_dir_gid_seq_write(struct file *file, } LPROC_SEQ_FOPS(mdt_enable_remote_dir_gid); +static int mdt_enable_striped_dir_seq_show(struct seq_file *m, void *data) +{ + struct obd_device *obd = m->private; + struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev); + + seq_printf(m, "%u\n", mdt->mdt_enable_striped_dir); + return 0; +} + +static ssize_t +mdt_enable_striped_dir_seq_write(struct file *file, const char __user *buffer, + size_t count, loff_t *off) +{ + struct seq_file *m = file->private_data; + struct obd_device *obd = m->private; + struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev); + bool val; + int rc; + + rc = kstrtobool_from_user(buffer, count, &val); + if (rc) + return rc; + + mdt->mdt_enable_striped_dir = val; + return count; +} +LPROC_SEQ_FOPS(mdt_enable_striped_dir); + +static int mdt_enable_dir_migration_seq_show(struct seq_file *m, void *data) +{ + struct obd_device *obd = m->private; + struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev); + + seq_printf(m, "%u\n", mdt->mdt_enable_dir_migration); + return 0; +} + +static ssize_t +mdt_enable_dir_migration_seq_write(struct file *file, const char __user *buffer, + size_t count, loff_t *off) +{ + struct seq_file *m = file->private_data; + struct obd_device *obd = m->private; + struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev); + bool val; + int rc; + + rc = kstrtobool_from_user(buffer, count, &val); + if (rc) + return rc; + + mdt->mdt_enable_dir_migration = val; + return count; +} +LPROC_SEQ_FOPS(mdt_enable_dir_migration); + + /** * Show MDT policy for handling dirty metadata under a lock being cancelled. * @@ -987,6 +1044,10 @@ static struct lprocfs_vars lprocfs_mdt_obd_vars[] = { .fops = &mdt_enable_remote_dir_fops }, { .name = "enable_remote_dir_gid", .fops = &mdt_enable_remote_dir_gid_fops }, + { .name = "enable_striped_dir", + .fops = &mdt_enable_striped_dir_fops }, + { .name = "enable_dir_migration", + .fops = &mdt_enable_dir_migration_fops }, { .name = "hsm_control", .fops = &mdt_hsm_cdt_control_fops }, { .name = "recovery_time_hard", diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index 9c759c1..87f26ce 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -217,78 +217,6 @@ static int mdt_lookup_version_check(struct mdt_thread_info *info, } -static inline int mdt_remote_dir_permission_check(struct mdt_thread_info *info) -{ - struct lu_ucred *uc = mdt_ucred(info); - struct mdt_device *mdt = info->mti_mdt; - - if (!md_capable(uc, CFS_CAP_SYS_ADMIN)) { - if (uc->uc_gid != mdt->mdt_enable_remote_dir_gid && - mdt->mdt_enable_remote_dir_gid != -1) - return -EPERM; - } - - return 0; -} - -/** - * mdt_remote_dir_permission: Check whether the remote operation is permitted, - * - * Only sysadmin can create remote directory / striped directory, - * migrate directory and set default stripedEA on directory, unless - * - * lctl set_param mdt.*.enable_remote_dir_gid=allow_gid. - * - * param[in] info: mdt_thread_info. - * - * retval = 0 remote operation is allowed. - * < 0 remote operation is denied. - */ -int mdt_remote_dir_permission(struct mdt_thread_info *info) -{ - struct md_op_spec *spec = &info->mti_spec; - struct lu_attr *attr = &info->mti_attr.ma_attr; - struct obd_export *exp = mdt_info_req(info)->rq_export; - int rc; - - if (info->mti_rr.rr_opcode == REINT_MIGRATE) { - rc = mdt_remote_dir_permission_check(info); - if (rc != 0) - return rc; - } - - if (info->mti_rr.rr_opcode == REINT_CREATE && - (S_ISDIR(attr->la_mode) && spec->u.sp_ea.eadata != NULL && - spec->u.sp_ea.eadatalen != 0)) { - const struct lmv_user_md *lum = spec->u.sp_ea.eadata; - - /* Only new clients can create remote dir( >= 2.4) and - * striped dir(>= 2.6), old client will return -ENOTSUPP */ - if (!mdt_is_dne_client(exp)) - return -ENOTSUPP; - - if (le32_to_cpu(lum->lum_stripe_count) > 1 && - !mdt_is_striped_client(exp)) - return -ENOTSUPP; - - rc = mdt_remote_dir_permission_check(info); - if (rc != 0) - return rc; - } - - if (info->mti_rr.rr_opcode == REINT_SETATTR) { - struct md_attr *ma = &info->mti_attr; - - if ((ma->ma_valid & MA_LMV)) { - rc = mdt_remote_dir_permission_check(info); - if (rc != 0) - return rc; - } - } - - return 0; -} - static int mdt_unlock_slaves(struct mdt_thread_info *mti, struct mdt_object *obj, struct ldlm_enqueue_info *einfo, @@ -423,6 +351,7 @@ static int mdt_create(struct mdt_thread_info *info) struct mdt_body *repbody; struct md_attr *ma = &info->mti_attr; struct mdt_reint_record *rr = &info->mti_rr; + struct md_op_spec *spec = &info->mti_spec; int rc; ENTRY; @@ -433,6 +362,33 @@ static int mdt_create(struct mdt_thread_info *info) if (!fid_is_md_operative(rr->rr_fid1)) RETURN(-EPERM); + if (S_ISDIR(ma->ma_attr.la_mode) && + spec->u.sp_ea.eadata != NULL && spec->u.sp_ea.eadatalen != 0) { + const struct lmv_user_md *lum = spec->u.sp_ea.eadata; + struct lu_ucred *uc = mdt_ucred(info); + struct obd_export *exp = mdt_info_req(info)->rq_export; + + /* Only new clients can create remote dir( >= 2.4) and + * striped dir(>= 2.6), old client will return -ENOTSUPP */ + if (!mdt_is_dne_client(exp)) + RETURN(-ENOTSUPP); + + if (le32_to_cpu(lum->lum_stripe_count) > 1) { + if (!mdt_is_striped_client(exp)) + RETURN(-ENOTSUPP); + + if (!mdt->mdt_enable_striped_dir) + RETURN(-EPERM); + } else if (!mdt->mdt_enable_remote_dir) { + RETURN(-EPERM); + } + + if (!md_capable(uc, CFS_CAP_SYS_ADMIN) && + uc->uc_gid != mdt->mdt_enable_remote_dir_gid && + mdt->mdt_enable_remote_dir_gid != -1) + RETURN(-EPERM); + } + repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY); parent = mdt_object_find(info->mti_env, info->mti_mdt, rr->rr_fid1); @@ -474,10 +430,6 @@ static int mdt_create(struct mdt_thread_info *info) if (unlikely(IS_ERR(child))) GOTO(unlock_parent, rc = PTR_ERR(child)); - rc = mdt_remote_dir_permission(info); - if (rc != 0) - GOTO(put_child, rc); - ma->ma_need = MA_INODE; ma->ma_valid = 0; @@ -672,26 +624,27 @@ int mdt_add_dirty_flag(struct mdt_thread_info *info, struct mdt_object *mo, } static int mdt_reint_setattr(struct mdt_thread_info *info, - struct mdt_lock_handle *lhc) + struct mdt_lock_handle *lhc) { - struct md_attr *ma = &info->mti_attr; - struct mdt_reint_record *rr = &info->mti_rr; - struct ptlrpc_request *req = mdt_info_req(info); - struct mdt_object *mo; - struct mdt_body *repbody; - int rc, rc2; - ENTRY; + struct mdt_device *mdt = info->mti_mdt; + struct md_attr *ma = &info->mti_attr; + struct mdt_reint_record *rr = &info->mti_rr; + struct ptlrpc_request *req = mdt_info_req(info); + struct mdt_object *mo; + struct mdt_body *repbody; + int rc, rc2; + ENTRY; - DEBUG_REQ(D_INODE, req, "setattr "DFID" %x", PFID(rr->rr_fid1), - (unsigned int)ma->ma_attr.la_valid); + DEBUG_REQ(D_INODE, req, "setattr "DFID" %x", PFID(rr->rr_fid1), + (unsigned int)ma->ma_attr.la_valid); if (info->mti_dlm_req) ldlm_request_cancel(req, info->mti_dlm_req, 0, LATF_SKIP); repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY); - mo = mdt_object_find(info->mti_env, info->mti_mdt, rr->rr_fid1); - if (IS_ERR(mo)) - GOTO(out, rc = PTR_ERR(mo)); + mo = mdt_object_find(info->mti_env, mdt, rr->rr_fid1); + if (IS_ERR(mo)) + GOTO(out, rc = PTR_ERR(mo)); if (!mdt_object_exists(mo)) GOTO(out_put, rc = -ENOENT); @@ -756,12 +709,21 @@ static int mdt_reint_setattr(struct mdt_thread_info *info, GOTO(out_put, rc); } else if ((ma->ma_valid & (MA_LOV | MA_LMV)) && (ma->ma_valid & MA_INODE)) { - struct lu_buf *buf = &info->mti_buf; - struct mdt_lock_handle *lh; + struct lu_buf *buf = &info->mti_buf; + struct lu_ucred *uc = mdt_ucred(info); + struct mdt_lock_handle *lh; - rc = mdt_remote_dir_permission(info); - if (rc < 0) - GOTO(out_put, rc); + /* reject if either remote or striped dir is disabled */ + if (ma->ma_valid & MA_LMV) { + if (!mdt->mdt_enable_remote_dir || + !mdt->mdt_enable_striped_dir) + GOTO(out_put, rc = -EPERM); + + if (!md_capable(uc, CFS_CAP_SYS_ADMIN) && + uc->uc_gid != mdt->mdt_enable_remote_dir_gid && + mdt->mdt_enable_remote_dir_gid != -1) + GOTO(out_put, rc = -EPERM); + } if (ma->ma_attr.la_valid != 0) GOTO(out_put, rc = -EPROTO); @@ -1667,7 +1629,6 @@ static int mdt_lock_remote_slaves(struct mdt_thread_info *info, INIT_LIST_HEAD(&msl->msl_linkage); msl->msl_obj = slave; list_add_tail(&msl->msl_linkage, slave_locks); - } EXIT; @@ -1967,6 +1928,7 @@ static int mdt_reint_migrate_internal(struct mdt_thread_info *info) const struct lu_env *env = info->mti_env; struct mdt_device *mdt = info->mti_mdt; struct mdt_reint_record *rr = &info->mti_rr; + struct lu_ucred *uc = mdt_ucred(info); struct md_attr *ma = &info->mti_attr; struct ldlm_enqueue_info *peinfo = &info->mti_einfo[0]; struct ldlm_enqueue_info *seinfo = &info->mti_einfo[1]; @@ -1992,9 +1954,13 @@ static int mdt_reint_migrate_internal(struct mdt_thread_info *info) if (lu_name_is_dot_or_dotdot(&rr->rr_name)) RETURN(-EBUSY); - rc = mdt_remote_dir_permission(info); - if (rc) - RETURN(rc); + if (!mdt->mdt_enable_remote_dir || !mdt->mdt_enable_dir_migration) + RETURN(-EPERM); + + if (!md_capable(uc, CFS_CAP_SYS_ADMIN) && + uc->uc_gid != mdt->mdt_enable_remote_dir_gid && + mdt->mdt_enable_remote_dir_gid != -1) + RETURN(-EPERM); /* pobj is master object of parent */ pobj = mdt_object_find_check(info, rr->rr_fid1, 0); diff --git a/lustre/mdt/mdt_xattr.c b/lustre/mdt/mdt_xattr.c index 9bd7526..5101eab 100644 --- a/lustre/mdt/mdt_xattr.c +++ b/lustre/mdt/mdt_xattr.c @@ -310,6 +310,7 @@ static int mdt_dir_layout_shrink(struct mdt_thread_info *info) { const struct lu_env *env = info->mti_env; struct mdt_device *mdt = info->mti_mdt; + struct lu_ucred *uc = mdt_ucred(info); struct mdt_reint_record *rr = &info->mti_rr; struct lmv_user_md *lmu = rr->rr_eadata; __u32 lum_stripe_count = lmu->lum_stripe_count; @@ -325,9 +326,13 @@ static int mdt_dir_layout_shrink(struct mdt_thread_info *info) ENTRY; - rc = mdt_remote_dir_permission(info); - if (rc) - RETURN(rc); + if (!mdt->mdt_enable_dir_migration) + RETURN(-EPERM); + + if (!md_capable(uc, CFS_CAP_SYS_ADMIN) && + uc->uc_gid != mdt->mdt_enable_remote_dir_gid && + mdt->mdt_enable_remote_dir_gid != -1) + RETURN(-EPERM); /* mti_big_lmm is used to save LMV, but it may be uninitialized. */ if (unlikely(!info->mti_big_lmm)) { diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 0e33c79..18ad4eb 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -19239,7 +19239,6 @@ test_415() { } run_test 415 "lock revoke is not missing" - test_416() { [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] && skip "Need server version at least 2.11.55" @@ -19253,6 +19252,42 @@ test_416() { } run_test 416 "transaction start failure won't cause system hung" +cleanup_417() { + trap 0 + do_nodes $(comma_list $(mdts_nodes)) \ + "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1" + do_nodes $(comma_list $(mdts_nodes)) \ + "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1" + do_nodes $(comma_list $(mdts_nodes)) \ + "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1" +} + +test_417() { + [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return + [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ]] && + skip "Need MDS version at least 2.11.56" && return + + trap cleanup_417 RETURN EXIT + + $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed" + do_nodes $(comma_list $(mdts_nodes)) \ + "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0" + $LFS migrate -m 0 $DIR/$tdir.1 && + error "migrate dir $tdir.1 should fail" + + do_nodes $(comma_list $(mdts_nodes)) \ + "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0" + $LFS mkdir -i 1 $DIR/$tdir.2 && + error "create remote dir $tdir.2 should fail" + + do_nodes $(comma_list $(mdts_nodes)) \ + "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0" + $LFS mkdir -c 2 $DIR/$tdir.3 && + error "create striped dir $tdir.3 should fail" + true +} +run_test 417 "disable remote dir, striped dir and dir migration" + prep_801() { [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] || [[ $(lustre_version_code ost1) -lt $(version_code 2.9.55) ]] && diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh index 9caa3f7..b42bc9c 100755 --- a/lustre/tests/test-framework.sh +++ b/lustre/tests/test-framework.sh @@ -1946,11 +1946,6 @@ mount_facet() { set_default_debug_facet $facet - if [[ $facet == mds* ]]; then - do_facet $facet \ - lctl set_param -n mdt.${FSNAME}*.enable_remote_dir=1 2>/dev/null - fi - if [[ $opts =~ .*nosvc.* ]]; then echo "Start $dm_dev without service" else @@ -2012,12 +2007,6 @@ start() { mount_facet ${facet} RC=$? - if [[ $facet == mds* ]]; then - do_facet $facet \ - lctl set_param -n mdt.${FSNAME}*.enable_remote_dir=1 \ - 2>/dev/null - fi - return $RC } @@ -5084,15 +5073,6 @@ check_and_setup_lustre() { set_flavor_all $SEC fi - if [ -z "$CLIENTONLY" ]; then - # Enable remote MDT create for testing - for num in $(seq $MDSCOUNT); do - do_facet mds$num \ - lctl set_param -n mdt.${FSNAME}*.enable_remote_dir=1 \ - 2>/dev/null - done - fi - if [ "$ONLY" == "setup" ]; then exit 0 fi -- 1.8.3.1