From 6dbb4c6c826133452c8c2da3937711c2030f99eb Mon Sep 17 00:00:00 2001 From: Lai Siyao Date: Tue, 12 Dec 2023 14:50:33 -0500 Subject: [PATCH] LU-12998 lod: statfs upon nocreate check lod_declare_create() checks whether directory create target MDT is current MDT, this may happen if nocreate is set on some MDT. Upon such mismatch, call dt_statfs() to fetch latest statfs to know whether nocreate is set. lmv_create() will choose another MDT if target MDT is set with nocreate, but in case the flag is cleared, call obd_statfs() to fetch cached statfs and check again. Fixes: 1dbcd0bab88 (LU-12998 mds: add no_create parameter to stop creates) Signed-off-by: Lai Siyao Change-Id: I2575d15416968554c66d40dcf18ecca2a06c7a37 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53437 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Hongchao Zhang Reviewed-by: Oleg Drokin --- lustre/lmv/lmv_obd.c | 17 ++++++++++--- lustre/lod/lod_object.c | 67 +++++++++++++++++++++++-------------------------- 2 files changed, 45 insertions(+), 39 deletions(-) diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index 682e9f4..cd8d42c 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -2131,6 +2131,17 @@ static struct lu_tgt_desc *lmv_locate_tgt_by_space(struct lmv_obd *lmv, return tgt; } +static bool lmv_tgt_nocreate(struct lmv_obd *lmv, struct lmv_tgt_desc *tgt) +{ + if (likely(!(tgt->ltd_statfs.os_state & OS_STATFS_NOCREATE))) + return false; + + obd_statfs(NULL, tgt->ltd_exp, &tgt->ltd_statfs, + ktime_get_seconds() - + lmv->lmv_mdt_descs.ltd_lmv_desc.ld_qos_maxage, 0); + return tgt->ltd_statfs.os_state & OS_STATFS_NOCREATE; +} + static bool lmv_qos_exclude(struct lmv_obd *lmv, struct md_op_data *op_data) { const char *name = op_data->op_name; @@ -2190,7 +2201,7 @@ struct lmv_tgt_desc *lmv_locate_tgt_create(struct obd_device *obd, tgt = lmv_tgt(lmv, op_data->op_mds); if (!tgt) RETURN(ERR_PTR(-ENODEV)); - if (unlikely(tgt->ltd_statfs.os_state & OS_STATFS_NOCREATE)) + if (unlikely(lmv_tgt_nocreate(lmv, tgt))) GOTO(new_tgt, -EAGAIN); } else if (lmv_op_user_qos_mkdir(op_data)) { tgt = lmv_locate_tgt_by_space(lmv, op_data, tgt); @@ -2203,11 +2214,11 @@ struct lmv_tgt_desc *lmv_locate_tgt_create(struct obd_device *obd, tgt = lmv_tgt(lmv, op_data->op_mds); if (!tgt) RETURN(ERR_PTR(-ENODEV)); - if (unlikely(tgt->ltd_statfs.os_state & OS_STATFS_NOCREATE)) + if (unlikely(lmv_tgt_nocreate(lmv, tgt))) GOTO(new_tgt, -EAGAIN); } else if ((lmv_op_default_qos_mkdir(op_data) && !lmv_qos_exclude(lmv, op_data)) || - tgt->ltd_statfs.os_state & OS_STATFS_NOCREATE) { + unlikely(lmv_tgt_nocreate(lmv, tgt))) { new_tgt: tgt = lmv_locate_tgt_by_space(lmv, op_data, tgt); if (IS_ERR(tgt)) diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index 1b5c88e..4347eda 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -6326,47 +6326,42 @@ static int lod_declare_create(const struct lu_env *env, struct dt_object *dt, struct lu_buf buf = { NULL }; ss = lu_site2seq(dt->do_lu.lo_dev->ld_site); - - /* If the parent has default stripeEA, and client - * did not find it before sending create request, - * then MDT will return -EREMOTE, and client will - * retrieve the default stripeEA and re-create the - * sub directory. - * - * Note: if dah_eadata != NULL, it means creating the - * striped directory with specified stripeEA, then it - * should ignore the default stripeEA */ - if (hint != NULL && hint->dah_eadata == NULL) { + if (hint && (!hint->dah_eadata || hint->dah_eadata_is_dmv)) { if (CFS_FAIL_CHECK(OBD_FAIL_MDS_STALE_DIR_LAYOUT)) GOTO(out, rc = -EREMOTE); + } else if (hint) { + LASSERT(hint->dah_eadata && !hint->dah_eadata_is_dmv); + buf.lb_buf = (void *)hint->dah_eadata; + buf.lb_len = hint->dah_eadata_len; + } - if (lo->ldo_dir_stripe_offset != LMV_OFFSET_DEFAULT && - lo->ldo_dir_stripe_offset != ss->ss_node_id) { - struct lod_device *lod; - struct lu_tgt_desc *mdt = NULL; - bool found_mdt = false; - - lod = lu2lod_dev(lo->ldo_obj.do_lu.lo_dev); - lod_foreach_mdt(lod, mdt) { - if (mdt->ltd_index == - lo->ldo_dir_stripe_offset) { - found_mdt = true; - break; - } - } - /* If the MDT indicated by stripe_offset can be - * found, then tell client to resend the create - * request to the correct MDT, otherwise return - * error to client */ - if (found_mdt) - GOTO(out, rc = -EREMOTE); - else - GOTO(out, rc = -EINVAL); + /* if dir target MDT is not current MDT, it's possible that + * directory creation is disabled on the target MDT. + */ + if (lo->ldo_dir_stripe_offset != LMV_OFFSET_DEFAULT && + lo->ldo_dir_stripe_offset != ss->ss_node_id) { + struct lod_device *lod; + struct lu_tgt_desc *mdt = NULL; + bool no_create = false; + + lod = lu2lod_dev(lo->ldo_obj.do_lu.lo_dev); + rc = -EINVAL; + lod_foreach_mdt(lod, mdt) { + if (mdt->ltd_index == + lo->ldo_dir_stripe_offset) { + rc = -EPROTO; + /* refresh statfs */ + dt_statfs(env, mdt->ltd_tgt, + &mdt->ltd_statfs); + no_create = (mdt->ltd_statfs.os_state & + OS_STATFS_NOCREATE); + break; + } } - } else if (hint && hint->dah_eadata) { - buf.lb_buf = (void *)hint->dah_eadata; - buf.lb_len = hint->dah_eadata_len; + + if (!no_create) + GOTO(out, rc); } rc = lod_declare_dir_striping_create(env, dt, attr, &buf, dof, -- 1.8.3.1