diff options
author | Sage Weil <sage@newdream.net> | 2010-02-17 10:02:43 -0800 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-02-17 10:02:43 -0800 |
commit | 85ccce43a3fc15a40ded6ae1603e3f68a17f4d24 (patch) | |
tree | 1e15fb7dc7df43da4a3feacff671c8169e96291d /fs/ceph/caps.c | |
parent | 5ce6e9dbe6805ab8ee67e21936d17f431adc63c6 (diff) | |
download | op-kernel-dev-85ccce43a3fc15a40ded6ae1603e3f68a17f4d24.zip op-kernel-dev-85ccce43a3fc15a40ded6ae1603e3f68a17f4d24.tar.gz |
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.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index ab9b571..f94b56f 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -128,6 +128,7 @@ static int caps_total_count; /* total caps allocated */ static int caps_use_count; /* in use */ static int caps_reserve_count; /* unused, reserved */ static int caps_avail_count; /* unused, unreserved */ +static int caps_min_count; /* keep at least this many (unreserved) */ void __init ceph_caps_init(void) { @@ -149,6 +150,15 @@ void ceph_caps_finalize(void) caps_avail_count = 0; caps_use_count = 0; caps_reserve_count = 0; + caps_min_count = 0; + spin_unlock(&caps_list_lock); +} + +void ceph_adjust_min_caps(int delta) +{ + spin_lock(&caps_list_lock); + caps_min_count += delta; + BUG_ON(caps_min_count < 0); spin_unlock(&caps_list_lock); } @@ -265,12 +275,10 @@ static void put_cap(struct ceph_cap *cap, caps_reserve_count, caps_avail_count); caps_use_count--; /* - * Keep some preallocated caps around, at least enough to do a - * readdir (which needs to preallocate lots of them), to avoid - * lots of free/alloc churn. + * Keep some preallocated caps around (ceph_min_count), to + * avoid lots of free/alloc churn. */ - if (caps_avail_count >= caps_reserve_count + - ceph_client(cap->ci->vfs_inode.i_sb)->mount_args->max_readdir) { + if (caps_avail_count >= caps_reserve_count + caps_min_count) { caps_total_count--; kmem_cache_free(ceph_cap_cachep, cap); } else { @@ -289,7 +297,8 @@ static void put_cap(struct ceph_cap *cap, } void ceph_reservation_status(struct ceph_client *client, - int *total, int *avail, int *used, int *reserved) + int *total, int *avail, int *used, int *reserved, + int *min) { if (total) *total = caps_total_count; @@ -299,6 +308,8 @@ void ceph_reservation_status(struct ceph_client *client, *used = caps_use_count; if (reserved) *reserved = caps_reserve_count; + if (min) + *min = caps_min_count; } /* |