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 (!obj->mot_lsom_inited &&
(som->ms_valid & SOM_FL_LAZY) &&
!mutex_is_locked(&obj->mot_som_mutex)) {
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"