Commit 66802884 authored by Xuehan Xu's avatar Xuehan Xu Committed by Ilya Dryomov

ceph: set timeout conditionally in __cap_delay_requeue

__cap_delay_requeue could be invoked through ceph_check_caps when there
exists caps that needs to be sent and are delayed by "i_hold_caps_min"
or "i_hold_caps_max". If __cap_delay_requeue sets timeout unconditionally,
there could be a chance that some "wanted" caps can not be release for a
long since their timeouts are reset every time they get delayed.

Fixes: http://tracker.ceph.com/issues/36369Signed-off-by: default avatarXuehan Xu <xuxuehan@360.cn>
Reviewed-by: default avatar"Yan, Zheng" <zyan@redhat.com>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 89486833
...@@ -519,7 +519,8 @@ static void __cap_set_timeouts(struct ceph_mds_client *mdsc, ...@@ -519,7 +519,8 @@ static void __cap_set_timeouts(struct ceph_mds_client *mdsc,
* -> we take mdsc->cap_delay_lock * -> we take mdsc->cap_delay_lock
*/ */
static void __cap_delay_requeue(struct ceph_mds_client *mdsc, static void __cap_delay_requeue(struct ceph_mds_client *mdsc,
struct ceph_inode_info *ci) struct ceph_inode_info *ci,
bool set_timeout)
{ {
dout("__cap_delay_requeue %p flags %d at %lu\n", &ci->vfs_inode, dout("__cap_delay_requeue %p flags %d at %lu\n", &ci->vfs_inode,
ci->i_ceph_flags, ci->i_hold_caps_max); ci->i_ceph_flags, ci->i_hold_caps_max);
...@@ -530,6 +531,7 @@ static void __cap_delay_requeue(struct ceph_mds_client *mdsc, ...@@ -530,6 +531,7 @@ static void __cap_delay_requeue(struct ceph_mds_client *mdsc,
goto no_change; goto no_change;
list_del_init(&ci->i_cap_delay_list); list_del_init(&ci->i_cap_delay_list);
} }
if (set_timeout)
__cap_set_timeouts(mdsc, ci); __cap_set_timeouts(mdsc, ci);
list_add_tail(&ci->i_cap_delay_list, &mdsc->cap_delay_list); list_add_tail(&ci->i_cap_delay_list, &mdsc->cap_delay_list);
no_change: no_change:
...@@ -720,7 +722,7 @@ void ceph_add_cap(struct inode *inode, ...@@ -720,7 +722,7 @@ void ceph_add_cap(struct inode *inode,
dout(" issued %s, mds wanted %s, actual %s, queueing\n", dout(" issued %s, mds wanted %s, actual %s, queueing\n",
ceph_cap_string(issued), ceph_cap_string(wanted), ceph_cap_string(issued), ceph_cap_string(wanted),
ceph_cap_string(actual_wanted)); ceph_cap_string(actual_wanted));
__cap_delay_requeue(mdsc, ci); __cap_delay_requeue(mdsc, ci, true);
} }
if (flags & CEPH_CAP_FLAG_AUTH) { if (flags & CEPH_CAP_FLAG_AUTH) {
...@@ -1647,7 +1649,7 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask, ...@@ -1647,7 +1649,7 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask,
if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) && if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) &&
(mask & CEPH_CAP_FILE_BUFFER)) (mask & CEPH_CAP_FILE_BUFFER))
dirty |= I_DIRTY_DATASYNC; dirty |= I_DIRTY_DATASYNC;
__cap_delay_requeue(mdsc, ci); __cap_delay_requeue(mdsc, ci, true);
return dirty; return dirty;
} }
...@@ -2065,7 +2067,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, ...@@ -2065,7 +2067,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
/* Reschedule delayed caps release if we delayed anything */ /* Reschedule delayed caps release if we delayed anything */
if (delayed) if (delayed)
__cap_delay_requeue(mdsc, ci); __cap_delay_requeue(mdsc, ci, false);
spin_unlock(&ci->i_ceph_lock); spin_unlock(&ci->i_ceph_lock);
...@@ -2125,7 +2127,7 @@ static int try_flush_caps(struct inode *inode, u64 *ptid) ...@@ -2125,7 +2127,7 @@ static int try_flush_caps(struct inode *inode, u64 *ptid)
if (delayed) { if (delayed) {
spin_lock(&ci->i_ceph_lock); spin_lock(&ci->i_ceph_lock);
__cap_delay_requeue(mdsc, ci); __cap_delay_requeue(mdsc, ci, true);
spin_unlock(&ci->i_ceph_lock); spin_unlock(&ci->i_ceph_lock);
} }
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment