]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: always add one new capsnap if Fb is used and Fw is not used
authorXiubo Li <xiubli@redhat.com>
Mon, 8 May 2023 05:48:43 +0000 (13:48 +0800)
committerXiubo Li <xiubli@redhat.com>
Tue, 18 Jul 2023 02:21:22 +0000 (10:21 +0800)
If we set the 'writing' to 1 when the 'Fb' caps is used then later
if we have any dirty caps it will be skipped and will reuse the
existing capsnap, which is incorrect.

At the same time trigger to flush the buffer when making snapshot
and if the Fb is being used.

Fixes: https://tracker.ceph.com/issues/59343
Signed-off-by: Xiubo Li <xiubli@redhat.com>
(cherry picked from commit 6262351f7da9413d8306a6f1765ecab1f0ab912e)

src/client/Client.cc

index a51516aa13ef0f5fa0386129de0a79b517e75ec8..f508aeb81e7d8b441db1aa9be30ef28c64d014dc 100644 (file)
@@ -3522,7 +3522,7 @@ void Client::put_cap_ref(Inode *in, int cap)
     int put_nref = 0;
     int drop = last & ~in->caps_issued();
     if (in->snapid == CEPH_NOSNAP) {
-      if ((last & (CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER)) &&
+      if ((last & CEPH_CAP_FILE_WR) &&
          !in->cap_snaps.empty() &&
          in->cap_snaps.rbegin()->second.writing) {
        ldout(cct, 10) << __func__ << " finishing pending cap_snap on " << *in << dendl;
@@ -3536,6 +3536,10 @@ void Client::put_cap_ref(Inode *in, int cap)
        signal_cond_list(in->waitfor_commit);
        ldout(cct, 5) << __func__ << " dropped last FILE_BUFFER ref on " << *in << dendl;
        ++put_nref;
+
+       if (!in->cap_snaps.empty()) {
+         flush_snaps(in);
+       }
       }
     }
     if (last & CEPH_CAP_FILE_CACHE) {
@@ -4047,9 +4051,11 @@ void Client::finish_cap_snap(Inode *in, CapSnap &capsnap, int used)
   }
 
   if (used & CEPH_CAP_FILE_BUFFER) {
-    capsnap.writing = 1;
     ldout(cct, 10) << __func__ << " " << *in << " cap_snap " << &capsnap << " used " << used
-            << " WRBUFFER, delaying" << dendl;
+            << " WRBUFFER, trigger to flush dirty buffer" << dendl;
+
+    /* trigger to flush the buffer */
+    _flush(in, new C_Client_FlushComplete(this, in));
   } else {
     capsnap.dirty_data = 0;
     flush_snaps(in);