diff options
author | Xuehan Xu <xxhdx1985126@gmail.com> | 2018-10-11 05:55:39 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2018-10-22 04:28:21 -0400 |
commit | 668028844174aa7069da1f8ea89a5dbc93e86216 (patch) | |
tree | bcae7d1adac13c98ae2aacf495d46f37d699c30b /fs/ceph/caps.c | |
parent | 894868330a1e038ea4a65dbb81741eef70ad71b1 (diff) |
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>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r-- | fs/ceph/caps.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index b26ae1673992..f36946fdfb00 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -519,7 +519,8 @@ static void __cap_set_timeouts(struct ceph_mds_client *mdsc, | |||
519 | * -> we take mdsc->cap_delay_lock | 519 | * -> we take mdsc->cap_delay_lock |
520 | */ | 520 | */ |
521 | static void __cap_delay_requeue(struct ceph_mds_client *mdsc, | 521 | 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) | ||
523 | { | 524 | { |
524 | dout("__cap_delay_requeue %p flags %d at %lu\n", &ci->vfs_inode, | 525 | dout("__cap_delay_requeue %p flags %d at %lu\n", &ci->vfs_inode, |
525 | ci->i_ceph_flags, ci->i_hold_caps_max); | 526 | ci->i_ceph_flags, ci->i_hold_caps_max); |
@@ -530,7 +531,8 @@ static void __cap_delay_requeue(struct ceph_mds_client *mdsc, | |||
530 | goto no_change; | 531 | goto no_change; |
531 | list_del_init(&ci->i_cap_delay_list); | 532 | list_del_init(&ci->i_cap_delay_list); |
532 | } | 533 | } |
533 | __cap_set_timeouts(mdsc, ci); | 534 | if (set_timeout) |
535 | __cap_set_timeouts(mdsc, ci); | ||
534 | list_add_tail(&ci->i_cap_delay_list, &mdsc->cap_delay_list); | 536 | list_add_tail(&ci->i_cap_delay_list, &mdsc->cap_delay_list); |
535 | no_change: | 537 | no_change: |
536 | spin_unlock(&mdsc->cap_delay_lock); | 538 | spin_unlock(&mdsc->cap_delay_lock); |
@@ -720,7 +722,7 @@ void ceph_add_cap(struct inode *inode, | |||
720 | dout(" issued %s, mds wanted %s, actual %s, queueing\n", | 722 | dout(" issued %s, mds wanted %s, actual %s, queueing\n", |
721 | ceph_cap_string(issued), ceph_cap_string(wanted), | 723 | ceph_cap_string(issued), ceph_cap_string(wanted), |
722 | ceph_cap_string(actual_wanted)); | 724 | ceph_cap_string(actual_wanted)); |
723 | __cap_delay_requeue(mdsc, ci); | 725 | __cap_delay_requeue(mdsc, ci, true); |
724 | } | 726 | } |
725 | 727 | ||
726 | if (flags & CEPH_CAP_FLAG_AUTH) { | 728 | if (flags & CEPH_CAP_FLAG_AUTH) { |
@@ -1647,7 +1649,7 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask, | |||
1647 | if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) && | 1649 | if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) && |
1648 | (mask & CEPH_CAP_FILE_BUFFER)) | 1650 | (mask & CEPH_CAP_FILE_BUFFER)) |
1649 | dirty |= I_DIRTY_DATASYNC; | 1651 | dirty |= I_DIRTY_DATASYNC; |
1650 | __cap_delay_requeue(mdsc, ci); | 1652 | __cap_delay_requeue(mdsc, ci, true); |
1651 | return dirty; | 1653 | return dirty; |
1652 | } | 1654 | } |
1653 | 1655 | ||
@@ -2065,7 +2067,7 @@ ack: | |||
2065 | 2067 | ||
2066 | /* Reschedule delayed caps release if we delayed anything */ | 2068 | /* Reschedule delayed caps release if we delayed anything */ |
2067 | if (delayed) | 2069 | if (delayed) |
2068 | __cap_delay_requeue(mdsc, ci); | 2070 | __cap_delay_requeue(mdsc, ci, false); |
2069 | 2071 | ||
2070 | spin_unlock(&ci->i_ceph_lock); | 2072 | spin_unlock(&ci->i_ceph_lock); |
2071 | 2073 | ||
@@ -2125,7 +2127,7 @@ retry: | |||
2125 | 2127 | ||
2126 | if (delayed) { | 2128 | if (delayed) { |
2127 | spin_lock(&ci->i_ceph_lock); | 2129 | spin_lock(&ci->i_ceph_lock); |
2128 | __cap_delay_requeue(mdsc, ci); | 2130 | __cap_delay_requeue(mdsc, ci, true); |
2129 | spin_unlock(&ci->i_ceph_lock); | 2131 | spin_unlock(&ci->i_ceph_lock); |
2130 | } | 2132 | } |
2131 | } else { | 2133 | } else { |