Skip to content

Commit 2d12ad9

Browse files
lxbszidryomov
authored andcommitted
ceph: trigger to flush the buffer when making snapshot
The 'i_wr_ref' is used to track the 'Fb' caps, while whenever the 'Fb' caps is took the kclient will always take the 'Fw' caps at the same time. That means it will always be a false check in __ceph_finish_cap_snap(). When writing to buffer the kclient will take both 'Fb|Fw' caps and then write the contents to the buffer pages by increasing the 'i_wrbuffer_ref' and then just release both 'Fb|Fw'. This is different with the user space libcephfs, which will keep the 'Fb' being took and use 'i_wr_ref' instead of 'i_wrbuffer_ref' to track this until the buffer is flushed to Rados. We need to defer flushing the capsnap until the corresponding buffer pages are all flushed to Rados, and at the same time just trigger to flush the buffer pages immediately. Link: https://tracker.ceph.com/issues/48640 Link: https://tracker.ceph.com/issues/59343 Signed-off-by: Xiubo Li <[email protected]> Reviewed-by: Milind Changire <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
1 parent dc94bb8 commit 2d12ad9

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

fs/ceph/caps.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3109,6 +3109,12 @@ static void __ceph_put_cap_refs(struct ceph_inode_info *ci, int had,
31093109
}
31103110
if (had & CEPH_CAP_FILE_WR) {
31113111
if (--ci->i_wr_ref == 0) {
3112+
/*
3113+
* The Fb caps will always be took and released
3114+
* together with the Fw caps.
3115+
*/
3116+
WARN_ON_ONCE(ci->i_wb_ref);
3117+
31123118
last++;
31133119
check_flushsnaps = true;
31143120
if (ci->i_wrbuffer_ref_head == 0 &&

fs/ceph/snap.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -675,14 +675,17 @@ int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
675675
return 0;
676676
}
677677

678-
/* Fb cap still in use, delay it */
679-
if (ci->i_wb_ref) {
678+
/*
679+
* Defer flushing the capsnap if the dirty buffer not flushed yet.
680+
* And trigger to flush the buffer immediately.
681+
*/
682+
if (ci->i_wrbuffer_ref) {
680683
dout("%s %p %llx.%llx cap_snap %p snapc %p %llu %s s=%llu "
681684
"used WRBUFFER, delaying\n", __func__, inode,
682685
ceph_vinop(inode), capsnap, capsnap->context,
683686
capsnap->context->seq, ceph_cap_string(capsnap->dirty),
684687
capsnap->size);
685-
capsnap->writing = 1;
688+
ceph_queue_writeback(inode);
686689
return 0;
687690
}
688691

0 commit comments

Comments
 (0)