From 6214a9330254af64a06ffd48824f57a40037ca19 Mon Sep 17 00:00:00 2001 From: Lai Siyao Date: Sat, 23 Jan 2021 18:28:26 +0800 Subject: [PATCH] LU-14366 mdt: lfs mkdir should return -EEXIST if exists 'lfs setdirstripe' will try restripe if target exists, however it's confusing to get -ENOTSUPP or -EALREADY for 'lfs mkdir', while the latter invokes the same function as 'lfs setdirstripe'. Pack MDS_OPEN_CREAT flag in request for 'lfs mkdir', and MDT won't try restripe if it's set. Add sanity 230s. Lustre-change: https://review.whamcloud.com/41329 Lustre-commit: 65e3e4050ec5bb371c1c343fca49a605286a086e Signed-off-by: Lai Siyao Change-Id: I7b7ed04ee0b150253ff4d13bbdf1fe847d8f577c Reviewed-by: Andreas Dilger Reviewed-by: Yingjin Qian Reviewed-on: https://review.whamcloud.com/43428 Tested-by: jenkins Tested-by: Maloo --- lustre/include/lustre/lustreapi.h | 1 + lustre/include/uapi/linux/lustre/lustre_idl.h | 2 ++ lustre/llite/dir.c | 29 +++++++++++++++++---------- lustre/mdc/mdc_lib.c | 5 +++++ lustre/mdt/mdt_reint.c | 8 ++++++-- lustre/tests/sanity.sh | 22 ++++++++++++++++++++ lustre/utils/lfs.c | 2 ++ lustre/utils/liblustreapi.c | 3 +++ 8 files changed, 59 insertions(+), 13 deletions(-) diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index 49cc02a..be4c892 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -131,6 +131,7 @@ struct llapi_stripe_param { /* Number of stripes. Size of lsp_osts[] if lsp_specific is true.*/ int lsp_stripe_count; bool lsp_is_specific; + bool lsp_is_create; __u32 lsp_osts[0]; }; diff --git a/lustre/include/uapi/linux/lustre/lustre_idl.h b/lustre/include/uapi/linux/lustre/lustre_idl.h index 85db043..b932907 100644 --- a/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -1972,6 +1972,8 @@ enum mds_op_bias { MDS_TRUNC_KEEP_LEASE = 1 << 18, MDS_PCC_ATTACH = 1 << 19, MDS_CLOSE_UPDATE_TIMES = 1 << 20, + /* setstripe create only, don't restripe if target exists */ + MDS_SETSTRIPE_CREATE = 1 << 21, }; #define MDS_CLOSE_INTENT (MDS_HSM_RELEASE | MDS_CLOSE_LAYOUT_SWAP | \ diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 0e73a9d..4329254 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -402,7 +402,8 @@ out: * <0 if the creation is failed. */ static int ll_dir_setdirstripe(struct dentry *dparent, struct lmv_user_md *lump, - size_t len, const char *dirname, umode_t mode) + size_t len, const char *dirname, umode_t mode, + bool createonly) { struct inode *parent = dparent->d_inode; struct ptlrpc_request *request = NULL; @@ -508,6 +509,9 @@ static int ll_dir_setdirstripe(struct dentry *dparent, struct lmv_user_md *lump, } op_data->op_cli_flags |= CLI_SET_MEA; + if (createonly) + op_data->op_bias |= MDS_SETSTRIPE_CREATE; + err = md_create(sbi->ll_md_exp, op_data, lump, len, mode, from_kuid(&init_user_ns, current_fsuid()), from_kgid(&init_user_ns, current_fsgid()), @@ -1412,17 +1416,18 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } out_free: OBD_FREE_LARGE(buf, len); - return rc; - } + return rc; + } case LL_IOC_LMV_SETSTRIPE: { struct lmv_user_md *lum; - char *buf = NULL; - char *filename; - int namelen = 0; - int lumlen = 0; - umode_t mode; - int len; - int rc; + char *buf = NULL; + char *filename; + int namelen = 0; + int lumlen = 0; + umode_t mode; + bool createonly = false; + int len; + int rc; rc = obd_ioctl_getdata(&buf, &len, (void __user *)arg); if (rc) @@ -1465,7 +1470,9 @@ out_free: } mode = data->ioc_type; - rc = ll_dir_setdirstripe(dentry, lum, lumlen, filename, mode); + createonly = data->ioc_obdo1.o_flags & OBD_FL_OBDMDEXISTS; + rc = ll_dir_setdirstripe(dentry, lum, lumlen, filename, mode, + createonly); lmv_out_free: OBD_FREE_LARGE(buf, len); RETURN(rc); diff --git a/lustre/mdc/mdc_lib.c b/lustre/mdc/mdc_lib.c index b44bc0f..09f4e7c7 100644 --- a/lustre/mdc/mdc_lib.c +++ b/lustre/mdc/mdc_lib.c @@ -219,6 +219,11 @@ void mdc_create_pack(struct ptlrpc_request *req, struct md_op_data *op_data, flags = 0; if (op_data->op_bias & MDS_CREATE_VOLATILE) flags |= MDS_OPEN_VOLATILE; + if (op_data->op_bias & MDS_SETSTRIPE_CREATE) + /* borrow MDS_OPEN_CREATE flag to indicate current setstripe + * create only, and don't restripe if object exists. + */ + flags |= MDS_OPEN_CREAT; set_mrc_cr_flags(rec, flags); rec->cr_bias = op_data->op_bias; rec->cr_umask = current_umask(); diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index c14b84a..c29422b 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -531,8 +531,12 @@ static int mdt_create(struct mdt_thread_info *info) mdt->mdt_enable_remote_dir_gid != -1) RETURN(-EPERM); - /* restripe if later found dir exists */ - if (le32_to_cpu(lum->lum_stripe_offset) == LMV_OFFSET_DEFAULT) + /* restripe if later found dir exists, MDS_OPEN_CREAT means + * this is create only, don't try restripe. + */ + if (mdt->mdt_enable_dir_restripe && + le32_to_cpu(lum->lum_stripe_offset) == LMV_OFFSET_DEFAULT && + !(spec->sp_cr_flags & MDS_OPEN_CREAT)) restripe = true; } diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 442bbb0..190910e 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -18733,6 +18733,28 @@ test_230r() { } run_test 230r "migrate with too many local locks" +test_230s() { + [ $MDS1_VERSION -ge $(version_code 2.13.57) ] || + skip "Need MDS version at least 2.13.57" + + local mdts=$(comma_list $(mdts_nodes)) + local restripe_status=$(do_facet mds1 $LCTL get_param -n \ + mdt.*MDT0000.enable_dir_restripe) + + stack_trap "do_nodes $mdts $LCTL set_param \ + mdt.*.enable_dir_restripe=$restripe_status" + + local st + for st in 0 1; do + do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st" + test_mkdir $DIR/$tdir + $LFS mkdir $DIR/$tdir |& grep "File exists" || + error "$LFS mkdir doesn't return -EEXIST if target exists" + rmdir $DIR/$tdir + done +} +run_test 230s "lfs mkdir should return -EEXIST if target exists" + test_231a() { # For simplicity this test assumes that max_pages_per_rpc diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index eff36a7..43a81a4 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -6337,6 +6337,8 @@ static int lfs_setdirstripe(int argc, char **argv) param->lsp_stripe_pattern = LMV_HASH_TYPE_UNKNOWN; param->lsp_pool = lsa.lsa_pool_name; param->lsp_is_specific = false; + if (strcmp(argv[0], "mkdir") == 0) + param->lsp_is_create = true; if (lsa.lsa_nr_tgts > 1) { if (lsa.lsa_stripe_count > 0 && lsa.lsa_stripe_count != LLAPI_LAYOUT_DEFAULT && diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index d03ea43..469dbc9 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -1097,6 +1097,9 @@ int llapi_dir_create(const char *name, mode_t mode, data.ioc_inlbuf2 = (char *)lmu; data.ioc_inllen2 = lmu_size; data.ioc_type = mode; + if (param->lsp_is_create) + /* borrow obdo1.o_flags to store this flag */ + data.ioc_obdo1.o_flags = OBD_FL_OBDMDEXISTS; rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc) { llapi_error(LLAPI_MSG_ERROR, rc, -- 1.8.3.1