ceph: avoid pending truncate during nonblocking cap acquire
Subsystems (2)
PATCH 1/1 ceph: avoid pending truncate during nonblocking cap acquire
Readahead acquires caps while the folios are locked. This can deadlock when processing a pending truncate; truncate_pagecache() can then attempt to a folio that is already locked.
Return -EAGAIN instead when NON_BLOCKING is set, causing the readahead to be abandoned.
Fixes 49870056005c ("ceph: convert ceph_readpages to ceph_readahead")
Signed-off-by Max Kellermann <[email protected]>
--- fs/ceph/caps.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/ceph/caps.c +4 -0
@@ -2889,6 +2889,10 @@ static int try_get_cap_refs(struct inode *inode, int need, int want, }/* finish pending truncate */ +if (ci->i_truncate_pending && (flags &NON_BLOCKING )) { + ret = -EAGAIN ; + goto out_unlock; + }while (ci->i_truncate_pending) {spin_unlock (&ci->i_ceph_lock);if (snap_rwsem_locked) {
Signature · 1 line
2.47.3
LGTM.
Reviewed-by Xiubo Li <[email protected]>
Quoted 33 lines · Max Kellermann
Readahead acquires caps while the folios are locked. This can deadlock when processing a pending truncate;
truncate_pagecache()can then attempt to a folio that is already locked.Return
-EAGAINinstead whenNON_BLOCKINGis set, causing the readahead to be abandoned.Fixes 49870056005c ("ceph: convert ceph_readpages to ceph_readahead")Signed-off-by Max Kellermann <[email protected]>--- fs/ceph/caps.c | 4 ++++ 1 file changed, 4 insertions(+)fs/ceph/caps.c +4
-1@@ -2889,6 +2889,10 @@ static int try_get_cap_refs(struct inode *inode, int need, int want, }/* finish pending truncate */ +if (ci->i_truncate_pending && (flags &NON_BLOCKING )) { + ret = -EAGAIN ; + goto out_unlock; + }while (ci->i_truncate_pending) {spin_unlock (&ci->i_ceph_lock);if (snap_rwsem_locked) { --2.47.3