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>
This commit is contained in:
@@ -148,11 +148,17 @@ void ceph_caps_finalize(struct ceph_mds_client *mdsc)
|
||||
spin_unlock(&mdsc->caps_list_lock);
|
||||
}
|
||||
|
||||
void ceph_adjust_min_caps(struct ceph_mds_client *mdsc, int delta)
|
||||
void ceph_adjust_caps_max_min(struct ceph_mds_client *mdsc,
|
||||
struct ceph_mount_options *fsopt)
|
||||
{
|
||||
spin_lock(&mdsc->caps_list_lock);
|
||||
mdsc->caps_min_count += delta;
|
||||
BUG_ON(mdsc->caps_min_count < 0);
|
||||
mdsc->caps_min_count = fsopt->max_readdir;
|
||||
if (mdsc->caps_min_count < 1024)
|
||||
mdsc->caps_min_count = 1024;
|
||||
mdsc->caps_use_max = fsopt->caps_max;
|
||||
if (mdsc->caps_use_max > 0 &&
|
||||
mdsc->caps_use_max < mdsc->caps_min_count)
|
||||
mdsc->caps_use_max = mdsc->caps_min_count;
|
||||
spin_unlock(&mdsc->caps_list_lock);
|
||||
}
|
||||
|
||||
@@ -272,6 +278,7 @@ int ceph_reserve_caps(struct ceph_mds_client *mdsc,
|
||||
if (!err) {
|
||||
BUG_ON(have + alloc != need);
|
||||
ctx->count = need;
|
||||
ctx->used = 0;
|
||||
}
|
||||
|
||||
spin_lock(&mdsc->caps_list_lock);
|
||||
@@ -295,13 +302,24 @@ int ceph_reserve_caps(struct ceph_mds_client *mdsc,
|
||||
}
|
||||
|
||||
void ceph_unreserve_caps(struct ceph_mds_client *mdsc,
|
||||
struct ceph_cap_reservation *ctx)
|
||||
struct ceph_cap_reservation *ctx)
|
||||
{
|
||||
bool reclaim = false;
|
||||
if (!ctx->count)
|
||||
return;
|
||||
|
||||
dout("unreserve caps ctx=%p count=%d\n", ctx, ctx->count);
|
||||
spin_lock(&mdsc->caps_list_lock);
|
||||
__ceph_unreserve_caps(mdsc, ctx->count);
|
||||
ctx->count = 0;
|
||||
|
||||
if (mdsc->caps_use_max > 0 &&
|
||||
mdsc->caps_use_count > mdsc->caps_use_max)
|
||||
reclaim = true;
|
||||
spin_unlock(&mdsc->caps_list_lock);
|
||||
|
||||
if (reclaim)
|
||||
ceph_reclaim_caps_nr(mdsc, ctx->used);
|
||||
}
|
||||
|
||||
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,
|
||||
BUG_ON(list_empty(&mdsc->caps_list));
|
||||
|
||||
ctx->count--;
|
||||
ctx->used++;
|
||||
mdsc->caps_reserve_count--;
|
||||
mdsc->caps_use_count++;
|
||||
|
||||
@@ -500,12 +519,12 @@ static void __insert_cap_node(struct ceph_inode_info *ci,
|
||||
static void __cap_set_timeouts(struct ceph_mds_client *mdsc,
|
||||
struct ceph_inode_info *ci)
|
||||
{
|
||||
struct ceph_mount_options *ma = mdsc->fsc->mount_options;
|
||||
struct ceph_mount_options *opt = mdsc->fsc->mount_options;
|
||||
|
||||
ci->i_hold_caps_min = round_jiffies(jiffies +
|
||||
ma->caps_wanted_delay_min * HZ);
|
||||
opt->caps_wanted_delay_min * HZ);
|
||||
ci->i_hold_caps_max = round_jiffies(jiffies +
|
||||
ma->caps_wanted_delay_max * HZ);
|
||||
opt->caps_wanted_delay_max * HZ);
|
||||
dout("__cap_set_timeouts %p min %lu max %lu\n", &ci->vfs_inode,
|
||||
ci->i_hold_caps_min - jiffies, ci->i_hold_caps_max - jiffies);
|
||||
}
|
||||
|
Reference in New Issue
Block a user