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();
|
||||
xas_for_each(&xas, folio, last_page) {
|
||||
unsigned int pgpos =
|
||||
(folio_index(folio) - start_page) * PAGE_SIZE;
|
||||
unsigned int pgend = pgpos + folio_size(folio);
|
||||
unsigned int pgpos, pgend;
|
||||
bool pg_failed = false;
|
||||
|
||||
if (xas_retry(&xas, folio))
|
||||
continue;
|
||||
|
||||
pgpos = (folio_index(folio) - start_page) * PAGE_SIZE;
|
||||
pgend = pgpos + folio_size(folio);
|
||||
|
||||
for (;;) {
|
||||
if (!subreq) {
|
||||
pg_failed = true;
|
||||
|
Loading…
Reference in New Issue
Block a user