On Thu, Oct 11, 2018 at 5:58 PM <xxhdx1985126@xxxxxxxxx> wrote: > > From: Xuehan Xu <xxhdx1985126@xxxxxxxxx> > > __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@xxxxxx> > --- > fs/ceph/caps.c | 14 ++++++++------ > 1 file changed, 8 insertions(+), 6 deletions(-) > > diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c > index 990258c..486cc77 100644 > --- a/fs/ceph/caps.c > +++ b/fs/ceph/caps.c > @@ -533,9 +533,11 @@ static void __cap_set_timeouts(struct ceph_mds_client *mdsc, > * -> we take mdsc->cap_delay_lock > */ > static void __cap_delay_requeue(struct ceph_mds_client *mdsc, > - struct ceph_inode_info *ci) > + struct ceph_inode_info *ci, > + bool set_timeout) > { > - __cap_set_timeouts(mdsc, ci); > + if (set_timeout) > + __cap_set_timeouts(mdsc, ci); > dout("__cap_delay_requeue %p flags %d at %lu\n", &ci->vfs_inode, > ci->i_ceph_flags, ci->i_hold_caps_max); > if (!mdsc->stopping) { > @@ -734,7 +736,7 @@ void ceph_add_cap(struct inode *inode, > dout(" issued %s, mds wanted %s, actual %s, queueing\n", > ceph_cap_string(issued), ceph_cap_string(wanted), > ceph_cap_string(actual_wanted)); > - __cap_delay_requeue(mdsc, ci); > + __cap_delay_requeue(mdsc, ci, true); > } > > if (flags & CEPH_CAP_FLAG_AUTH) { > @@ -1661,7 +1663,7 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask, > if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) && > (mask & CEPH_CAP_FILE_BUFFER)) > dirty |= I_DIRTY_DATASYNC; > - __cap_delay_requeue(mdsc, ci); > + __cap_delay_requeue(mdsc, ci, true); > return dirty; > } > > @@ -2079,7 +2081,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, > > /* Reschedule delayed caps release if we delayed anything */ > if (delayed) > - __cap_delay_requeue(mdsc, ci); > + __cap_delay_requeue(mdsc, ci, false); > > spin_unlock(&ci->i_ceph_lock); > > @@ -2139,7 +2141,7 @@ static int try_flush_caps(struct inode *inode, u64 *ptid) > > if (delayed) { > spin_lock(&ci->i_ceph_lock); > - __cap_delay_requeue(mdsc, ci); > + __cap_delay_requeue(mdsc, ci, true); > spin_unlock(&ci->i_ceph_lock); > } > } else { > -- > 1.8.3.1 > Applied, thanks Yan, Zheng