diff options
author | Matthew Wilcox (Oracle) <willy@infradead.org> | 2022-03-31 08:27:09 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-04-15 14:18:28 +0200 |
commit | 9a8835902eb66efa716e86aae853ae3122dc0ba5 (patch) | |
tree | 978cb289569c11544fc20d037518d2102fe21830 /lib | |
parent | cbd110b8dd7ad763bf413f71c0484116ae9302d4 (diff) | |
download | linux-stable-9a8835902eb66efa716e86aae853ae3122dc0ba5.tar.gz linux-stable-9a8835902eb66efa716e86aae853ae3122dc0ba5.tar.bz2 linux-stable-9a8835902eb66efa716e86aae853ae3122dc0ba5.zip |
XArray: Update the LRU list in xas_split()
commit 3ed4bb77156da0bc732847c8c9df92454c1fbeea upstream.
When splitting a value entry, we may need to add the new nodes to the LRU
list and remove the parent node from the LRU list. The WARN_ON checks
in shadow_lru_isolate() catch this oversight. This bug was latent
until we stopped splitting folios in shrink_page_list() with commit
820c4e2e6f51 ("mm/vmscan: Free non-shmem folios without splitting them").
That allows the creation of large shadow entries, and subsequently when
trying to page in a small page, we will split the large shadow entry
in __filemap_add_folio().
Fixes: 8fc75643c5e1 ("XArray: add xas_split")
Reported-by: Hugh Dickins <hughd@google.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/xarray.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/lib/xarray.c b/lib/xarray.c index 6a2ad7451bdd..61464c52c20e 100644 --- a/lib/xarray.c +++ b/lib/xarray.c @@ -1080,6 +1080,7 @@ void xas_split(struct xa_state *xas, void *entry, unsigned int order) xa_mk_node(child)); if (xa_is_value(curr)) values--; + xas_update(xas, child); } else { unsigned int canon = offset - xas->xa_sibs; @@ -1094,6 +1095,7 @@ void xas_split(struct xa_state *xas, void *entry, unsigned int order) } while (offset-- > xas->xa_offset); node->nr_values += values; + xas_update(xas, node); } EXPORT_SYMBOL_GPL(xas_split); #endif |