Skip to content

Commit a743795

Browse files
lxbszidryomov
authored andcommitted
ceph: try to queue a writeback if revoking fails
If the pagecaches writeback just finished and the i_wrbuffer_ref reaches zero it will try to trigger ceph_check_caps(). But if just before ceph_check_caps() the i_wrbuffer_ref could be increased again by mmap/cache write, then the Fwb revoke will fail. We need to try to queue a writeback in this case instead of triggering the writeback by BDI's delayed work per 5 seconds. URL: https://tracker.ceph.com/issues/46904 URL: https://tracker.ceph.com/issues/55377 Signed-off-by: Xiubo Li <xiubli@redhat.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
1 parent 55ab552 commit a743795

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

fs/ceph/caps.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1911,6 +1911,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
19111911
struct rb_node *p;
19121912
bool queue_invalidate = false;
19131913
bool tried_invalidate = false;
1914+
bool queue_writeback = false;
19141915

19151916
if (session)
19161917
ceph_get_mds_session(session);
@@ -2063,10 +2064,27 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
20632064
}
20642065

20652066
/* completed revocation? going down and there are no caps? */
2066-
if (revoking && (revoking & cap_used) == 0) {
2067-
dout("completed revocation of %s\n",
2068-
ceph_cap_string(cap->implemented & ~cap->issued));
2069-
goto ack;
2067+
if (revoking) {
2068+
if ((revoking & cap_used) == 0) {
2069+
dout("completed revocation of %s\n",
2070+
ceph_cap_string(cap->implemented & ~cap->issued));
2071+
goto ack;
2072+
}
2073+
2074+
/*
2075+
* If the "i_wrbuffer_ref" was increased by mmap or generic
2076+
* cache write just before the ceph_check_caps() is called,
2077+
* the Fb capability revoking will fail this time. Then we
2078+
* must wait for the BDI's delayed work to flush the dirty
2079+
* pages and to release the "i_wrbuffer_ref", which will cost
2080+
* at most 5 seconds. That means the MDS needs to wait at
2081+
* most 5 seconds to finished the Fb capability's revocation.
2082+
*
2083+
* Let's queue a writeback for it.
2084+
*/
2085+
if (S_ISREG(inode->i_mode) && ci->i_wrbuffer_ref &&
2086+
(revoking & CEPH_CAP_FILE_BUFFER))
2087+
queue_writeback = true;
20702088
}
20712089

20722090
/* want more caps from mds? */
@@ -2136,6 +2154,8 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
21362154
spin_unlock(&ci->i_ceph_lock);
21372155

21382156
ceph_put_mds_session(session);
2157+
if (queue_writeback)
2158+
ceph_queue_writeback(inode);
21392159
if (queue_invalidate)
21402160
ceph_queue_invalidate(inode);
21412161
}

0 commit comments

Comments
 (0)