[2/3] ceph: kick flushing and flush snaps before sending normal cap message
diff mbox series

Message ID 20190620132821.7814-2-zyan@redhat.com
State New
Headers show
Series
  • [1/3] ceph: clear CEPH_I_KICK_FLUSH flag inside __kick_flushing_caps()
Related show

Commit Message

Yan, Zheng June 20, 2019, 1:28 p.m. UTC
Othweise client may send cap flush messages in wrong order.

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
---
 fs/ceph/caps.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

Comments

Jeff Layton June 20, 2019, 3:11 p.m. UTC | #1
On Thu, 2019-06-20 at 21:28 +0800, Yan, Zheng wrote:
> Othweise client may send cap flush messages in wrong order.
> 

"Otherwise"

> Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
> ---
>  fs/ceph/caps.c | 18 ++++++++++++++----
>  1 file changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
> index cd946bca4792..82cfb153d0f3 100644
> --- a/fs/ceph/caps.c
> +++ b/fs/ceph/caps.c
> @@ -2119,6 +2119,7 @@ static int try_flush_caps(struct inode *inode, u64 *ptid)
>  
>  retry:
>  	spin_lock(&ci->i_ceph_lock);
> +retry_locked:
>  	if (ci->i_ceph_flags & CEPH_I_NOFLUSH) {
>  		spin_unlock(&ci->i_ceph_lock);
>  		dout("try_flush_caps skipping %p I_NOFLUSH set\n", inode);
> @@ -2126,8 +2127,6 @@ static int try_flush_caps(struct inode *inode, u64 *ptid)
>  	}
>  	if (ci->i_dirty_caps && ci->i_auth_cap) {
>  		struct ceph_cap *cap = ci->i_auth_cap;
> -		int used = __ceph_caps_used(ci);
> -		int want = __ceph_caps_wanted(ci);
>  		int delayed;
>  
>  		if (!session || session != cap->session) {
> @@ -2143,13 +2142,24 @@ static int try_flush_caps(struct inode *inode, u64 *ptid)
>  			goto out;
>  		}
>  
> +		if (ci->i_ceph_flags &
> +		    (CEPH_I_KICK_FLUSH | CEPH_I_FLUSH_SNAPS)) {
> +			if (ci->i_ceph_flags & CEPH_I_KICK_FLUSH)
> +				__kick_flushing_caps(mdsc, session, ci, 0);
> +			if (ci->i_ceph_flags & CEPH_I_FLUSH_SNAPS)
> +				__ceph_flush_snaps(ci, session);
> +			goto retry_locked;
> +		}
> +
>  		flushing = __mark_caps_flushing(inode, session, true,
>  						&flush_tid, &oldest_flush_tid);
>  
>  		/* __send_cap drops i_ceph_lock */
>  		delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, true,
> -				used, want, (cap->issued | cap->implemented),
> -				flushing, flush_tid, oldest_flush_tid);
> +				     __ceph_caps_used(ci),
> +				     __ceph_caps_wanted(ci),
> +				     (cap->issued | cap->implemented),
> +				     flushing, flush_tid, oldest_flush_tid);
>  
>  		if (delayed) {
>  			spin_lock(&ci->i_ceph_lock);

This set looks good to me (aside from typo in the commit message in this
patch). You can add this to all 3:

Reviewed-by: Jeff Layton <jlayton@redhat.com>

Patch
diff mbox series

diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index cd946bca4792..82cfb153d0f3 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -2119,6 +2119,7 @@  static int try_flush_caps(struct inode *inode, u64 *ptid)
 
 retry:
 	spin_lock(&ci->i_ceph_lock);
+retry_locked:
 	if (ci->i_ceph_flags & CEPH_I_NOFLUSH) {
 		spin_unlock(&ci->i_ceph_lock);
 		dout("try_flush_caps skipping %p I_NOFLUSH set\n", inode);
@@ -2126,8 +2127,6 @@  static int try_flush_caps(struct inode *inode, u64 *ptid)
 	}
 	if (ci->i_dirty_caps && ci->i_auth_cap) {
 		struct ceph_cap *cap = ci->i_auth_cap;
-		int used = __ceph_caps_used(ci);
-		int want = __ceph_caps_wanted(ci);
 		int delayed;
 
 		if (!session || session != cap->session) {
@@ -2143,13 +2142,24 @@  static int try_flush_caps(struct inode *inode, u64 *ptid)
 			goto out;
 		}
 
+		if (ci->i_ceph_flags &
+		    (CEPH_I_KICK_FLUSH | CEPH_I_FLUSH_SNAPS)) {
+			if (ci->i_ceph_flags & CEPH_I_KICK_FLUSH)
+				__kick_flushing_caps(mdsc, session, ci, 0);
+			if (ci->i_ceph_flags & CEPH_I_FLUSH_SNAPS)
+				__ceph_flush_snaps(ci, session);
+			goto retry_locked;
+		}
+
 		flushing = __mark_caps_flushing(inode, session, true,
 						&flush_tid, &oldest_flush_tid);
 
 		/* __send_cap drops i_ceph_lock */
 		delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, true,
-				used, want, (cap->issued | cap->implemented),
-				flushing, flush_tid, oldest_flush_tid);
+				     __ceph_caps_used(ci),
+				     __ceph_caps_wanted(ci),
+				     (cap->issued | cap->implemented),
+				     flushing, flush_tid, oldest_flush_tid);
 
 		if (delayed) {
 			spin_lock(&ci->i_ceph_lock);