[PATCH v4, RESEND] fs/dax: check zero or empty entry before converting xarray entry

Seunguk Shin <[email protected]>
Newsgroups org.kernel.vger.linux-fsdevel,dev.linux.lists.nvdimm,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
dax_associate_entry(), dax_disassociate_entry(), and dax_busy_page()
call dax_to_folio(entry) before checking whether entry is a zero or
empty xarray entry.

That ordering is wrong because zero and empty entries are not folio
entries. Commit 98c183a4fccf ("fs/dax: don't disassociate zero page
entries") added guards in the associate and disassociate paths, but the
guards still come after dax_to_folio(entry), and dax_busy_page() still
has the same problem.

Move the zero/empty checks before dax_to_folio(entry) in all three helpers.

Fixes: 38607c62b34b ("fs/dax: properly refcount fs dax pages")
Signed-off-by: Seunguk Shin <[email protected]>
Reviewed-by: Jan Kara <[email protected]>
Reviewed-by: Alistair Popple <[email protected]>
---
Changes in v4:
- Rebase on current upstream
- Link to v3: https://lore.kernel.org/all/[email protected]/
Changes in v3:
- Rebase on current upstream
- Update the changelog for the current code state
- Link to v2: https://lore.kernel.org/all/[email protected]/
Changes in v2:
- Add Fixes and Reviewed-by tags.
- Rebase on the latest.
- Link to v1: https://lore.kernel.org/all/[email protected]/
---
 fs/dax.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/fs/dax.c b/fs/dax.c
index 6d175cd47a99..4bca6e2bc342 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -480,11 +480,12 @@ static void dax_associate_entry(void *entry, struct address_space *mapping,
                                unsigned long address, bool shared)
 {
        unsigned long size = dax_entry_size(entry), index;
-       struct folio *folio = dax_to_folio(entry);
+       struct folio *folio;

        if (dax_is_zero_entry(entry) || dax_is_empty_entry(entry))
                return;

+       folio = dax_to_folio(entry);
        index = linear_page_index(vma, address & ~(size - 1));
        if (shared && (folio->mapping || dax_folio_is_shared(folio))) {
                if (folio->mapping)
@@ -505,21 +506,23 @@ static void dax_associate_entry(void *entry, struct address_space *mapping,
 static void dax_disassociate_entry(void *entry, struct address_space *mapping,
                                bool trunc)
 {
-       struct folio *folio = dax_to_folio(entry);
+       struct folio *folio;

        if (dax_is_zero_entry(entry) || dax_is_empty_entry(entry))
                return;

+       folio = dax_to_folio(entry);
        dax_folio_put(folio);
 }

 static struct page *dax_busy_page(void *entry)
 {
-       struct folio *folio = dax_to_folio(entry);
+       struct folio *folio;

        if (dax_is_zero_entry(entry) || dax_is_empty_entry(entry))
                return NULL;

+       folio = dax_to_folio(entry);
        if (folio_ref_count(folio) - folio_mapcount(folio))
                return &folio->page;
        else
--
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.