From: Lai Siyao Date: Tue, 12 Dec 2023 19:50:33 +0000 (-0500) Subject: LU-12998 lod: statfs upon nocreate check X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=066262a04cb8e0cbf49a20b7bf036d4484399afe;p=fs%2Flustre-release.git 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 --- diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index b043a22..25effc3 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -1997,6 +1997,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 int lmv_create(struct obd_export *exp, struct md_op_data *op_data, const void *data, size_t datalen, umode_t mode, uid_t uid, gid_t gid, kernel_cap_t cap_effective, __u64 rdev, @@ -2048,7 +2059,7 @@ static int lmv_create(struct obd_export *exp, struct md_op_data *op_data, tgt = lmv_tgt(lmv, op_data->op_mds); if (!tgt) RETURN(-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); @@ -2061,10 +2072,10 @@ static int lmv_create(struct obd_export *exp, struct md_op_data *op_data, tgt = lmv_tgt(lmv, op_data->op_mds); if (!tgt) RETURN(-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) || - 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 7491099..09e889f 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -6254,47 +6254,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,