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:
@@ -1965,6 +1965,18 @@ void ceph_queue_cap_reclaim_work(struct ceph_mds_client *mdsc)
|
||||
}
|
||||
}
|
||||
|
||||
void ceph_reclaim_caps_nr(struct ceph_mds_client *mdsc, int nr)
|
||||
{
|
||||
int val;
|
||||
if (!nr)
|
||||
return;
|
||||
val = atomic_add_return(nr, &mdsc->cap_reclaim_pending);
|
||||
if (!(val % CEPH_CAPS_PER_RELEASE)) {
|
||||
atomic_set(&mdsc->cap_reclaim_pending, 0);
|
||||
ceph_queue_cap_reclaim_work(mdsc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* requests
|
||||
*/
|
||||
@@ -2878,7 +2890,6 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
|
||||
if (result == 0 && (req->r_op == CEPH_MDS_OP_READDIR ||
|
||||
req->r_op == CEPH_MDS_OP_LSSNAP))
|
||||
ceph_readdir_prepopulate(req, req->r_session);
|
||||
ceph_unreserve_caps(mdsc, &req->r_caps_reservation);
|
||||
}
|
||||
current->journal_info = NULL;
|
||||
mutex_unlock(&req->r_fill_mutex);
|
||||
@@ -2887,12 +2898,18 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
|
||||
if (realm)
|
||||
ceph_put_snap_realm(mdsc, realm);
|
||||
|
||||
if (err == 0 && req->r_target_inode &&
|
||||
test_bit(CEPH_MDS_R_GOT_UNSAFE, &req->r_req_flags)) {
|
||||
struct ceph_inode_info *ci = ceph_inode(req->r_target_inode);
|
||||
spin_lock(&ci->i_unsafe_lock);
|
||||
list_add_tail(&req->r_unsafe_target_item, &ci->i_unsafe_iops);
|
||||
spin_unlock(&ci->i_unsafe_lock);
|
||||
if (err == 0) {
|
||||
if (req->r_target_inode &&
|
||||
test_bit(CEPH_MDS_R_GOT_UNSAFE, &req->r_req_flags)) {
|
||||
struct ceph_inode_info *ci =
|
||||
ceph_inode(req->r_target_inode);
|
||||
spin_lock(&ci->i_unsafe_lock);
|
||||
list_add_tail(&req->r_unsafe_target_item,
|
||||
&ci->i_unsafe_iops);
|
||||
spin_unlock(&ci->i_unsafe_lock);
|
||||
}
|
||||
|
||||
ceph_unreserve_caps(mdsc, &req->r_caps_reservation);
|
||||
}
|
||||
out_err:
|
||||
mutex_lock(&mdsc->mutex);
|
||||
@@ -4083,13 +4100,14 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
|
||||
spin_lock_init(&mdsc->cap_dirty_lock);
|
||||
init_waitqueue_head(&mdsc->cap_flushing_wq);
|
||||
INIT_WORK(&mdsc->cap_reclaim_work, ceph_cap_reclaim_work);
|
||||
atomic_set(&mdsc->cap_reclaim_pending, 0);
|
||||
|
||||
spin_lock_init(&mdsc->dentry_list_lock);
|
||||
INIT_LIST_HEAD(&mdsc->dentry_leases);
|
||||
INIT_LIST_HEAD(&mdsc->dentry_dir_leases);
|
||||
|
||||
ceph_caps_init(mdsc);
|
||||
ceph_adjust_min_caps(mdsc, fsc->min_caps);
|
||||
ceph_adjust_caps_max_min(mdsc, fsc->mount_options);
|
||||
|
||||
spin_lock_init(&mdsc->snapid_map_lock);
|
||||
mdsc->snapid_map_tree = RB_ROOT;
|
||||
|
Reference in New Issue
Block a user