Whamcloud - gitweb
LU-12998 lod: statfs upon nocreate check 37/53437/3
authorLai Siyao <lai.siyao@whamcloud.com>
Tue, 12 Dec 2023 19:50:33 +0000 (14:50 -0500)
committerOleg Drokin <green@whamcloud.com>
Wed, 19 Jun 2024 00:45:22 +0000 (00:45 +0000)
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 <lai.siyao@whamcloud.com>
Change-Id: I2575d15416968554c66d40dcf18ecca2a06c7a37
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53437
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Hongchao Zhang <hongchao@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/lmv/lmv_obd.c
lustre/lod/lod_object.c

index 682e9f4..cd8d42c 100644 (file)
@@ -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))
index 1b5c88e..4347eda 100644 (file)
@@ -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,