aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorLuis Henriques <lhenriques@suse.com>2018-01-12 12:19:29 -0500
committerIlya Dryomov <idryomov@gmail.com>2018-04-02 05:17:53 -0400
commitd557c48db730eaab6b75d4af332c135309b7a6a4 (patch)
tree74b28856b9052a36b588d9baf77b5781f8479c97 /fs/ceph
parente3161f17d92699ce6ca3b7988131b10ad4035cf9 (diff)
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 <lhenriques@suse.com> Reviewed-by: "Yan, Zheng" <zyan@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/inode.c6
-rw-r--r--fs/ceph/mds_client.c1
-rw-r--r--fs/ceph/mds_client.h2
-rw-r--r--fs/ceph/quota.c29
-rw-r--r--fs/ceph/super.h20
5 files changed, 51 insertions, 7 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 8ea11b1a2e23..8bf60250309e 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -539,6 +539,9 @@ void ceph_destroy_inode(struct inode *inode)
539 539
540 ceph_queue_caps_release(inode); 540 ceph_queue_caps_release(inode);
541 541
542 if (__ceph_has_any_quota(ci))
543 ceph_adjust_quota_realms_count(inode, false);
544
542 /* 545 /*
543 * we may still have a snap_realm reference if there are stray 546 * we may still have a snap_realm reference if there are stray
544 * caps in i_snap_caps. 547 * caps in i_snap_caps.
@@ -796,8 +799,7 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
796 inode->i_rdev = le32_to_cpu(info->rdev); 799 inode->i_rdev = le32_to_cpu(info->rdev);
797 inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1; 800 inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
798 801
799 ci->i_max_bytes = iinfo->max_bytes; 802 __ceph_update_quota(ci, iinfo->max_bytes, iinfo->max_files);
800 ci->i_max_files = iinfo->max_files;
801 803
802 if ((new_version || (new_issued & CEPH_CAP_AUTH_SHARED)) && 804 if ((new_version || (new_issued & CEPH_CAP_AUTH_SHARED)) &&
803 (issued & CEPH_CAP_AUTH_EXCL) == 0) { 805 (issued & CEPH_CAP_AUTH_EXCL) == 0) {
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 1c9877c1149f..5ece2e6ad154 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -3609,6 +3609,7 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
3609 atomic_set(&mdsc->num_sessions, 0); 3609 atomic_set(&mdsc->num_sessions, 0);
3610 mdsc->max_sessions = 0; 3610 mdsc->max_sessions = 0;
3611 mdsc->stopping = 0; 3611 mdsc->stopping = 0;
3612 atomic64_set(&mdsc->quotarealms_count, 0);
3612 mdsc->last_snap_seq = 0; 3613 mdsc->last_snap_seq = 0;
3613 init_rwsem(&mdsc->snap_rwsem); 3614 init_rwsem(&mdsc->snap_rwsem);
3614 mdsc->snap_realms = RB_ROOT; 3615 mdsc->snap_realms = RB_ROOT;
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index 2a67c8b01ae6..2ec3b5b35067 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -314,6 +314,8 @@ struct ceph_mds_client {
314 int max_sessions; /* len of s_mds_sessions */ 314 int max_sessions; /* len of s_mds_sessions */
315 int stopping; /* true if shutting down */ 315 int stopping; /* true if shutting down */
316 316
317 atomic64_t quotarealms_count; /* # realms with quota */
318
317 /* 319 /*
318 * snap_rwsem will cover cap linkage into snaprealms, and 320 * snap_rwsem will cover cap linkage into snaprealms, and
319 * realm snap contexts. (later, we can do per-realm snap 321 * realm snap contexts. (later, we can do per-realm snap
diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c
index c561a85ea8b1..588744b4665f 100644
--- a/fs/ceph/quota.c
+++ b/fs/ceph/quota.c
@@ -21,9 +21,19 @@
21#include "super.h" 21#include "super.h"
22#include "mds_client.h" 22#include "mds_client.h"
23 23
24static inline bool ceph_has_quota(struct ceph_inode_info *ci) 24void ceph_adjust_quota_realms_count(struct inode *inode, bool inc)
25{ 25{
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
33static 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;
27} 37}
28 38
29void ceph_handle_quota(struct ceph_mds_client *mdsc, 39void ceph_handle_quota(struct ceph_mds_client *mdsc,
@@ -62,8 +72,8 @@ void ceph_handle_quota(struct ceph_mds_client *mdsc,
62 ci->i_rbytes = le64_to_cpu(h->rbytes); 72 ci->i_rbytes = le64_to_cpu(h->rbytes);
63 ci->i_rfiles = le64_to_cpu(h->rfiles); 73 ci->i_rfiles = le64_to_cpu(h->rfiles);
64 ci->i_rsubdirs = le64_to_cpu(h->rsubdirs); 74 ci->i_rsubdirs = le64_to_cpu(h->rsubdirs);
65 ci->i_max_bytes = le64_to_cpu(h->max_bytes); 75 __ceph_update_quota(ci, le64_to_cpu(h->max_bytes),
66 ci->i_max_files = le64_to_cpu(h->max_files); 76 le64_to_cpu(h->max_files));
67 spin_unlock(&ci->i_ceph_lock); 77 spin_unlock(&ci->i_ceph_lock);
68 78
69 iput(inode); 79 iput(inode);
@@ -103,7 +113,7 @@ static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc,
103 break; 113 break;
104 114
105 ci = ceph_inode(in); 115 ci = ceph_inode(in);
106 has_quota = ceph_has_quota(ci); 116 has_quota = __ceph_has_any_quota(ci);
107 iput(in); 117 iput(in);
108 118
109 next = realm->parent; 119 next = realm->parent;
@@ -241,6 +251,9 @@ static bool check_quota_exceeded(struct inode *inode, enum quota_check_op op,
241 */ 251 */
242bool ceph_quota_is_max_files_exceeded(struct inode *inode) 252bool ceph_quota_is_max_files_exceeded(struct inode *inode)
243{ 253{
254 if (!ceph_has_realms_with_quotas(inode))
255 return false;
256
244 WARN_ON(!S_ISDIR(inode->i_mode)); 257 WARN_ON(!S_ISDIR(inode->i_mode));
245 258
246 return check_quota_exceeded(inode, QUOTA_CHECK_MAX_FILES_OP, 0); 259 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)
258{ 271{
259 loff_t size = i_size_read(inode); 272 loff_t size = i_size_read(inode);
260 273
274 if (!ceph_has_realms_with_quotas(inode))
275 return false;
276
261 /* return immediately if we're decreasing file size */ 277 /* return immediately if we're decreasing file size */
262 if (newsize <= size) 278 if (newsize <= size)
263 return false; 279 return false;
@@ -277,6 +293,9 @@ bool ceph_quota_is_max_bytes_approaching(struct inode *inode, loff_t newsize)
277{ 293{
278 loff_t size = ceph_inode(inode)->i_reported_size; 294 loff_t size = ceph_inode(inode)->i_reported_size;
279 295
296 if (!ceph_has_realms_with_quotas(inode))
297 return false;
298
280 /* return immediately if we're decreasing file size */ 299 /* return immediately if we're decreasing file size */
281 if (newsize <= size) 300 if (newsize <= size)
282 return false; 301 return false;
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 8217abf46182..1321a6749953 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -1075,6 +1075,26 @@ extern int ceph_fs_debugfs_init(struct ceph_fs_client *client);
1075extern void ceph_fs_debugfs_cleanup(struct ceph_fs_client *client); 1075extern void ceph_fs_debugfs_cleanup(struct ceph_fs_client *client);
1076 1076
1077/* quota.c */ 1077/* quota.c */
1078static inline bool __ceph_has_any_quota(struct ceph_inode_info *ci)
1079{
1080 return ci->i_max_files || ci->i_max_bytes;
1081}
1082
1083extern void ceph_adjust_quota_realms_count(struct inode *inode, bool inc);
1084
1085static 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
1078extern void ceph_handle_quota(struct ceph_mds_client *mdsc, 1098extern void ceph_handle_quota(struct ceph_mds_client *mdsc,
1079 struct ceph_mds_session *session, 1099 struct ceph_mds_session *session,
1080 struct ceph_msg *msg); 1100 struct ceph_msg *msg);