Whamcloud - gitweb
LU-15593 mdt: Add option to disable use of SOM 83/46683/7
authorPatrick Farrell <pfarrell@whamcloud.com>
Mon, 7 Mar 2022 20:31:34 +0000 (15:31 -0500)
committerOleg Drokin <green@whamcloud.com>
Mon, 27 Jun 2022 04:39:58 +0000 (04:39 +0000)
There's currently no way to disable use of strict SOM,
which is a problem if there's ever a SOM bug.  This is
tricky to do from the client, but easy on the MDT.

The test just verifies that the size stays the same with
strict SOM disabled, because there's no easy way to check
SOM is disabled unless SOM is broken.  (Since it gives the
same value for stat.)

Note this patch requires LU-15609 to be fixed on the client
or the client will see size as 0 when SOM is disabled.

Test-Parameters: testlist=sanity-flr env="ONLY=44e,ONLY_REPEAT=20"
Signed-off-by: Patrick Farrell <pfarrell@whamcloud.com>
Change-Id: I338fa7e4dd423b07df0f3c5bad4ec6f02e935fea
Reviewed-on: https://review.whamcloud.com/46683
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: John L. Hammond <jhammond@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/mdt/mdt_handler.c
lustre/mdt/mdt_internal.h
lustre/mdt/mdt_lproc.c
lustre/mdt/mdt_som.c
lustre/tests/sanity-flr.sh

index ba6da25..69cd0bb 100644 (file)
@@ -801,8 +801,9 @@ static inline bool mdt_hsm_is_released(struct lov_mds_md *lmm)
 void mdt_pack_attr2body(struct mdt_thread_info *info, struct mdt_body *b,
                         const struct lu_attr *attr, const struct lu_fid *fid)
 {
-       struct md_attr *ma = &info->mti_attr;
+       struct mdt_device *mdt = info->mti_mdt;
        struct obd_export *exp = info->mti_exp;
+       struct md_attr *ma = &info->mti_attr;
        struct lu_nodemap *nodemap = NULL;
 
        LASSERT(ma->ma_valid & MA_INODE);
@@ -897,7 +898,9 @@ void mdt_pack_attr2body(struct mdt_thread_info *info, struct mdt_body *b,
                        else
                                b->mbo_blocks = 1;
                        b->mbo_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
-               } else if (info->mti_som_valid) { /* som is valid */
+               } else if (info->mti_som_strict &&
+                          mdt->mdt_opts.mo_enable_strict_som) {
+                       /* use SOM for size*/
                        b->mbo_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
                } else if (ma->ma_valid & MA_SOM) { /* lsom is valid */
                        b->mbo_valid |= OBD_MD_FLLAZYSIZE | OBD_MD_FLLAZYBLOCKS;
@@ -4248,7 +4251,7 @@ void mdt_thread_info_init(struct ptlrpc_request *req,
         info->mti_opdata = 0;
        info->mti_big_lmm_used = 0;
        info->mti_big_acl_used = 0;
-       info->mti_som_valid = 0;
+       info->mti_som_strict = 0;
 
         info->mti_spec.no_create = 0;
        info->mti_spec.sp_rm_entry = 0;
@@ -6114,6 +6117,8 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m,
        else
                m->mdt_opts.mo_acl = 0;
 
+       m->mdt_opts.mo_enable_strict_som = 1;
+
        /* XXX: to support suppgid for ACL, we enable identity_upcall
         * by default, otherwise, maybe got unexpected -EACCESS. */
        if (m->mdt_opts.mo_acl)
index 59d9257..a5a9178 100644 (file)
@@ -260,7 +260,8 @@ struct mdt_device {
                                   mo_cos:1,
                                   mo_evict_tgt_nids:1,
                                   mo_dom_read_open:1,
-                                  mo_migrate_hsm_allowed:1;
+                                  mo_migrate_hsm_allowed:1,
+                                  mo_enable_strict_som:1;
                unsigned int       mo_dom_lock;
        } mdt_opts;
         /* mdt state flags */
@@ -488,7 +489,7 @@ struct mdt_thread_info {
        /* big_lmm buffer was used and must be used in reply */
                                   mti_big_lmm_used:1,
                                   mti_big_acl_used:1,
-                                  mti_som_valid:1;
+                                  mti_som_strict:1;
 
        /* opdata for mdt_reint_open(), has the same as
         * ldlm_reply:lock_policy_res1.  mdt_update_last_rcvd() stores this
index e3bfce8..78fb699 100644 (file)
@@ -1046,6 +1046,58 @@ static ssize_t dom_read_open_store(struct kobject *kobj,
 }
 LUSTRE_RW_ATTR(dom_read_open);
 
+/**
+ * Show policy for using strict SOM information for real size (stat size).
+ *
+ * \param[in] m                seq_file handle
+ * \param[in] data     unused
+ *
+ * \retval             0 on success
+ * \retval             negative value on error
+ */
+static ssize_t enable_strict_som_show(struct kobject *kobj,
+                                     struct attribute *attr, char *buf)
+{
+       struct obd_device *obd = container_of(kobj, struct obd_device,
+                                             obd_kset.kobj);
+       struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+       return scnprintf(buf, PAGE_SIZE, "%u\n",
+                        !!mdt->mdt_opts.mo_enable_strict_som);
+}
+
+/**
+ * Modify policy for using strict SOM information for real size (stat size).
+ *
+ * If disabled, SOM is never used for stat.
+ *
+ * \param[in] file     proc file
+ * \param[in] buffer   string which represents policy
+ * \param[in] count    \a buffer length
+ * \param[in] off      unused for single entry
+ *
+ * \retval             \a count on success
+ * \retval             negative number on error
+ */
+static ssize_t enable_strict_som_store(struct kobject *kobj,
+                                      struct attribute *attr,
+                                      const char *buffer, size_t count)
+{
+       struct obd_device *obd = container_of(kobj, struct obd_device,
+                                             obd_kset.kobj);
+       struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+       bool val;
+       int rc;
+
+       rc = kstrtobool(buffer, &val);
+       if (rc)
+               return rc;
+
+       mdt->mdt_opts.mo_enable_strict_som = !!val;
+       return count;
+}
+LUSTRE_RW_ATTR(enable_strict_som);
+
 static ssize_t migrate_hsm_allowed_show(struct kobject *kobj,
                                        struct attribute *attr, char *buf)
 {
@@ -1413,6 +1465,7 @@ static struct attribute *mdt_attrs[] = {
        &lustre_attr_sync_count.attr,
        &lustre_attr_dom_lock.attr,
        &lustre_attr_dom_read_open.attr,
+       &lustre_attr_enable_strict_som.attr,
        &lustre_attr_migrate_hsm_allowed.attr,
        &lustre_attr_hsm_control.attr,
        &lustre_attr_job_cleanup_interval.attr,
index 1f22a30..8bcc862 100644 (file)
@@ -99,7 +99,7 @@ int mdt_get_som(struct mdt_thread_info *info, struct mdt_object *obj,
                         */
                        attr->la_size = som->ms_size;
                        attr->la_blocks = som->ms_blocks;
-                       info->mti_som_valid = 1;
+                       info->mti_som_strict = 1;
                } else if (!obj->mot_lsom_inited &&
                           (som->ms_valid & SOM_FL_LAZY) &&
                           !mutex_is_locked(&obj->mot_som_mutex)) {
@@ -176,7 +176,7 @@ int mdt_lsom_downgrade(struct mdt_thread_info *info, struct mdt_object *o)
        if (tmp_ma->ma_valid & MA_SOM) {
                struct md_som *som = &tmp_ma->ma_som;
 
-               info->mti_som_valid = 0;
+               info->mti_som_strict = 0;
                /* The size and blocks info should be still correct. */
                if (som->ms_valid & SOM_FL_STRICT)
                        rc = mdt_set_som(info, o, SOM_FL_STALE,
index e50979d..781f807 100644 (file)
@@ -2212,6 +2212,54 @@ test_44d() {
 }
 run_test 44d "lfs mirror split does not break size"
 
+test_44e() {
+       local tf=$DIR/$tdir/$tfile
+       local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
+       local size1
+       local size2
+
+       test_mkdir $DIR/$tdir
+       [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
+               skip "Need MDS version at least 2.14.52"
+
+       $LFS mirror create -N2 $tf || error "create mirrored file $tf failed"
+
+       # Disable xattr caching so we can repeatedly check SOM with lfs getsom
+       $LCTL set_param llite.*.xattr_cache=0
+       stack_trap "$LCTL set_param llite.*.xattr_cache=1"
+
+       dd if=/dev/zero of=$tf bs=1M count=10 || error "dd write $tfile failed"
+       sync
+       size1=$(stat -c "%s" $tf)
+       echo " ** before mirror resync, file size=$size1"
+
+       $LFS mirror resync $tf || error "mirror resync file $tf failed"
+       size1=$(stat -c "%s" $tf)
+       size2=$($LFS getsom -s $tf)
+
+       $LFS getsom $tf
+
+       ((size1 == size2)) ||
+               error "mirrored file with strict SOM $size1 != disabled SOM $size2"
+
+       # Remount client to clear cached size information
+       remount_client $MOUNT
+
+       save_lustre_params $(get_facets MDS) mdt.*MDT*.enable_strict_som > $p
+       stack_trap "restore_lustre_params < $p; rm -f $p"
+       local mds_facet=mds$(($($LFS getstripe -m $tf) + 1))
+
+       do_facet $mds_facet $LCTL set_param mdt.*MDT*.enable_strict_som=0
+
+       size2=$(stat -c "%s" $tf)
+       # 'getsom' here is just for debugging
+       $LFS getsom $tf
+
+       ((size2 == size1)) ||
+               error "mirrored file in sync with som disabled, size with som disabled ($size2) and without som disabled ($size1) should agree"
+}
+run_test 44e "basic FLR SOM tests + disable SOM"
+
 test_45() {
        [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"