fs/dax: check zero or empty entry before converting xarray entry
PATCH RESEND v4 1/1 fs/dax: check zero or empty entry before converting xarray entry
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.
---
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(-)
fs/dax.c +6 -3
@@ -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
Quoted 9 lines · On Thu, 30 Jul 2026 14:12:55 +0100 Seunguk Shin <[email protected]> wrote:
dax_associate_entry(),dax_disassociate_entry(), anddax_busy_page()calldax_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 afterdax_to_folio(entry), anddax_busy_page()still has the same problem.
Are there any known userspace-visible runtime effects of this?
If so, please fully describe them in the changelog. If not, please also mention that.
This is important information for deciding which kernel(s) need the patch.
Quoted 1 line
Move the zero/empty checks before
dax_to_folio(entry)in all three helpers.
Thanks.
Hi Andrew,
Thank you for looking into this.
Quoted 1 line
Are there any known userspace-visible runtime effects of this?
Yes. I'm trying to fix this because it caused kernel panic on a VM with DAX in kata-containers project:
https://github.com/kata-containers/kata-containers/commit/1c154b4c15cfc63e06ad1c48a801064677e874e2
I'll add kernel panic message in the commit log like patch v2:
https://lore.kernel.org/all/[email protected]/
Thank you.