1
0
mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2026-01-19 04:44:09 +00:00
Matthew Wilcox (Oracle) 7e934cf5ac xarray: Fix early termination of xas_for_each_marked
xas_for_each_marked() is using entry == NULL as a termination condition
of the iteration. When xas_for_each_marked() is used protected only by
RCU, this can however race with xas_store(xas, NULL) in the following
way:

TASK1                                   TASK2
page_cache_delete()         	        find_get_pages_range_tag()
                                          xas_for_each_marked()
                                            xas_find_marked()
                                              off = xas_find_chunk()

  xas_store(&xas, NULL)
    xas_init_marks(&xas);
    ...
    rcu_assign_pointer(*slot, NULL);
                                              entry = xa_entry(off);

And thus xas_for_each_marked() terminates prematurely possibly leading
to missed entries in the iteration (translating to missing writeback of
some pages or a similar problem).

If we find a NULL entry that has been marked, skip it (unless we're trying
to allocate an entry).

Reported-by: Jan Kara <jack@suse.cz>
CC: stable@vger.kernel.org
Fixes: ef8e5717db01 ("page cache: Convert delete_batch to XArray")
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
2020-03-12 17:42:08 -04:00
..
2019-12-05 11:43:31 -08:00
2019-11-27 10:17:28 -08:00
2019-12-05 11:43:31 -08:00
2019-11-26 10:26:26 +01:00
2019-11-28 11:16:43 -08:00
2019-12-03 11:20:37 +01:00
2019-12-08 12:42:19 +01:00
2019-12-05 12:27:16 -08:00
2019-12-02 14:46:22 -08:00
2019-12-09 10:36:44 -08:00
2019-12-02 14:46:22 -08:00
2019-12-11 12:22:38 -08:00
2019-11-27 11:06:20 -08:00
2019-12-01 12:59:06 -08:00
2019-12-04 19:44:14 -08:00
2019-12-09 10:36:44 -08:00
2019-12-25 17:08:33 -07:00
2019-12-06 10:28:09 -08:00
2019-12-03 13:58:22 -08:00
2019-12-06 10:47:28 +01:00
2019-12-06 10:28:09 -08:00
2019-12-05 11:43:31 -08:00
2019-11-30 14:35:43 -08:00
2019-12-01 06:29:17 -08:00
2020-01-02 16:15:33 -08:00
2019-12-01 14:00:59 -08:00