Skip to content

Commit d557c48

Browse files
Luis Henriquesidryomov
authored andcommitted
ceph: quota: add counter for snaprealms with quota
By keeping a counter with the number of snaprealms that have quota set allows to optimize the functions that need to walk throught the realms hierarchy looking for quotas. Thus, if this counter is zero it's safe to assume that there are no realms with quota. Signed-off-by: Luis Henriques <[email protected]> Reviewed-by: "Yan, Zheng" <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
1 parent e3161f1 commit d557c48

File tree

5 files changed

+51
-7
lines changed

5 files changed

+51
-7
lines changed

fs/ceph/inode.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,9 @@ void ceph_destroy_inode(struct inode *inode)
539539

540540
ceph_queue_caps_release(inode);
541541

542+
if (__ceph_has_any_quota(ci))
543+
ceph_adjust_quota_realms_count(inode, false);
544+
542545
/*
543546
* we may still have a snap_realm reference if there are stray
544547
* caps in i_snap_caps.
@@ -796,8 +799,7 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
796799
inode->i_rdev = le32_to_cpu(info->rdev);
797800
inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
798801

799-
ci->i_max_bytes = iinfo->max_bytes;
800-
ci->i_max_files = iinfo->max_files;
802+
__ceph_update_quota(ci, iinfo->max_bytes, iinfo->max_files);
801803

802804
if ((new_version || (new_issued & CEPH_CAP_AUTH_SHARED)) &&
803805
(issued & CEPH_CAP_AUTH_EXCL) == 0) {

fs/ceph/mds_client.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3609,6 +3609,7 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
36093609
atomic_set(&mdsc->num_sessions, 0);
36103610
mdsc->max_sessions = 0;
36113611
mdsc->stopping = 0;
3612+
atomic64_set(&mdsc->quotarealms_count, 0);
36123613
mdsc->last_snap_seq = 0;
36133614
init_rwsem(&mdsc->snap_rwsem);
36143615
mdsc->snap_realms = RB_ROOT;

fs/ceph/mds_client.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ struct ceph_mds_client {
314314
int max_sessions; /* len of s_mds_sessions */
315315
int stopping; /* true if shutting down */
316316

317+
atomic64_t quotarealms_count; /* # realms with quota */
318+
317319
/*
318320
* snap_rwsem will cover cap linkage into snaprealms, and
319321
* realm snap contexts. (later, we can do per-realm snap

fs/ceph/quota.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,19 @@
2121
#include "super.h"
2222
#include "mds_client.h"
2323

24-
static inline bool ceph_has_quota(struct ceph_inode_info *ci)
24+
void ceph_adjust_quota_realms_count(struct inode *inode, bool inc)
2525
{
26-
return (ci && (ci->i_max_files || ci->i_max_bytes));
26+
struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
27+
if (inc)
28+
atomic64_inc(&mdsc->quotarealms_count);
29+
else
30+
atomic64_dec(&mdsc->quotarealms_count);
31+
}
32+
33+
static inline bool ceph_has_realms_with_quotas(struct inode *inode)
34+
{
35+
struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
36+
return atomic64_read(&mdsc->quotarealms_count) > 0;
2737
}
2838

2939
void ceph_handle_quota(struct ceph_mds_client *mdsc,
@@ -62,8 +72,8 @@ void ceph_handle_quota(struct ceph_mds_client *mdsc,
6272
ci->i_rbytes = le64_to_cpu(h->rbytes);
6373
ci->i_rfiles = le64_to_cpu(h->rfiles);
6474
ci->i_rsubdirs = le64_to_cpu(h->rsubdirs);
65-
ci->i_max_bytes = le64_to_cpu(h->max_bytes);
66-
ci->i_max_files = le64_to_cpu(h->max_files);
75+
__ceph_update_quota(ci, le64_to_cpu(h->max_bytes),
76+
le64_to_cpu(h->max_files));
6777
spin_unlock(&ci->i_ceph_lock);
6878

6979
iput(inode);
@@ -103,7 +113,7 @@ static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc,
103113
break;
104114

105115
ci = ceph_inode(in);
106-
has_quota = ceph_has_quota(ci);
116+
has_quota = __ceph_has_any_quota(ci);
107117
iput(in);
108118

109119
next = realm->parent;
@@ -241,6 +251,9 @@ static bool check_quota_exceeded(struct inode *inode, enum quota_check_op op,
241251
*/
242252
bool ceph_quota_is_max_files_exceeded(struct inode *inode)
243253
{
254+
if (!ceph_has_realms_with_quotas(inode))
255+
return false;
256+
244257
WARN_ON(!S_ISDIR(inode->i_mode));
245258

246259
return check_quota_exceeded(inode, QUOTA_CHECK_MAX_FILES_OP, 0);
@@ -258,6 +271,9 @@ bool ceph_quota_is_max_bytes_exceeded(struct inode *inode, loff_t newsize)
258271
{
259272
loff_t size = i_size_read(inode);
260273

274+
if (!ceph_has_realms_with_quotas(inode))
275+
return false;
276+
261277
/* return immediately if we're decreasing file size */
262278
if (newsize <= size)
263279
return false;
@@ -277,6 +293,9 @@ bool ceph_quota_is_max_bytes_approaching(struct inode *inode, loff_t newsize)
277293
{
278294
loff_t size = ceph_inode(inode)->i_reported_size;
279295

296+
if (!ceph_has_realms_with_quotas(inode))
297+
return false;
298+
280299
/* return immediately if we're decreasing file size */
281300
if (newsize <= size)
282301
return false;

fs/ceph/super.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,26 @@ extern int ceph_fs_debugfs_init(struct ceph_fs_client *client);
10751075
extern void ceph_fs_debugfs_cleanup(struct ceph_fs_client *client);
10761076

10771077
/* quota.c */
1078+
static inline bool __ceph_has_any_quota(struct ceph_inode_info *ci)
1079+
{
1080+
return ci->i_max_files || ci->i_max_bytes;
1081+
}
1082+
1083+
extern void ceph_adjust_quota_realms_count(struct inode *inode, bool inc);
1084+
1085+
static inline void __ceph_update_quota(struct ceph_inode_info *ci,
1086+
u64 max_bytes, u64 max_files)
1087+
{
1088+
bool had_quota, has_quota;
1089+
had_quota = __ceph_has_any_quota(ci);
1090+
ci->i_max_bytes = max_bytes;
1091+
ci->i_max_files = max_files;
1092+
has_quota = __ceph_has_any_quota(ci);
1093+
1094+
if (had_quota != has_quota)
1095+
ceph_adjust_quota_realms_count(&ci->vfs_inode, has_quota);
1096+
}
1097+
10781098
extern void ceph_handle_quota(struct ceph_mds_client *mdsc,
10791099
struct ceph_mds_session *session,
10801100
struct ceph_msg *msg);

0 commit comments

Comments
 (0)