Skip to content

Commit 37020bb

Browse files
lostjefflehsiangkao
authored andcommitted
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: d435d53 ("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>
1 parent 39bfcb8 commit 37020bb

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

fs/erofs/fscache.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,15 @@ static void erofs_fscache_rreq_unlock_folios(struct netfs_io_request *rreq)
7575

7676
rcu_read_lock();
7777
xas_for_each(&xas, folio, last_page) {
78-
unsigned int pgpos =
79-
(folio_index(folio) - start_page) * PAGE_SIZE;
80-
unsigned int pgend = pgpos + folio_size(folio);
78+
unsigned int pgpos, pgend;
8179
bool pg_failed = false;
8280

81+
if (xas_retry(&xas, folio))
82+
continue;
83+
84+
pgpos = (folio_index(folio) - start_page) * PAGE_SIZE;
85+
pgend = pgpos + folio_size(folio);
86+
8387
for (;;) {
8488
if (!subreq) {
8589
pg_failed = true;

0 commit comments

Comments
 (0)