erofs: fix missing xas_retry() in fscache mode
The xarray iteration only holds the RCU read lock and thus may encounter
XA_RETRY_ENTRY if there's process modifying the xarray concurrently.
This will cause oops when referring to the invalid entry.
Fix this by adding the missing xas_retry(), which will make the
iteration wind back to the root node if XA_RETRY_ENTRY is encountered.
Fixes: d435d53228
("erofs: change to use asynchronous io for fscache readpage/readahead")
Suggested-by: David Howells <dhowells@redhat.com>
Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Reviewed-by: Jia Zhu <zhujia.zj@bytedance.com>
Signed-off-by: Jingbo Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20221114121943.29987-1-jefflexu@linux.alibaba.com
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
This commit is contained in:
parent
39bfcb8138
commit
37020bbb71
@ -75,11 +75,15 @@ static void erofs_fscache_rreq_unlock_folios(struct netfs_io_request *rreq)
|
|||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
xas_for_each(&xas, folio, last_page) {
|
xas_for_each(&xas, folio, last_page) {
|
||||||
unsigned int pgpos =
|
unsigned int pgpos, pgend;
|
||||||
(folio_index(folio) - start_page) * PAGE_SIZE;
|
|
||||||
unsigned int pgend = pgpos + folio_size(folio);
|
|
||||||
bool pg_failed = false;
|
bool pg_failed = false;
|
||||||
|
|
||||||
|
if (xas_retry(&xas, folio))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pgpos = (folio_index(folio) - start_page) * PAGE_SIZE;
|
||||||
|
pgend = pgpos + folio_size(folio);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!subreq) {
|
if (!subreq) {
|
||||||
pg_failed = true;
|
pg_failed = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user