Skip to content

Commit 6680288

Browse files
xxhdx1985126idryomov
authored andcommitted
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/36369 Signed-off-by: Xuehan Xu <xuxuehan@360.cn> Reviewed-by: "Yan, Zheng" <zyan@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
1 parent 8948683 commit 6680288

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

fs/ceph/caps.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,8 @@ static void __cap_set_timeouts(struct ceph_mds_client *mdsc,
519519
* -> we take mdsc->cap_delay_lock
520520
*/
521521
static void __cap_delay_requeue(struct ceph_mds_client *mdsc,
522-
struct ceph_inode_info *ci)
522+
struct ceph_inode_info *ci,
523+
bool set_timeout)
523524
{
524525
dout("__cap_delay_requeue %p flags %d at %lu\n", &ci->vfs_inode,
525526
ci->i_ceph_flags, ci->i_hold_caps_max);
@@ -530,7 +531,8 @@ static void __cap_delay_requeue(struct ceph_mds_client *mdsc,
530531
goto no_change;
531532
list_del_init(&ci->i_cap_delay_list);
532533
}
533-
__cap_set_timeouts(mdsc, ci);
534+
if (set_timeout)
535+
__cap_set_timeouts(mdsc, ci);
534536
list_add_tail(&ci->i_cap_delay_list, &mdsc->cap_delay_list);
535537
no_change:
536538
spin_unlock(&mdsc->cap_delay_lock);
@@ -720,7 +722,7 @@ void ceph_add_cap(struct inode *inode,
720722
dout(" issued %s, mds wanted %s, actual %s, queueing\n",
721723
ceph_cap_string(issued), ceph_cap_string(wanted),
722724
ceph_cap_string(actual_wanted));
723-
__cap_delay_requeue(mdsc, ci);
725+
__cap_delay_requeue(mdsc, ci, true);
724726
}
725727

726728
if (flags & CEPH_CAP_FLAG_AUTH) {
@@ -1647,7 +1649,7 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask,
16471649
if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) &&
16481650
(mask & CEPH_CAP_FILE_BUFFER))
16491651
dirty |= I_DIRTY_DATASYNC;
1650-
__cap_delay_requeue(mdsc, ci);
1652+
__cap_delay_requeue(mdsc, ci, true);
16511653
return dirty;
16521654
}
16531655

@@ -2065,7 +2067,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
20652067

20662068
/* Reschedule delayed caps release if we delayed anything */
20672069
if (delayed)
2068-
__cap_delay_requeue(mdsc, ci);
2070+
__cap_delay_requeue(mdsc, ci, false);
20692071

20702072
spin_unlock(&ci->i_ceph_lock);
20712073

@@ -2125,7 +2127,7 @@ static int try_flush_caps(struct inode *inode, u64 *ptid)
21252127

21262128
if (delayed) {
21272129
spin_lock(&ci->i_ceph_lock);
2128-
__cap_delay_requeue(mdsc, ci);
2130+
__cap_delay_requeue(mdsc, ci, true);
21292131
spin_unlock(&ci->i_ceph_lock);
21302132
}
21312133
} else {

0 commit comments

Comments
 (0)