Skip to content

Commit 0666c09

Browse files
authored
Merge pull request ceph#65918 from chrisphoffman/wip-choffman-73487
client: account for mixed quotas in statfs Reviewed-by: Venky Shankar <[email protected]>
2 parents ee73c5e + 2b057ec commit 0666c09

File tree

2 files changed

+11
-8
lines changed

2 files changed

+11
-8
lines changed

src/client/Client.cc

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13532,9 +13532,10 @@ int Client::_statfs(Inode *in, struct statvfs *stbuf,
1353213532
// Usually quota_root will == root_ancestor, but if the mount root has no
1353313533
// quota but we can see a parent of it that does have a quota, we'll
1353413534
// respect that one instead.
13535-
InodeRef quota_root = in->quota.is_enabled() ? in : get_quota_root(in, perms);
13535+
InodeRef qr_bytes = in->quota.is_enabled(QUOTA_MAX_BYTES) ? in : get_quota_root(in, perms, QUOTA_MAX_BYTES);
13536+
InodeRef qr_files = in->quota.is_enabled(QUOTA_MAX_FILES) ? in : get_quota_root(in, perms, QUOTA_MAX_FILES);
1353613537

13537-
total_files_on_fs = quota_root->rstat.rfiles + quota_root->rstat.rsubdirs;
13538+
total_files_on_fs = qr_files->rstat.rfiles + qr_files->rstat.rsubdirs;
1353813539

1353913540
if (rval < 0) {
1354013541
ldout(cct, 1) << "underlying call to statfs returned error: "
@@ -13564,32 +13565,32 @@ int Client::_statfs(Inode *in, struct statvfs *stbuf,
1356413565

1356513566
// get_quota_root should always give us something if client quotas are
1356613567
// enabled
13567-
ceph_assert(cct->_conf.get_val<bool>("client_quota") == false || quota_root != nullptr);
13568+
ceph_assert(cct->_conf.get_val<bool>("client_quota") == false || qr_bytes != nullptr);
1356813569

1356913570
/* If bytes quota is set on a directory and conf option "client quota df"
1357013571
* is also set, available space = quota limit - used space. Else,
1357113572
* available space = total space - used space. */
13572-
if (quota_root && cct->_conf->client_quota_df && quota_root->quota.max_bytes) {
13573+
if (qr_bytes && cct->_conf->client_quota_df && qr_bytes->quota.max_bytes) {
1357313574

1357413575
// Skip the getattr if any sessions are stale, as we don't want to
1357513576
// block `df` if this client has e.g. been evicted, or if the MDS cluster
1357613577
// is unhealthy.
1357713578
if (!_any_stale_sessions()) {
13578-
int r = _getattr(quota_root, 0, perms, true);
13579+
int r = _getattr(qr_bytes, 0, perms, true);
1357913580
if (r != 0) {
1358013581
// Ignore return value: error getting latest inode metadata is not a good
1358113582
// reason to break "df".
1358213583
lderr(cct) << "Error in getattr on quota root 0x"
13583-
<< std::hex << quota_root->ino << std::dec
13584+
<< std::hex << qr_bytes->ino << std::dec
1358413585
<< " statfs result may be outdated" << dendl;
1358513586
}
1358613587
}
1358713588

1358813589
// Special case: if there is a size quota set on the Inode acting
1358913590
// as the root for this client mount, then report the quota status
1359013591
// as the filesystem statistics.
13591-
const fsblkcnt_t total = quota_root->quota.max_bytes >> CEPH_BLOCK_SHIFT;
13592-
const fsblkcnt_t used = quota_root->rstat.rbytes >> CEPH_BLOCK_SHIFT;
13592+
const fsblkcnt_t total = qr_bytes->quota.max_bytes >> CEPH_BLOCK_SHIFT;
13593+
const fsblkcnt_t used = qr_bytes->rstat.rbytes >> CEPH_BLOCK_SHIFT;
1359313594
// It is possible for a quota to be exceeded: arithmetic here must
1359413595
// handle case where used > total.
1359513596
const fsblkcnt_t free = total > used ? total - used : 0;

src/test/libcephfs/test.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,6 +1045,7 @@ TEST(LibCephFS, StatfsQuota) {
10451045

10461046
ASSERT_EQ(0, ceph_mkdir(cmount, quota_dir, 0777));
10471047
EXPECT_EQ(0, ceph_setxattr(cmount, quota_dir, "ceph.quota.max_files", "10000", 05, 0));
1048+
EXPECT_EQ(0, ceph_setxattr(cmount, "/", "ceph.quota.max_bytes", "20G", 03, 0));
10481049

10491050
const int num_quota_files = 1;
10501051
char quota_file[256];
@@ -1073,6 +1074,7 @@ TEST(LibCephFS, StatfsQuota) {
10731074
struct statvfs reg_stvbuf;
10741075
ASSERT_EQ(0, ceph_statfs(cmount, "test_statfs_regular_1", &reg_stvbuf));
10751076
ASSERT_GT(reg_stvbuf.f_files, quota_stvbuf.f_files);
1077+
ASSERT_EQ(21474836480, quota_stvbuf.f_blocks*quota_stvbuf.f_bsize);
10761078

10771079
for (int i = 0; i < num_reg_files; i++) {
10781080
sprintf(regular_file, "test_statfs_regular_%d", i);

0 commit comments

Comments
 (0)