summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiubo Li <xiubli@redhat.com>2022-08-11 13:00:53 +0800
committerIlya Dryomov <idryomov@gmail.com>2022-10-04 19:18:08 +0200
commit7c3ea9870e09e193981695dd67c37a1a2b6d600b (patch)
tree4ed44318d73c8bda5644e5262712afc0daaf6e9e
parent6eb06c46214d33c71ae86d60b3fc9cb17c20beca (diff)
ceph: no need to wait for transition RDCACHE|RD -> RD
For write when trying to get the Fwb caps we need to keep waiting on transition from WRBUFFER|WR -> WR to avoid a new WR sync write from going before a prior buffered writeback happens. While for read there is no need to wait on transition from RDCACHE|RD -> RD, and we can just exclude the revoking caps and force to sync read. Signed-off-by: Xiubo Li <xiubli@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
-rw-r--r--fs/ceph/caps.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 0ddd91eadbce..0dc1251c3c6d 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -2760,13 +2760,17 @@ again:
* on transition from wanted -> needed caps. This is needed
* for WRBUFFER|WR -> WR to avoid a new WR sync write from
* going before a prior buffered writeback happens.
+ *
+ * For RDCACHE|RD -> RD, there is not need to wait and we can
+ * just exclude the revoking caps and force to sync read.
*/
int not = want & ~(have & need);
int revoking = implemented & ~have;
+ int exclude = revoking & not;
dout("get_cap_refs %p have %s but not %s (revoking %s)\n",
inode, ceph_cap_string(have), ceph_cap_string(not),
ceph_cap_string(revoking));
- if ((revoking & not) == 0) {
+ if (!exclude || !(exclude & CEPH_CAP_FILE_BUFFER)) {
if (!snap_rwsem_locked &&
!ci->i_head_snapc &&
(need & CEPH_CAP_FILE_WR)) {
@@ -2788,7 +2792,7 @@ again:
snap_rwsem_locked = true;
}
if ((have & want) == want)
- *got = need | want;
+ *got = need | (want & ~exclude);
else
*got = need;
ceph_take_cap_refs(ci, *got, true);