aboutsummaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-07-27 14:36:26 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-07-27 14:36:26 -0700
commit62cc90241548d5570ee68e01aaba6506964e9811 (patch)
tree33815e4c27b296dc0068c2ed20bab27f422ffc9e /fs
parentaa6fc3defb36b11eb82c4d1f4e95b5f6d8a0bca6 (diff)
parent40de8160ca7f67d14619ee0351ce5d68fc4a237a (diff)
Merge tag 'mm-hotfixes-stable-2026-07-27-14-18' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mmHEADmaster
Pull misc fixes from Andrew Morton: "13 hotfixes. All are cc:stable. 11 are for MM. All are singletons - please see the changelogs for details" * tag 'mm-hotfixes-stable-2026-07-27-14-18' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: fs/proc/task_mmu: fix PAGEMAP_SCAN written state for PMD holes mm/hugetlb: fix list corruption in allocate_file_region_entries() mm: mglru: fix stale batch updates after memcg reparenting selftest: fix headers in fclog.c ocfs2: fix boundary check in ocfs2_check_dir_entry() to use buffer offset mm/percpu-km: fix bitmap overflow and accounting in pcpu_create_chunk() mm/util: don't read __page_2 for order-1 folios in snapshot_page() mm/hugetlb: fix swap entry corruption when clearing uffd-wp at fork() mm: migrate_device: fix pte_pfn/pte_dirty called on non-present PTE fs/proc/task_mmu: fix PAGEMAP_SCAN written state for unpopulated ptes userfaultfd: wait on source PMD during UFFDIO_MOVE lib: test_hmm: use device devt for coherent device range selection mm/vmstat: fold stranded per-cpu node stats when a node comes online
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/dir.c5
-rw-r--r--fs/proc/task_mmu.c34
2 files changed, 33 insertions, 6 deletions
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 8e6b03238327..d7fc3cccf2f4 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -302,10 +302,11 @@ static int ocfs2_check_dir_entry(struct inode *dir,
unsigned long offset)
{
const char *error_msg = NULL;
+ unsigned long buf_offset = (char *)de - buf;
unsigned long next_offset;
int rlen;
- if (offset > size - OCFS2_DIR_REC_LEN(1)) {
+ if (buf_offset > size || size - buf_offset < OCFS2_DIR_REC_LEN(1)) {
/* Dirent is (maybe partially) beyond the buffer
* boundaries so touching 'de' members is unsafe.
*/
@@ -316,7 +317,7 @@ static int ocfs2_check_dir_entry(struct inode *dir,
}
rlen = le16_to_cpu(de->rec_len);
- next_offset = ((char *) de - buf) + rlen;
+ next_offset = buf_offset + rlen;
if (unlikely(rlen < OCFS2_DIR_REC_LEN(1)))
error_msg = "rec_len is smaller than minimal";
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index d32408f7cd5e..229d1fc3d7f1 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -2432,8 +2432,18 @@ static unsigned long pagemap_page_category(struct pagemap_scan_private *p,
{
unsigned long categories;
- if (pte_none(pte))
- return 0;
+ if (pte_none(pte)) {
+ /*
+ * An unpopulated pte carries no uffd-wp marker, i.e. it is not
+ * write-protected, the same condition under which the present
+ * and swap cases below report PAGE_IS_WRITTEN. Report it here
+ * too so this generic path agrees with the PAGE_IS_WRITTEN fast
+ * path in pagemap_scan_pmd_entry(), which reports pte_none as
+ * written and, under PM_SCAN_WP_MATCHING, arms a marker. The
+ * fast path applies no VMA test, so neither does this.
+ */
+ return PAGE_IS_WRITTEN;
+ }
if (pte_present(pte)) {
struct page *page;
@@ -3039,12 +3049,28 @@ static int pagemap_scan_pte_hole(unsigned long addr, unsigned long end,
{
struct pagemap_scan_private *p = walk->private;
struct vm_area_struct *vma = walk->vma;
+ unsigned long categories;
int ret, err;
- if (!vma || !pagemap_scan_is_interesting_page(p->cur_vma_category, p))
+ if (!vma)
+ return 0;
+
+ /*
+ * In a uffd-wp VMA an unpopulated range is treated as written:
+ * uffd-wp registration populates page tables and installs markers
+ * with WP_UNPOPULATED, so a missing marker means the range was
+ * zapped. See the pte_none() handling in pagemap_page_category().
+ *
+ * hugetlb differs, see pagemap_hugetlb_category().
+ */
+ categories = p->cur_vma_category;
+ if (userfaultfd_wp(vma) && !is_vm_hugetlb_page(vma))
+ categories |= PAGE_IS_WRITTEN;
+
+ if (!pagemap_scan_is_interesting_page(categories, p))
return 0;
- ret = pagemap_scan_output(p->cur_vma_category, p, addr, &end);
+ ret = pagemap_scan_output(categories, p, addr, &end);
if (addr == end)
return ret;