Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Xiubo Li and committed by
Ilya Dryomov
7c3ea987 6eb06c46

+6 -2
+6 -2
fs/ceph/caps.c
··· 2760 2760 * on transition from wanted -> needed caps. This is needed 2761 2761 * for WRBUFFER|WR -> WR to avoid a new WR sync write from 2762 2762 * going before a prior buffered writeback happens. 2763 + * 2764 + * For RDCACHE|RD -> RD, there is not need to wait and we can 2765 + * just exclude the revoking caps and force to sync read. 2763 2766 */ 2764 2767 int not = want & ~(have & need); 2765 2768 int revoking = implemented & ~have; 2769 + int exclude = revoking & not; 2766 2770 dout("get_cap_refs %p have %s but not %s (revoking %s)\n", 2767 2771 inode, ceph_cap_string(have), ceph_cap_string(not), 2768 2772 ceph_cap_string(revoking)); 2769 - if ((revoking & not) == 0) { 2773 + if (!exclude || !(exclude & CEPH_CAP_FILE_BUFFER)) { 2770 2774 if (!snap_rwsem_locked && 2771 2775 !ci->i_head_snapc && 2772 2776 (need & CEPH_CAP_FILE_WR)) { ··· 2792 2788 snap_rwsem_locked = true; 2793 2789 } 2794 2790 if ((have & want) == want) 2795 - *got = need | want; 2791 + *got = need | (want & ~exclude); 2796 2792 else 2797 2793 *got = need; 2798 2794 ceph_take_cap_refs(ci, *got, true);