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.
Lustre-change: https://review.whamcloud.com/46683/
Lustre-commit:
2867d497b92f43f06edd7c378828f1fb8c3b300c (tbd)
Signed-off-by: Patrick Farrell <pfarrell@whamcloud.com>
Change-Id: I338fa7e4dd423b07df0f3c5bad4ec6f02e935fea
Reviewed-on: https://review.whamcloud.com/46709
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: John L. Hammond <jhammond@whamcloud.com>
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);
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;
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;
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)
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 */
/* 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
}
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)
{
&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,
*/
attr->la_size = som->ms_size;
attr->la_blocks = som->ms_blocks;
- info->mti_som_valid = 1;
+ info->mti_som_strict = 1;
}
} else if (rc == -ENODATA) {
rc = 0;
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,
}
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"