From: Xiubo Li Date: Mon, 8 May 2023 05:48:43 +0000 (+0800) Subject: client: always add one new capsnap if Fb is used and Fw is not used X-Git-Tag: v16.2.14~34^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0e9f14526e56d71e0b633250066866d3419bf087;p=ceph.git client: always add one new capsnap if Fb is used and Fw is not used 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 (cherry picked from commit 6262351f7da9413d8306a6f1765ecab1f0ab912e) --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 52980d5ecb0..8c12b6505e4 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -3514,7 +3514,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; @@ -3528,6 +3528,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) { @@ -4042,9 +4046,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);