diff options
author | Yan, Zheng <zyan@redhat.com> | 2019-02-01 01:57:15 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2019-03-05 12:55:17 -0500 |
commit | fe33032daae2e584d9e7e33bab44c9eafced1f8f (patch) | |
tree | a03be95fd94ffcd66c69e2146a1930837f769eb4 /fs/ceph/caps.c | |
parent | 37c4efc1ddf98ba8b234d116d863a9464445901e (diff) |
ceph: add mount option to limit caps count
If number of caps exceed the limit, ceph_trim_dentires() also trim
dentries with valid leases. Trimming dentry releases references to
associated inode, which may evict inode and release caps.
By default, there is no limit for caps count.
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r-- | fs/ceph/caps.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 6fbdc1a0afbe..36a8dc699448 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -148,11 +148,17 @@ void ceph_caps_finalize(struct ceph_mds_client *mdsc) | |||
148 | spin_unlock(&mdsc->caps_list_lock); | 148 | spin_unlock(&mdsc->caps_list_lock); |
149 | } | 149 | } |
150 | 150 | ||
151 | void ceph_adjust_min_caps(struct ceph_mds_client *mdsc, int delta) | 151 | void ceph_adjust_caps_max_min(struct ceph_mds_client *mdsc, |
152 | struct ceph_mount_options *fsopt) | ||
152 | { | 153 | { |
153 | spin_lock(&mdsc->caps_list_lock); | 154 | spin_lock(&mdsc->caps_list_lock); |
154 | mdsc->caps_min_count += delta; | 155 | mdsc->caps_min_count = fsopt->max_readdir; |
155 | BUG_ON(mdsc->caps_min_count < 0); | 156 | if (mdsc->caps_min_count < 1024) |
157 | mdsc->caps_min_count = 1024; | ||
158 | mdsc->caps_use_max = fsopt->caps_max; | ||
159 | if (mdsc->caps_use_max > 0 && | ||
160 | mdsc->caps_use_max < mdsc->caps_min_count) | ||
161 | mdsc->caps_use_max = mdsc->caps_min_count; | ||
156 | spin_unlock(&mdsc->caps_list_lock); | 162 | spin_unlock(&mdsc->caps_list_lock); |
157 | } | 163 | } |
158 | 164 | ||
@@ -272,6 +278,7 @@ int ceph_reserve_caps(struct ceph_mds_client *mdsc, | |||
272 | if (!err) { | 278 | if (!err) { |
273 | BUG_ON(have + alloc != need); | 279 | BUG_ON(have + alloc != need); |
274 | ctx->count = need; | 280 | ctx->count = need; |
281 | ctx->used = 0; | ||
275 | } | 282 | } |
276 | 283 | ||
277 | spin_lock(&mdsc->caps_list_lock); | 284 | spin_lock(&mdsc->caps_list_lock); |
@@ -295,13 +302,24 @@ int ceph_reserve_caps(struct ceph_mds_client *mdsc, | |||
295 | } | 302 | } |
296 | 303 | ||
297 | void ceph_unreserve_caps(struct ceph_mds_client *mdsc, | 304 | void ceph_unreserve_caps(struct ceph_mds_client *mdsc, |
298 | struct ceph_cap_reservation *ctx) | 305 | struct ceph_cap_reservation *ctx) |
299 | { | 306 | { |
307 | bool reclaim = false; | ||
308 | if (!ctx->count) | ||
309 | return; | ||
310 | |||
300 | dout("unreserve caps ctx=%p count=%d\n", ctx, ctx->count); | 311 | dout("unreserve caps ctx=%p count=%d\n", ctx, ctx->count); |
301 | spin_lock(&mdsc->caps_list_lock); | 312 | spin_lock(&mdsc->caps_list_lock); |
302 | __ceph_unreserve_caps(mdsc, ctx->count); | 313 | __ceph_unreserve_caps(mdsc, ctx->count); |
303 | ctx->count = 0; | 314 | ctx->count = 0; |
315 | |||
316 | if (mdsc->caps_use_max > 0 && | ||
317 | mdsc->caps_use_count > mdsc->caps_use_max) | ||
318 | reclaim = true; | ||
304 | spin_unlock(&mdsc->caps_list_lock); | 319 | spin_unlock(&mdsc->caps_list_lock); |
320 | |||
321 | if (reclaim) | ||
322 | ceph_reclaim_caps_nr(mdsc, ctx->used); | ||
305 | } | 323 | } |
306 | 324 | ||
307 | struct ceph_cap *ceph_get_cap(struct ceph_mds_client *mdsc, | 325 | struct ceph_cap *ceph_get_cap(struct ceph_mds_client *mdsc, |
@@ -346,6 +364,7 @@ struct ceph_cap *ceph_get_cap(struct ceph_mds_client *mdsc, | |||
346 | BUG_ON(list_empty(&mdsc->caps_list)); | 364 | BUG_ON(list_empty(&mdsc->caps_list)); |
347 | 365 | ||
348 | ctx->count--; | 366 | ctx->count--; |
367 | ctx->used++; | ||
349 | mdsc->caps_reserve_count--; | 368 | mdsc->caps_reserve_count--; |
350 | mdsc->caps_use_count++; | 369 | mdsc->caps_use_count++; |
351 | 370 | ||
@@ -500,12 +519,12 @@ static void __insert_cap_node(struct ceph_inode_info *ci, | |||
500 | static void __cap_set_timeouts(struct ceph_mds_client *mdsc, | 519 | static void __cap_set_timeouts(struct ceph_mds_client *mdsc, |
501 | struct ceph_inode_info *ci) | 520 | struct ceph_inode_info *ci) |
502 | { | 521 | { |
503 | struct ceph_mount_options *ma = mdsc->fsc->mount_options; | 522 | struct ceph_mount_options *opt = mdsc->fsc->mount_options; |
504 | 523 | ||
505 | ci->i_hold_caps_min = round_jiffies(jiffies + | 524 | ci->i_hold_caps_min = round_jiffies(jiffies + |
506 | ma->caps_wanted_delay_min * HZ); | 525 | opt->caps_wanted_delay_min * HZ); |
507 | ci->i_hold_caps_max = round_jiffies(jiffies + | 526 | ci->i_hold_caps_max = round_jiffies(jiffies + |
508 | ma->caps_wanted_delay_max * HZ); | 527 | opt->caps_wanted_delay_max * HZ); |
509 | dout("__cap_set_timeouts %p min %lu max %lu\n", &ci->vfs_inode, | 528 | dout("__cap_set_timeouts %p min %lu max %lu\n", &ci->vfs_inode, |
510 | ci->i_hold_caps_min - jiffies, ci->i_hold_caps_max - jiffies); | 529 | ci->i_hold_caps_min - jiffies, ci->i_hold_caps_max - jiffies); |
511 | } | 530 | } |