From: Yuan-Hao Hsu <aa9736195201@gmail.com>
To: Miklos Szeredi <miklos@szeredi.hu>, Amir Goldstein <amir73il@gmail.com>
Cc: linux-unionfs@vger.kernel.org, linux-kernel@vger.kernel.org,
Yuan-Hao Hsu <aa9736195201@gmail.com>
Subject: [PATCH] ovl: implement ->get_unmapped_area()
Date: Fri, 28 Aug 2026 01:07:18 +0800 [thread overview]
Message-ID: <20260827170718.497-1-aa9736195201@gmail.com> (raw)
ovl_mmap() passes realfile to the underlying filesystem, so the VMA it
returns is backed by realfile, not by the overlayfs file.
Address selection is not delegated. __get_unmapped_area() looks at the
overlayfs file's f_op, ovl_file_operations does not implement
->get_unmapped_area(), and the mapping lands wherever
mm_get_unmapped_area() puts it. ext4, xfs and btrfs all point
->get_unmapped_area() at thp_get_unmapped_area(); none of that is reached.
vaddr - file_offset is then not a multiple of PMD_SIZE,
thp_vma_suitable_order() rejects the VMA, and the PMD-sized folios the
underlying filesystem already has in the page cache are never mapped by
a PMD.
Delegate to the file ovl_mmap() will use. Calling thp_get_unmapped_area()
here instead would force alignment on filesystems that deliberately do
not implement ->get_unmapped_area(), which commit 34d7cf637c43 ("mm:
don't try THP alignment for FS without get_unmapped_area") avoided.
fs/proc delegates the same way in pde_get_unmapped_area().
Reading a 1025M ext4 file through mmap(NULL, ...), 97% of its page cache
in PMD-sized folios, 15 runs:
PMD congruent minor faults page tables
ext4, directly 15/15 764 68K
overlayfs, before 0/5 16186 2056K
overlayfs, after 15/15 764 68K
Fault counts had 0 stddev. Median read time 17.4ms -> 4.80ms, against
4.92ms for the same file on ext4.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Yuan-Hao Hsu <aa9736195201@gmail.com>
---
fs/overlayfs/file.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
index f3d97eb146e8..0d985025f4c8 100644
--- a/fs/overlayfs/file.c
+++ b/fs/overlayfs/file.c
@@ -13,6 +13,7 @@
#include <linux/security.h>
#include <linux/fs.h>
#include <linux/backing-file.h>
+#include <linux/sched/mm.h>
#include "overlayfs.h"
static char ovl_whatisit(struct inode *inode, struct inode *realinode)
@@ -465,6 +466,30 @@ static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
return vfs_fsync_range(upperfile, start, end, datasync);
}
+static unsigned long ovl_get_unmapped_area(struct file *file,
+ unsigned long addr, unsigned long len,
+ unsigned long pgoff, unsigned long flags)
+{
+ struct ovl_file *of = file->private_data;
+ struct file *realfile = of->realfile;
+
+ /*
+ * ovl_mmap() hands realfile to the underlying filesystem, so the vma
+ * ends up backed by realfile. Let that filesystem pick the address
+ * too, or one that needs a specific alignment - to allow PMD mappings,
+ * for example - never gets asked for one.
+ */
+ if (realfile->f_op->get_unmapped_area)
+ return realfile->f_op->get_unmapped_area(realfile, addr, len,
+ pgoff, flags);
+
+#ifdef CONFIG_MMU
+ return mm_get_unmapped_area(file, addr, len, pgoff, flags);
+#endif
+
+ return addr;
+}
+
static int ovl_mmap(struct file *file, struct vm_area_struct *vma)
{
struct ovl_file *of = file->private_data;
@@ -654,6 +679,7 @@ const struct file_operations ovl_file_operations = {
.write_iter = ovl_write_iter,
.fsync = ovl_fsync,
.mmap = ovl_mmap,
+ .get_unmapped_area = ovl_get_unmapped_area,
.fallocate = ovl_fallocate,
.fadvise = ovl_fadvise,
.flush = ovl_flush,
base-commit: 26260251022fbc2f248a3d747a9b2b961b18d2d8
next reply other threads:[~2026-08-27 17:07 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-27 17:07 Yuan-Hao Hsu [this message]
2026-08-28 12:23 ` [PATCH] ovl: implement ->get_unmapped_area() Amir Goldstein
2026-08-28 12:41 ` Matthew Wilcox
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260827170718.497-1-aa9736195201@gmail.com \
--to=aa9736195201@gmail.com \
--cc=amir73il@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-unionfs@vger.kernel.org \
--cc=miklos@szeredi.hu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.