Skip to content

Commit 902d6d0

Browse files
lxbszidryomov
authored andcommitted
ceph: always queue a writeback when revoking the Fb caps
In case there is 'Fw' dirty caps and 'CHECK_CAPS_FLUSH' is set we will always ignore queue a writeback. Queue a writeback is very important because it will block kclient flushing the snapcaps to MDS and which will block MDS waiting for revoking the 'Fb' caps. Link: https://tracker.ceph.com/issues/50223 Signed-off-by: Xiubo Li <xiubli@redhat.com> Reviewed-by: Milind Changire <mchangir@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
1 parent 841c351 commit 902d6d0

File tree

1 file changed

+24
-24
lines changed

1 file changed

+24
-24
lines changed

fs/ceph/caps.c

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2156,6 +2156,30 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags)
21562156
ceph_cap_string(cap->implemented),
21572157
ceph_cap_string(revoking));
21582158

2159+
/* completed revocation? going down and there are no caps? */
2160+
if (revoking) {
2161+
if ((revoking & cap_used) == 0) {
2162+
doutc(cl, "completed revocation of %s\n",
2163+
ceph_cap_string(cap->implemented & ~cap->issued));
2164+
goto ack;
2165+
}
2166+
2167+
/*
2168+
* If the "i_wrbuffer_ref" was increased by mmap or generic
2169+
* cache write just before the ceph_check_caps() is called,
2170+
* the Fb capability revoking will fail this time. Then we
2171+
* must wait for the BDI's delayed work to flush the dirty
2172+
* pages and to release the "i_wrbuffer_ref", which will cost
2173+
* at most 5 seconds. That means the MDS needs to wait at
2174+
* most 5 seconds to finished the Fb capability's revocation.
2175+
*
2176+
* Let's queue a writeback for it.
2177+
*/
2178+
if (S_ISREG(inode->i_mode) && ci->i_wrbuffer_ref &&
2179+
(revoking & CEPH_CAP_FILE_BUFFER))
2180+
queue_writeback = true;
2181+
}
2182+
21592183
if (cap == ci->i_auth_cap &&
21602184
(cap->issued & CEPH_CAP_FILE_WR)) {
21612185
/* request larger max_size from MDS? */
@@ -2183,30 +2207,6 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags)
21832207
}
21842208
}
21852209

2186-
/* completed revocation? going down and there are no caps? */
2187-
if (revoking) {
2188-
if ((revoking & cap_used) == 0) {
2189-
doutc(cl, "completed revocation of %s\n",
2190-
ceph_cap_string(cap->implemented & ~cap->issued));
2191-
goto ack;
2192-
}
2193-
2194-
/*
2195-
* If the "i_wrbuffer_ref" was increased by mmap or generic
2196-
* cache write just before the ceph_check_caps() is called,
2197-
* the Fb capability revoking will fail this time. Then we
2198-
* must wait for the BDI's delayed work to flush the dirty
2199-
* pages and to release the "i_wrbuffer_ref", which will cost
2200-
* at most 5 seconds. That means the MDS needs to wait at
2201-
* most 5 seconds to finished the Fb capability's revocation.
2202-
*
2203-
* Let's queue a writeback for it.
2204-
*/
2205-
if (S_ISREG(inode->i_mode) && ci->i_wrbuffer_ref &&
2206-
(revoking & CEPH_CAP_FILE_BUFFER))
2207-
queue_writeback = true;
2208-
}
2209-
22102210
/* want more caps from mds? */
22112211
if (want & ~cap->mds_wanted) {
22122212
if (want & ~(cap->mds_wanted | cap->issued))

0 commit comments

Comments
 (0)