From: Stephane Thiell Date: Fri, 3 Nov 2023 04:24:26 +0000 (-0700) Subject: LU-16771 llite: add statfs_project tunable X-Git-Tag: 2.15.60~11 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=refs%2Fchanges%2F72%2F52872%2F5;p=fs%2Flustre-release.git LU-16771 llite: add statfs_project tunable 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 Change-Id: I1c3eb27e66b1d05a1c713732dfe0a4d8f7af769f Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52872 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Alexander Boyko Reviewed-by: Alexander Zarochentsev Reviewed-by: Oleg Drokin --- diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 399e69a..115c06e 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -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 */ diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 6ddd3b9..68d3926 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -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; diff --git a/lustre/llite/lproc_llite.c b/lustre/llite/lproc_llite.c index 060e8fb..51b607e 100644 --- a/lustre/llite/lproc_llite.c +++ b/lustre/llite/lproc_llite.c @@ -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, diff --git a/lustre/tests/sanity-quota.sh b/lustre/tests/sanity-quota.sh index 066bf86..ca314fa 100755 --- a/lustre/tests/sanity-quota.sh +++ b/lustre/tests/sanity-quota.sh @@ -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"