aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/caps.c
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-02-17 13:02:43 -0500
committerSage Weil <sage@newdream.net>2010-02-17 13:02:43 -0500
commit85ccce43a3fc15a40ded6ae1603e3f68a17f4d24 (patch)
tree1e15fb7dc7df43da4a3feacff671c8169e96291d /fs/ceph/caps.c
parent5ce6e9dbe6805ab8ee67e21936d17f431adc63c6 (diff)
ceph: clean up readdir caps reservation
Use a global counter for the minimum number of allocated caps instead of hard coding a check against readdir_max. This takes into account multiple client instances, and avoids examining the superblock mount options when a cap is dropped. Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r--fs/ceph/caps.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index ab9b571dda11..f94b56faba3b 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -128,6 +128,7 @@ static int caps_total_count; /* total caps allocated */
128static int caps_use_count; /* in use */ 128static int caps_use_count; /* in use */
129static int caps_reserve_count; /* unused, reserved */ 129static int caps_reserve_count; /* unused, reserved */
130static int caps_avail_count; /* unused, unreserved */ 130static int caps_avail_count; /* unused, unreserved */
131static int caps_min_count; /* keep at least this many (unreserved) */
131 132
132void __init ceph_caps_init(void) 133void __init ceph_caps_init(void)
133{ 134{
@@ -149,6 +150,15 @@ void ceph_caps_finalize(void)
149 caps_avail_count = 0; 150 caps_avail_count = 0;
150 caps_use_count = 0; 151 caps_use_count = 0;
151 caps_reserve_count = 0; 152 caps_reserve_count = 0;
153 caps_min_count = 0;
154 spin_unlock(&caps_list_lock);
155}
156
157void ceph_adjust_min_caps(int delta)
158{
159 spin_lock(&caps_list_lock);
160 caps_min_count += delta;
161 BUG_ON(caps_min_count < 0);
152 spin_unlock(&caps_list_lock); 162 spin_unlock(&caps_list_lock);
153} 163}
154 164
@@ -265,12 +275,10 @@ static void put_cap(struct ceph_cap *cap,
265 caps_reserve_count, caps_avail_count); 275 caps_reserve_count, caps_avail_count);
266 caps_use_count--; 276 caps_use_count--;
267 /* 277 /*
268 * Keep some preallocated caps around, at least enough to do a 278 * Keep some preallocated caps around (ceph_min_count), to
269 * readdir (which needs to preallocate lots of them), to avoid 279 * avoid lots of free/alloc churn.
270 * lots of free/alloc churn.
271 */ 280 */
272 if (caps_avail_count >= caps_reserve_count + 281 if (caps_avail_count >= caps_reserve_count + caps_min_count) {
273 ceph_client(cap->ci->vfs_inode.i_sb)->mount_args->max_readdir) {
274 caps_total_count--; 282 caps_total_count--;
275 kmem_cache_free(ceph_cap_cachep, cap); 283 kmem_cache_free(ceph_cap_cachep, cap);
276 } else { 284 } else {
@@ -289,7 +297,8 @@ static void put_cap(struct ceph_cap *cap,
289} 297}
290 298
291void ceph_reservation_status(struct ceph_client *client, 299void ceph_reservation_status(struct ceph_client *client,
292 int *total, int *avail, int *used, int *reserved) 300 int *total, int *avail, int *used, int *reserved,
301 int *min)
293{ 302{
294 if (total) 303 if (total)
295 *total = caps_total_count; 304 *total = caps_total_count;
@@ -299,6 +308,8 @@ void ceph_reservation_status(struct ceph_client *client,
299 *used = caps_use_count; 308 *used = caps_use_count;
300 if (reserved) 309 if (reserved)
301 *reserved = caps_reserve_count; 310 *reserved = caps_reserve_count;
311 if (min)
312 *min = caps_min_count;
302} 313}
303 314
304/* 315/*