ceph: kick flushing and flush snaps before sending normal cap message
authorYan, Zheng <zyan@redhat.com>
Thu, 20 Jun 2019 08:09:37 +0000 (16:09 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Mon, 8 Jul 2019 12:01:44 +0000 (14:01 +0200)
Otherwise client may send cap flush messages in wrong order.

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
fs/ceph/caps.c

index 82a3583..f9055cd 100644 (file)
@@ -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 @@ retry:
        }
        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 @@ retry:
                        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);