]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: signal waitfor_commit waiters for write delegation enabled inode 65913/head
authorVenky Shankar <vshankar@redhat.com>
Wed, 15 Oct 2025 13:40:35 +0000 (13:40 +0000)
committerJos Collin <jcollin@redhat.com>
Thu, 5 Mar 2026 10:15:39 +0000 (15:45 +0530)
Fixes: http://tracker.ceph.com/issues/73624
Signed-off-by: Venky Shankar <vshankar@redhat.com>
Tested-by: Suhas Athani <sathani@redhat.com>
(cherry picked from commit ee864798373248abda5237ceef2258ed7236f6ee)

src/client/Client.cc
src/client/Inode.cc
src/client/Inode.h

index d9e466919c37a3c7b11c3cfee769f031281f3bf4..ad698160f5b822e11a03f44416e5c6da5bec2583 100644 (file)
@@ -3773,7 +3773,9 @@ void Client::put_cap_ref(Inode *in, int cap)
          p.second.dirty_data = 0;
        signal_context_list(in->waitfor_commit);
        ldout(cct, 5) << __func__ << " dropped last FILE_BUFFER ref on " << *in << dendl;
-       ++put_nref;
+        if (!in->is_write_delegated()) {
+          ++put_nref;
+        }
 
        if (!in->cap_snaps.empty()) {
          flush_snaps(in);
@@ -12372,13 +12374,9 @@ int Client::_fsync(Inode *in, bool syncdataonly)
     ldout(cct, 15) << "got " << r << " from flush writeback" << dendl;
   } else {
     // FIXME: this can starve
-    int nr_refs = 0;
-    if (in->is_write_delegated()) {
-      ++nr_refs;
-    }
-    while (in->cap_refs[CEPH_CAP_FILE_BUFFER] > nr_refs) {
+    while (!in->is_last_cap_ref(CEPH_CAP_FILE_BUFFER)) {
       ldout(cct, 10) << "ino " << in->ino << " has " << in->cap_refs[CEPH_CAP_FILE_BUFFER]
-                    << " uncommitted (nrefs: " << nr_refs << "), waiting" << dendl;
+                    << " uncommitted, waiting" << dendl;
       wait_on_context_list(in->waitfor_commit);
     }
   }
index aabed0a3ad3dc2343766c1c4ae2b71dc423c5e0d..4a42f060a51be37bc23e940409ce70c8faa1b05b 100644 (file)
@@ -198,6 +198,20 @@ void Inode::get_cap_ref(int cap)
   }
 }
 
+bool Inode::is_last_cap_ref(int c)
+{
+  if (c != CEPH_CAP_FILE_BUFFER) {
+    return cap_refs[c] == 0;
+  }
+
+  int nref = 0;
+  if (is_write_delegated()) {
+    ++nref;
+  }
+
+  return cap_refs[c] == nref;
+}
+
 int Inode::put_cap_ref(int cap)
 {
   int last = 0;
@@ -209,7 +223,8 @@ int Inode::put_cap_ref(int cap)
        lderr(client->cct) << "put_cap_ref " << ccap_string(c) << " went negative on " << *this << dendl;
        ceph_assert(cap_refs[c] > 0);
       }
-      if (--cap_refs[c] == 0)
+      --cap_refs[c];
+      if (is_last_cap_ref(c))
         last |= c;
       //cout << "inode " << *this << " put " << cap_string(c) << " " << (cap_refs[c]+1) << " -> " << cap_refs[c] << std::endl;
     }
index 1e2e22a2828c74968a4594b7ffbd23cd0b8b012c..eca3381249946da174c7c17e962f2cc88bb37544 100644 (file)
@@ -316,6 +316,7 @@ struct Inode : RefCountedObject {
 
   void get_cap_ref(int cap);
   int put_cap_ref(int cap);
+  bool is_last_cap_ref(int c);
   bool is_any_caps();
   bool cap_is_valid(const Cap &cap) const;
   int caps_issued(int *implemented = 0) const;