Commit 37020bbb authored by Jingbo Xu's avatar Jingbo Xu Committed by Gao Xiang
Browse files

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: d435d532 ("erofs: change to use asynchronous io for fscache readpage/readahead")
Suggested-by: default avatarDavid Howells <dhowells@redhat.com>
Reviewed-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
Reviewed-by: default avatarJia Zhu <zhujia.zj@bytedance.com>
Signed-off-by: default avatarJingbo Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20221114121943.29987-1-jefflexu@linux.alibaba.com


Signed-off-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
parent 39bfcb81
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -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;