[SRU][R][PATCH 1/1] ntfs3: use page allocation for resident attribute inline data
Viktor Pashaiev
w.paszajew at gmail.com
Thu Sep 17 18:50:39 UTC 2026
From: Namjae Jeon <linkinjeon at kernel.org>
BugLink: https://bugs.launchpad.net/bugs/2165844
kmemdup() based allocation for IOMAP_INLINE can result in inline_data
having a non-zero page offset. This triggers a kernel BUG at
fs/iomap/buffered-io.c:1061 when iomap->length exceeds the remaining
page space.
Fix this by using alloc_page() so page_address() is always page-aligned.
(backported from commit 36ee1313199b7f16bf963c6ac0241861585125d9)
[Viktor Pashaiev: adjusted file paths from fs/ntfs/ to fs/ntfs3/ for 7.0]
Signed-off-by: Namjae Jeon <linkinjeon at kernel.org>
Signed-off-by: Viktor Pashaiev <w.paszajew at gmail.com>
---
fs/ntfs3/attrib.c | 10 +++++++---
fs/ntfs3/inode.c | 6 +++---
2 files changed, 10 insertions(+), 6 deletions(-)
--- a/fs/ntfs3/attrib.c
+++ b/fs/ntfs3/attrib.c
@@ -1042,10 +1042,14 @@ int attr_data_get_block_locked(struct ntfs_inode *ni, CLST vcn, CLST clen,
*lcn = RESIDENT_LCN;
*len = data_size;
if (res && data_size) {
- *res = kmemdup(resident_data(attr_b), data_size,
- GFP_KERNEL);
- if (!*res)
+ struct page *page = alloc_page(GFP_NOFS | __GFP_ZERO);
+ if (page) {
+ memcpy(page_address(page), resident_data(attr_b),
+ data_size);
+ *res = page;
+ } else {
err = -ENOMEM;
+ }
}
goto out;
}
--- a/fs/ntfs3/inode.c
+++ b/fs/ntfs3/inode.c
@@ -845,7 +845,7 @@ static int ntfs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
if (lcn == RESIDENT_LCN) {
if (offset >= clen) {
- kfree(res);
+ put_page((struct page *)res);
if (flags & IOMAP_REPORT) {
/* special code for report. */
return -ENOENT;
@@ -853,7 +853,8 @@ static int ntfs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
return -EFAULT;
}
- iomap->private = iomap->inline_data = res;
+ iomap->private = res;
+ iomap->inline_data = page_address((struct page *)res);
iomap->type = IOMAP_INLINE;
iomap->offset = 0;
iomap->length = clen; /* resident size in bytes. */
@@ -965,7 +966,7 @@ static int ntfs_iomap_end(struct inode *inode, loff_t pos, loff_t length,
out:
if (iomap->type == IOMAP_INLINE) {
- kfree(iomap->private);
+ put_page((struct page *)iomap->private);
iomap->private = NULL;
}
--
2.43.0
More information about the kernel-team
mailing list