ceph: set timeout conditionally in __cap_delay_requeue
diff mbox series

Message ID CAJACTuf+kkzS9BrZJCL_MqCWK6x_4LDmdLC7S3Y4BdqXkFtx=w@mail.gmail.com
State New
Headers show
Series
  • ceph: set timeout conditionally in __cap_delay_requeue
Related show

Commit Message

Xuehan Xu Oct. 10, 2018, 8:54 a.m. UTC
__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>
---
 fs/ceph/caps.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

        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 {

Patch
diff mbox series

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);