Whamcloud - gitweb
LU-16771 llite: add statfs_project tunable 72/52872/5
authorStephane Thiell <sthiell@stanford.edu>
Fri, 3 Nov 2023 04:24:26 +0000 (21:24 -0700)
committerOleg Drokin <green@whamcloud.com>
Wed, 3 Jan 2024 03:02:34 +0000 (03:02 +0000)
Add a client tunable and mount option to turn off project-enabled
statfs() if needed, for example to speed up statfs() execution by
avoiding project quota check.

This new llite tunable statfs_project is set to 1 by default (feature
enabled). To turn statfs_project off:

    lctl set_param llite.*.statfs_project=0

Additionally, statfs_project can be disabled at mount time with:

   mount -t lustre -o nostatfs_project ...

Signed-off-by: Stephane Thiell <sthiell@stanford.edu>
Change-Id: I1c3eb27e66b1d05a1c713732dfe0a4d8f7af769f
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52872
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Alexander Boyko <alexander.boyko@hpe.com>
Reviewed-by: Alexander Zarochentsev <alexander.zarochentsev@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/lproc_llite.c
lustre/tests/sanity-quota.sh

index 399e69a..115c06e 100644 (file)
@@ -809,6 +809,7 @@ enum ll_sbi_flags {
        LL_SBI_ENCRYPT,                 /* client side encryption */
        LL_SBI_FOREIGN_SYMLINK,         /* foreign fake-symlink support */
        LL_SBI_FOREIGN_SYMLINK_UPCALL,  /* foreign fake-symlink upcall set */
+       LL_SBI_STATFS_PROJECT,          /* statfs returns project quota */
        LL_SBI_NUM_MOUNT_OPT,
 
        LL_SBI_ACL,                     /* support ACL */
index 6ddd3b9..68d3926 100644 (file)
@@ -199,6 +199,7 @@ static struct ll_sb_info *ll_init_sbi(struct lustre_sb_info *lsi)
        set_bit(LL_SBI_TINY_WRITE, sbi->ll_flags);
        set_bit(LL_SBI_PARALLEL_DIO, sbi->ll_flags);
        set_bit(LL_SBI_UNALIGNED_DIO, sbi->ll_flags);
+       set_bit(LL_SBI_STATFS_PROJECT, sbi->ll_flags);
        ll_sbi_set_encrypt(sbi, true);
        ll_sbi_set_name_encrypt(sbi, true);
 
@@ -1003,6 +1004,8 @@ static const match_table_t ll_sbi_flags_name = {
        {LL_SBI_ENCRYPT,                "encrypt"},
        {LL_SBI_ENCRYPT,                "noencrypt"},
        {LL_SBI_FOREIGN_SYMLINK,        "foreign_symlink=%s"},
+       {LL_SBI_STATFS_PROJECT,         "statfs_project"},
+       {LL_SBI_STATFS_PROJECT,         "nostatfs_project"},
        {LL_SBI_NUM_MOUNT_OPT,          NULL},
 
        {LL_SBI_ACL,                    "acl"},
@@ -1126,6 +1129,7 @@ static int ll_options(char *options, struct super_block *sb)
                case LL_SBI_LRU_RESIZE:
                case LL_SBI_LAZYSTATFS:
                case LL_SBI_VERBOSE:
+               case LL_SBI_STATFS_PROJECT:
                        if (turn_off)
                                clear_bit(token, sbi->ll_flags);
                        else
@@ -2638,6 +2642,7 @@ static int ll_statfs_project(struct inode *inode, struct kstatfs *sfs)
 int ll_statfs(struct dentry *de, struct kstatfs *sfs)
 {
        struct super_block *sb = de->d_sb;
+       struct ll_sb_info *sbi = ll_s2sbi(sb);
        struct obd_statfs osfs;
        __u64 fsid = huge_encode_dev(sb->s_dev);
        ktime_t kstart = ktime_get();
@@ -2646,7 +2651,7 @@ int ll_statfs(struct dentry *de, struct kstatfs *sfs)
        CDEBUG(D_VFSTRACE, "VFS Op:sb=%s (%p)\n", sb->s_id, sb);
 
        /* Some amount of caching on the client is allowed */
-       rc = ll_statfs_internal(ll_s2sbi(sb), &osfs, OBD_STATFS_SUM);
+       rc = ll_statfs_internal(sbi, &osfs, OBD_STATFS_SUM);
        if (rc)
                return rc;
 
@@ -2672,10 +2677,11 @@ int ll_statfs(struct dentry *de, struct kstatfs *sfs)
        sfs->f_fsid.val[0] = (__u32)fsid;
        sfs->f_fsid.val[1] = (__u32)(fsid >> 32);
        if (ll_i2info(de->d_inode)->lli_projid &&
+               test_bit(LL_SBI_STATFS_PROJECT, sbi->ll_flags) &&
            test_bit(LLIF_PROJECT_INHERIT, &ll_i2info(de->d_inode)->lli_flags))
                return ll_statfs_project(de->d_inode, sfs);
 
-       ll_stats_ops_tally(ll_s2sbi(sb), LPROC_LL_STATFS,
+       ll_stats_ops_tally(sbi, LPROC_LL_STATFS,
                           ktime_us_delta(ktime_get(), kstart));
 
        return 0;
index 060e8fb..51b607e 100644 (file)
@@ -1081,6 +1081,40 @@ static ssize_t statfs_max_age_store(struct kobject *kobj,
 }
 LUSTRE_RW_ATTR(statfs_max_age);
 
+static ssize_t statfs_project_show(struct kobject *kobj,
+                                 struct attribute *attr,
+                                 char *buf)
+{
+       struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+                                             ll_kset.kobj);
+
+       return scnprintf(buf, PAGE_SIZE, "%u\n",
+                        test_bit(LL_SBI_STATFS_PROJECT, sbi->ll_flags));
+}
+
+static ssize_t statfs_project_store(struct kobject *kobj,
+                                  struct attribute *attr,
+                                  const char *buffer,
+                                  size_t count)
+{
+       struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+                                             ll_kset.kobj);
+       bool val;
+       int rc;
+
+       rc = kstrtobool(buffer, &val);
+       if (rc)
+               return rc;
+
+       if (val)
+               set_bit(LL_SBI_STATFS_PROJECT, sbi->ll_flags);
+       else
+               clear_bit(LL_SBI_STATFS_PROJECT, sbi->ll_flags);
+
+       return count;
+}
+LUSTRE_RW_ATTR(statfs_project);
+
 static ssize_t max_easize_show(struct kobject *kobj,
                               struct attribute *attr,
                               char *buf)
@@ -2027,6 +2061,7 @@ static struct attribute *llite_attrs[] = {
        &lustre_attr_statahead_agl.attr,
        &lustre_attr_lazystatfs.attr,
        &lustre_attr_statfs_max_age.attr,
+       &lustre_attr_statfs_project.attr,
        &lustre_attr_max_easize.attr,
        &lustre_attr_default_easize.attr,
        &lustre_attr_xattr_cache.attr,
index 066bf86..ca314fa 100755 (executable)
@@ -3875,6 +3875,11 @@ test_41() {
        set_mdt_qtype ugp || error "enable mdt quota failed"
        set_ost_qtype ugp || error "enable ost quota failed"
 
+       local statfs_prj_orig=$($LCTL get_param -n llite.*.statfs_project)
+       (( statfs_prj_orig == 1 )) ||
+               $LCTL set_param llite.*.statfs_project=1
+       stack_trap "$LCTL set_param llite.*.statfs_project=$statfs_prj_orig"
+
        test_mkdir -p $dir && change_project -sp $projid $dir
        $LFS setquota -p $projid -b 0 -B ${blimit}K -i 0 -I $ilimit $dir ||
                error "set project quota failed"
@@ -3905,6 +3910,18 @@ test_41() {
        # larger than quota result, but it's no more than 3K
        expected=$(df -kP $dir | awk "/$FSNAME/"' {print $3}')
        (( expected - bused < 4)) || error "bused mismatch: $expected != $bused"
+
+       # disable statfs_project and check again
+       $LCTL set_param llite.*.statfs_project=0
+
+       expected=$({ df -kP $MOUNT; df -iP $MOUNT; } | \
+               awk '/'$FSNAME'/ { printf "%d %d ", $2,$3 }')
+
+       wait_update $HOSTNAME \
+               "{ df -kP $dir; df -iP $dir; } |
+                awk '/$FSNAME/ { printf \\\"%d %d \\\", \\\$2,\\\$3 }'" \
+               "$expected" ||
+               error "failed to get correct statfs when statfs_project=0"
 }
 run_test 41 "df should return projid-specific values"