aboutsummaryrefslogtreecommitdiffstats
path: root/fs
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
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')
-rw-r--r--fs/ceph/caps.c23
-rw-r--r--fs/ceph/debugfs.c13
-rw-r--r--fs/ceph/super.c5
-rw-r--r--fs/ceph/super.h5
4 files changed, 33 insertions, 13 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/*
diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c
index b58bd9188692..1a47b5c25b5f 100644
--- a/fs/ceph/debugfs.c
+++ b/fs/ceph/debugfs.c
@@ -255,14 +255,15 @@ static int osdc_show(struct seq_file *s, void *pp)
255static int caps_show(struct seq_file *s, void *p) 255static int caps_show(struct seq_file *s, void *p)
256{ 256{
257 struct ceph_client *client = p; 257 struct ceph_client *client = p;
258 int total, avail, used, reserved; 258 int total, avail, used, reserved, min;
259 259
260 ceph_reservation_status(client, &total, &avail, &used, &reserved); 260 ceph_reservation_status(client, &total, &avail, &used, &reserved, &min);
261 seq_printf(s, "total\t\t%d\n" 261 seq_printf(s, "total\t\t%d\n"
262 "avail\t\t%d\n" 262 "avail\t\t%d\n"
263 "used\t\t%d\n" 263 "used\t\t%d\n"
264 "reserved\t%d\n", 264 "reserved\t%d\n"
265 total, avail, used, reserved); 265 "min\t%d\n",
266 total, avail, used, reserved, min);
266 return 0; 267 return 0;
267} 268}
268 269
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index 39aaf29a04a0..74953be75f8f 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -578,6 +578,9 @@ static struct ceph_client *ceph_create_client(struct ceph_mount_args *args)
578 if (!client->wb_pagevec_pool) 578 if (!client->wb_pagevec_pool)
579 goto fail_trunc_wq; 579 goto fail_trunc_wq;
580 580
581 /* caps */
582 client->min_caps = args->max_readdir;
583 ceph_adjust_min_caps(client->min_caps);
581 584
582 /* subsystems */ 585 /* subsystems */
583 err = ceph_monc_init(&client->monc, client); 586 err = ceph_monc_init(&client->monc, client);
@@ -619,6 +622,8 @@ static void ceph_destroy_client(struct ceph_client *client)
619 ceph_monc_stop(&client->monc); 622 ceph_monc_stop(&client->monc);
620 ceph_osdc_stop(&client->osdc); 623 ceph_osdc_stop(&client->osdc);
621 624
625 ceph_adjust_min_caps(-client->min_caps);
626
622 ceph_debugfs_client_cleanup(client); 627 ceph_debugfs_client_cleanup(client);
623 destroy_workqueue(client->wb_wq); 628 destroy_workqueue(client->wb_wq);
624 destroy_workqueue(client->pg_inv_wq); 629 destroy_workqueue(client->pg_inv_wq);
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 1f3928785e12..3b5faf9980f8 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -129,6 +129,8 @@ struct ceph_client {
129 129
130 int auth_err; 130 int auth_err;
131 131
132 int min_caps; /* min caps i added */
133
132 struct ceph_messenger *msgr; /* messenger instance */ 134 struct ceph_messenger *msgr; /* messenger instance */
133 struct ceph_mon_client monc; 135 struct ceph_mon_client monc;
134 struct ceph_mds_client mdsc; 136 struct ceph_mds_client mdsc;
@@ -557,11 +559,12 @@ extern int __ceph_caps_mds_wanted(struct ceph_inode_info *ci);
557 559
558extern void ceph_caps_init(void); 560extern void ceph_caps_init(void);
559extern void ceph_caps_finalize(void); 561extern void ceph_caps_finalize(void);
562extern void ceph_adjust_min_caps(int delta);
560extern int ceph_reserve_caps(struct ceph_cap_reservation *ctx, int need); 563extern int ceph_reserve_caps(struct ceph_cap_reservation *ctx, int need);
561extern int ceph_unreserve_caps(struct ceph_cap_reservation *ctx); 564extern int ceph_unreserve_caps(struct ceph_cap_reservation *ctx);
562extern void ceph_reservation_status(struct ceph_client *client, 565extern void ceph_reservation_status(struct ceph_client *client,
563 int *total, int *avail, int *used, 566 int *total, int *avail, int *used,
564 int *reserved); 567 int *reserved, int *min);
565 568
566static inline struct ceph_client *ceph_inode_to_client(struct inode *inode) 569static inline struct ceph_client *ceph_inode_to_client(struct inode *inode)
567{ 570{