ceph: set timeout conditionally in __cap_delay_requeue
diff mbox series

Message ID 20181011095539.15113-1-xxhdx1985126@gmail.com
State New
Headers show
Series
  • ceph: set timeout conditionally in __cap_delay_requeue
Related show

Commit Message

Xuehan Xu Oct. 11, 2018, 9:55 a.m. UTC
From: Xuehan Xu <xxhdx1985126@gmail.com>

__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(-)

Comments

Yan, Zheng Oct. 12, 2018, 2:52 a.m. UTC | #1
On Thu, Oct 11, 2018 at 5:58 PM <xxhdx1985126@gmail.com> wrote:
>
> From: Xuehan Xu <xxhdx1985126@gmail.com>
>
> __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(-)
>
> 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

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