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 */
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);
{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"},
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
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();
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;
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;
}
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)
&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,
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"
# 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"