--- /dev/null
+From d8b90e6387a74bcb1714c8d1e6a782ff709de9a9 Mon Sep 17 00:00:00 2001
+From: Baokun Li <libaokun1@huawei.com>
+Date: Thu, 21 Aug 2025 21:38:57 +0800
+Subject: ext4: add ext4_sb_bread_nofail() helper function for ext4_free_branches()
+
+From: Baokun Li <libaokun1@huawei.com>
+
+commit d8b90e6387a74bcb1714c8d1e6a782ff709de9a9 upstream.
+
+The implicit __GFP_NOFAIL flag in ext4_sb_bread() was removed in commit
+8a83ac54940d ("ext4: call bdev_getblk() from sb_getblk_gfp()"), meaning
+the function can now fail under memory pressure.
+
+Most callers of ext4_sb_bread() propagate the error to userspace and do not
+remount the filesystem read-only. However, ext4_free_branches() handles
+ext4_sb_bread() failure by remounting the filesystem read-only.
+
+This implies that an ext3 filesystem (mounted via the ext4 driver) could be
+forcibly remounted read-only due to a transient page allocation failure,
+which is unacceptable.
+
+To mitigate this, introduce a new helper function, ext4_sb_bread_nofail(),
+which explicitly uses __GFP_NOFAIL, and use it in ext4_free_branches().
+
+Fixes: 8a83ac54940d ("ext4: call bdev_getblk() from sb_getblk_gfp()")
+Cc: stable@kernel.org
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/ext4.h | 2 ++
+ fs/ext4/indirect.c | 2 +-
+ fs/ext4/super.c | 9 +++++++++
+ 3 files changed, 12 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -3144,6 +3144,8 @@ extern struct buffer_head *ext4_sb_bread
+ sector_t block, blk_opf_t op_flags);
+ extern struct buffer_head *ext4_sb_bread_unmovable(struct super_block *sb,
+ sector_t block);
++extern struct buffer_head *ext4_sb_bread_nofail(struct super_block *sb,
++ sector_t block);
+ extern void ext4_read_bh_nowait(struct buffer_head *bh, blk_opf_t op_flags,
+ bh_end_io_t *end_io, bool simu_fail);
+ extern int ext4_read_bh(struct buffer_head *bh, blk_opf_t op_flags,
+--- a/fs/ext4/indirect.c
++++ b/fs/ext4/indirect.c
+@@ -1025,7 +1025,7 @@ static void ext4_free_branches(handle_t
+ }
+
+ /* Go read the buffer for the next level down */
+- bh = ext4_sb_bread(inode->i_sb, nr, 0);
++ bh = ext4_sb_bread_nofail(inode->i_sb, nr);
+
+ /*
+ * A read failure? Report error and clear slot
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -265,6 +265,15 @@ struct buffer_head *ext4_sb_bread_unmova
+ return __ext4_sb_bread_gfp(sb, block, 0, gfp);
+ }
+
++struct buffer_head *ext4_sb_bread_nofail(struct super_block *sb,
++ sector_t block)
++{
++ gfp_t gfp = mapping_gfp_constraint(sb->s_bdev->bd_mapping,
++ ~__GFP_FS) | __GFP_MOVABLE | __GFP_NOFAIL;
++
++ return __ext4_sb_bread_gfp(sb, block, 0, gfp);
++}
++
+ void ext4_sb_breadahead_unmovable(struct super_block *sb, sector_t block)
+ {
+ struct buffer_head *bh = bdev_getblk(sb->s_bdev, block,
--- /dev/null
+From 8ecb790ea8c3fc69e77bace57f14cf0d7c177bd8 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Tue, 16 Sep 2025 23:22:47 -0400
+Subject: ext4: avoid potential buffer over-read in parse_apply_sb_mount_options()
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 8ecb790ea8c3fc69e77bace57f14cf0d7c177bd8 upstream.
+
+Unlike other strings in the ext4 superblock, we rely on tune2fs to
+make sure s_mount_opts is NUL terminated. Harden
+parse_apply_sb_mount_options() by treating s_mount_opts as a potential
+__nonstring.
+
+Cc: stable@vger.kernel.org
+Fixes: 8b67f04ab9de ("ext4: Add mount options in superblock")
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Message-ID: <20250916-tune2fs-v2-1-d594dc7486f0@mit.edu>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/super.c | 17 +++++------------
+ 1 file changed, 5 insertions(+), 12 deletions(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -2469,7 +2469,7 @@ static int parse_apply_sb_mount_options(
+ struct ext4_fs_context *m_ctx)
+ {
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+- char *s_mount_opts = NULL;
++ char s_mount_opts[65];
+ struct ext4_fs_context *s_ctx = NULL;
+ struct fs_context *fc = NULL;
+ int ret = -ENOMEM;
+@@ -2477,15 +2477,11 @@ static int parse_apply_sb_mount_options(
+ if (!sbi->s_es->s_mount_opts[0])
+ return 0;
+
+- s_mount_opts = kstrndup(sbi->s_es->s_mount_opts,
+- sizeof(sbi->s_es->s_mount_opts),
+- GFP_KERNEL);
+- if (!s_mount_opts)
+- return ret;
++ strscpy_pad(s_mount_opts, sbi->s_es->s_mount_opts);
+
+ fc = kzalloc(sizeof(struct fs_context), GFP_KERNEL);
+ if (!fc)
+- goto out_free;
++ return -ENOMEM;
+
+ s_ctx = kzalloc(sizeof(struct ext4_fs_context), GFP_KERNEL);
+ if (!s_ctx)
+@@ -2517,11 +2513,8 @@ parse_failed:
+ ret = 0;
+
+ out_free:
+- if (fc) {
+- ext4_fc_free(fc);
+- kfree(fc);
+- }
+- kfree(s_mount_opts);
++ ext4_fc_free(fc);
++ kfree(fc);
+ return ret;
+ }
+
--- /dev/null
+From 46c22a8bb4cb03211da1100d7ee4a2005bf77c70 Mon Sep 17 00:00:00 2001
+From: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Date: Fri, 5 Sep 2025 13:44:46 +0530
+Subject: ext4: correctly handle queries for metadata mappings
+
+From: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+
+commit 46c22a8bb4cb03211da1100d7ee4a2005bf77c70 upstream.
+
+Currently, our handling of metadata is _ambiguous_ in some scenarios,
+that is, we end up returning unknown if the range only covers the
+mapping partially.
+
+For example, in the following case:
+
+$ xfs_io -c fsmap -d
+
+ 0: 254:16 [0..7]: static fs metadata 8
+ 1: 254:16 [8..15]: special 102:1 8
+ 2: 254:16 [16..5127]: special 102:2 5112
+ 3: 254:16 [5128..5255]: special 102:3 128
+ 4: 254:16 [5256..5383]: special 102:4 128
+ 5: 254:16 [5384..70919]: inodes 65536
+ 6: 254:16 [70920..70967]: unknown 48
+ ...
+
+$ xfs_io -c fsmap -d 24 33
+
+ 0: 254:16 [24..39]: unknown 16 <--- incomplete reporting
+
+$ xfs_io -c fsmap -d 24 33 (With patch)
+
+ 0: 254:16 [16..5127]: special 102:2 5112
+
+This is because earlier in ext4_getfsmap_meta_helper, we end up ignoring
+any extent that starts before our queried range, but overlaps it. While
+the man page [1] is a bit ambiguous on this, this fix makes the output
+make more sense since we are anyways returning an "unknown" extent. This
+is also consistent to how XFS does it:
+
+$ xfs_io -c fsmap -d
+
+ ...
+ 6: 254:16 [104..127]: free space 24
+ 7: 254:16 [128..191]: inodes 64
+ ...
+
+$ xfs_io -c fsmap -d 137 150
+
+ 0: 254:16 [128..191]: inodes 64 <-- full extent returned
+
+ [1] https://man7.org/linux/man-pages/man2/ioctl_getfsmap.2.html
+
+Reported-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Cc: stable@kernel.org
+Signed-off-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Message-ID: <023f37e35ee280cd9baac0296cbadcbe10995cab.1757058211.git.ojaswin@linux.ibm.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/fsmap.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/fs/ext4/fsmap.c
++++ b/fs/ext4/fsmap.c
+@@ -74,7 +74,8 @@ static int ext4_getfsmap_dev_compare(con
+ static bool ext4_getfsmap_rec_before_low_key(struct ext4_getfsmap_info *info,
+ struct ext4_fsmap *rec)
+ {
+- return rec->fmr_physical < info->gfi_low.fmr_physical;
++ return rec->fmr_physical + rec->fmr_length <=
++ info->gfi_low.fmr_physical;
+ }
+
+ /*
+@@ -200,15 +201,18 @@ static int ext4_getfsmap_meta_helper(str
+ ext4_group_first_block_no(sb, agno));
+ fs_end = fs_start + EXT4_C2B(sbi, len);
+
+- /* Return relevant extents from the meta_list */
++ /*
++ * Return relevant extents from the meta_list. We emit all extents that
++ * partially/fully overlap with the query range
++ */
+ list_for_each_entry_safe(p, tmp, &info->gfi_meta_list, fmr_list) {
+- if (p->fmr_physical < info->gfi_next_fsblk) {
++ if (p->fmr_physical + p->fmr_length <= info->gfi_next_fsblk) {
+ list_del(&p->fmr_list);
+ kfree(p);
+ continue;
+ }
+- if (p->fmr_physical <= fs_start ||
+- p->fmr_physical + p->fmr_length <= fs_end) {
++ if (p->fmr_physical <= fs_end &&
++ p->fmr_physical + p->fmr_length > fs_start) {
+ /* Emit the retained free extent record if present */
+ if (info->gfi_lastfree.fmr_owner) {
+ error = ext4_getfsmap_helper(sb, info,
--- /dev/null
+From 963845748fe67125006859229487b45485564db7 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Mon, 1 Sep 2025 13:27:40 +0200
+Subject: ext4: fail unaligned direct IO write with EINVAL
+
+From: Jan Kara <jack@suse.cz>
+
+commit 963845748fe67125006859229487b45485564db7 upstream.
+
+Commit bc264fea0f6f ("iomap: support incremental iomap_iter advances")
+changed the error handling logic in iomap_iter(). Previously any error
+from iomap_dio_bio_iter() got propagated to userspace, after this commit
+if ->iomap_end returns error, it gets propagated to userspace instead of
+an error from iomap_dio_bio_iter(). This results in unaligned writes to
+ext4 to silently fallback to buffered IO instead of erroring out.
+
+Now returning ENOTBLK for DIO writes from ext4_iomap_end() seems
+unnecessary these days. It is enough to return ENOTBLK from
+ext4_iomap_begin() when we don't support DIO write for that particular
+file offset (due to hole).
+
+Fixes: bc264fea0f6f ("iomap: support incremental iomap_iter advances")
+Cc: stable@kernel.org
+Signed-off-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Message-ID: <20250901112739.32484-2-jack@suse.cz>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/inode.c | 35 -----------------------------------
+ 1 file changed, 35 deletions(-)
+
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 5b7a15db4953..c3b23c90fd11 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -3872,47 +3872,12 @@ static int ext4_iomap_overwrite_begin(struct inode *inode, loff_t offset,
+ return ret;
+ }
+
+-static inline bool ext4_want_directio_fallback(unsigned flags, ssize_t written)
+-{
+- /* must be a directio to fall back to buffered */
+- if ((flags & (IOMAP_WRITE | IOMAP_DIRECT)) !=
+- (IOMAP_WRITE | IOMAP_DIRECT))
+- return false;
+-
+- /* atomic writes are all-or-nothing */
+- if (flags & IOMAP_ATOMIC)
+- return false;
+-
+- /* can only try again if we wrote nothing */
+- return written == 0;
+-}
+-
+-static int ext4_iomap_end(struct inode *inode, loff_t offset, loff_t length,
+- ssize_t written, unsigned flags, struct iomap *iomap)
+-{
+- /*
+- * Check to see whether an error occurred while writing out the data to
+- * the allocated blocks. If so, return the magic error code for
+- * non-atomic write so that we fallback to buffered I/O and attempt to
+- * complete the remainder of the I/O.
+- * For non-atomic writes, any blocks that may have been
+- * allocated in preparation for the direct I/O will be reused during
+- * buffered I/O. For atomic write, we never fallback to buffered-io.
+- */
+- if (ext4_want_directio_fallback(flags, written))
+- return -ENOTBLK;
+-
+- return 0;
+-}
+-
+ const struct iomap_ops ext4_iomap_ops = {
+ .iomap_begin = ext4_iomap_begin,
+- .iomap_end = ext4_iomap_end,
+ };
+
+ const struct iomap_ops ext4_iomap_overwrite_ops = {
+ .iomap_begin = ext4_iomap_overwrite_begin,
+- .iomap_end = ext4_iomap_end,
+ };
+
+ static int ext4_iomap_begin_report(struct inode *inode, loff_t offset,
+--
+2.51.0
+
--- /dev/null
+From 12e803c8827d049ae8f2c743ef66ab87ae898375 Mon Sep 17 00:00:00 2001
+From: Zhang Yi <yi.zhang@huawei.com>
+Date: Fri, 12 Sep 2025 18:58:41 +0800
+Subject: ext4: fix an off-by-one issue during moving extents
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+commit 12e803c8827d049ae8f2c743ef66ab87ae898375 upstream.
+
+During the movement of a written extent, mext_page_mkuptodate() is
+called to read data in the range [from, to) into the page cache and to
+update the corresponding buffers. Therefore, we should not wait on any
+buffer whose start offset is >= 'to'. Otherwise, it will return -EIO and
+fail the extents movement.
+
+ $ for i in `seq 3 -1 0`; \
+ do xfs_io -fs -c "pwrite -b 1024 $((i * 1024)) 1024" /mnt/foo; \
+ done
+ $ umount /mnt && mount /dev/pmem1s /mnt # drop cache
+ $ e4defrag /mnt/foo
+ e4defrag 1.47.0 (5-Feb-2023)
+ ext4 defragmentation for /mnt/foo
+ [1/1]/mnt/foo: 0% [ NG ]
+ Success: [0/1]
+
+Cc: stable@kernel.org
+Fixes: a40759fb16ae ("ext4: remove array of buffer_heads from mext_page_mkuptodate()")
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Message-ID: <20250912105841.1886799-1-yi.zhang@huaweicloud.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/move_extent.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/move_extent.c
++++ b/fs/ext4/move_extent.c
+@@ -225,7 +225,7 @@ static int mext_page_mkuptodate(struct f
+ do {
+ if (bh_offset(bh) + blocksize <= from)
+ continue;
+- if (bh_offset(bh) > to)
++ if (bh_offset(bh) >= to)
+ break;
+ wait_on_buffer(bh);
+ if (buffer_uptodate(bh))
--- /dev/null
+From 57295e835408d8d425bef58da5253465db3d6888 Mon Sep 17 00:00:00 2001
+From: Ahmet Eray Karadag <eraykrdg1@gmail.com>
+Date: Sat, 20 Sep 2025 05:13:43 +0300
+Subject: ext4: guard against EA inode refcount underflow in xattr update
+
+From: Ahmet Eray Karadag <eraykrdg1@gmail.com>
+
+commit 57295e835408d8d425bef58da5253465db3d6888 upstream.
+
+syzkaller found a path where ext4_xattr_inode_update_ref() reads an EA
+inode refcount that is already <= 0 and then applies ref_change (often
+-1). That lets the refcount underflow and we proceed with a bogus value,
+triggering errors like:
+
+ EXT4-fs error: EA inode <n> ref underflow: ref_count=-1 ref_change=-1
+ EXT4-fs warning: ea_inode dec ref err=-117
+
+Make the invariant explicit: if the current refcount is non-positive,
+treat this as on-disk corruption, emit ext4_error_inode(), and fail the
+operation with -EFSCORRUPTED instead of updating the refcount. Delete the
+WARN_ONCE() as negative refcounts are now impossible; keep error reporting
+in ext4_error_inode().
+
+This prevents the underflow and the follow-on orphan/cleanup churn.
+
+Reported-by: syzbot+0be4f339a8218d2a5bb1@syzkaller.appspotmail.com
+Fixes: https://syzbot.org/bug?extid=0be4f339a8218d2a5bb1
+Cc: stable@kernel.org
+Co-developed-by: Albin Babu Varghese <albinbabuvarghese20@gmail.com>
+Signed-off-by: Albin Babu Varghese <albinbabuvarghese20@gmail.com>
+Signed-off-by: Ahmet Eray Karadag <eraykrdg1@gmail.com>
+Message-ID: <20250920021342.45575-1-eraykrdg1@gmail.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/xattr.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1019,7 +1019,7 @@ static int ext4_xattr_inode_update_ref(h
+ int ref_change)
+ {
+ struct ext4_iloc iloc;
+- s64 ref_count;
++ u64 ref_count;
+ int ret;
+
+ inode_lock_nested(ea_inode, I_MUTEX_XATTR);
+@@ -1029,13 +1029,17 @@ static int ext4_xattr_inode_update_ref(h
+ goto out;
+
+ ref_count = ext4_xattr_inode_get_ref(ea_inode);
++ if ((ref_count == 0 && ref_change < 0) || (ref_count == U64_MAX && ref_change > 0)) {
++ ext4_error_inode(ea_inode, __func__, __LINE__, 0,
++ "EA inode %lu ref wraparound: ref_count=%lld ref_change=%d",
++ ea_inode->i_ino, ref_count, ref_change);
++ ret = -EFSCORRUPTED;
++ goto out;
++ }
+ ref_count += ref_change;
+ ext4_xattr_inode_set_ref(ea_inode, ref_count);
+
+ if (ref_change > 0) {
+- WARN_ONCE(ref_count <= 0, "EA inode %lu ref_count=%lld",
+- ea_inode->i_ino, ref_count);
+-
+ if (ref_count == 1) {
+ WARN_ONCE(ea_inode->i_nlink, "EA inode %lu i_nlink=%u",
+ ea_inode->i_ino, ea_inode->i_nlink);
+@@ -1044,9 +1048,6 @@ static int ext4_xattr_inode_update_ref(h
+ ext4_orphan_del(handle, ea_inode);
+ }
+ } else {
+- WARN_ONCE(ref_count < 0, "EA inode %lu ref_count=%lld",
+- ea_inode->i_ino, ref_count);
+-
+ if (ref_count == 0) {
+ WARN_ONCE(ea_inode->i_nlink != 1,
+ "EA inode %lu i_nlink=%u",
--- /dev/null
+From 9d80eaa1a1d37539224982b76c9ceeee736510b9 Mon Sep 17 00:00:00 2001
+From: Yongjian Sun <sunyongjian1@huawei.com>
+Date: Thu, 11 Sep 2025 21:30:24 +0800
+Subject: ext4: increase i_disksize to offset + len in ext4_update_disksize_before_punch()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yongjian Sun <sunyongjian1@huawei.com>
+
+commit 9d80eaa1a1d37539224982b76c9ceeee736510b9 upstream.
+
+After running a stress test combined with fault injection,
+we performed fsck -a followed by fsck -fn on the filesystem
+image. During the second pass, fsck -fn reported:
+
+Inode 131512, end of extent exceeds allowed value
+ (logical block 405, physical block 1180540, len 2)
+
+This inode was not in the orphan list. Analysis revealed the
+following call chain that leads to the inconsistency:
+
+ ext4_da_write_end()
+ //does not update i_disksize
+ ext4_punch_hole()
+ //truncate folio, keep size
+ext4_page_mkwrite()
+ ext4_block_page_mkwrite()
+ ext4_block_write_begin()
+ ext4_get_block()
+ //insert written extent without update i_disksize
+journal commit
+echo 1 > /sys/block/xxx/device/delete
+
+da-write path updates i_size but does not update i_disksize. Then
+ext4_punch_hole truncates the da-folio yet still leaves i_disksize
+unchanged(in the ext4_update_disksize_before_punch function, the
+condition offset + len < size is met). Then ext4_page_mkwrite sees
+ext4_nonda_switch return 1 and takes the nodioread_nolock path, the
+folio about to be written has just been punched out, and it’s offset
+sits beyond the current i_disksize. This may result in a written
+extent being inserted, but again does not update i_disksize. If the
+journal gets committed and then the block device is yanked, we might
+run into this. It should be noted that replacing ext4_punch_hole with
+ext4_zero_range in the call sequence may also trigger this issue, as
+neither will update i_disksize under these circumstances.
+
+To fix this, we can modify ext4_update_disksize_before_punch to
+increase i_disksize to min(i_size, offset + len) when both i_size and
+(offset + len) are greater than i_disksize.
+
+Cc: stable@kernel.org
+Signed-off-by: Yongjian Sun <sunyongjian1@huawei.com>
+Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Message-ID: <20250911133024.1841027-1-sunyongjian@huaweicloud.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/inode.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -4252,7 +4252,11 @@ int ext4_can_truncate(struct inode *inod
+ * We have to make sure i_disksize gets properly updated before we truncate
+ * page cache due to hole punching or zero range. Otherwise i_disksize update
+ * can get lost as it may have been postponed to submission of writeback but
+- * that will never happen after we truncate page cache.
++ * that will never happen if we remove the folio containing i_size from the
++ * page cache. Also if we punch hole within i_size but above i_disksize,
++ * following ext4_page_mkwrite() may mistakenly allocate written blocks over
++ * the hole and thus introduce allocated blocks beyond i_disksize which is
++ * not allowed (e2fsck would complain in case of crash).
+ */
+ int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
+ loff_t len)
+@@ -4263,9 +4267,11 @@ int ext4_update_disksize_before_punch(st
+ loff_t size = i_size_read(inode);
+
+ WARN_ON(!inode_is_locked(inode));
+- if (offset > size || offset + len < size)
++ if (offset > size)
+ return 0;
+
++ if (offset + len < size)
++ size = offset + len;
+ if (EXT4_I(inode)->i_disksize >= size)
+ return 0;
+
--- /dev/null
+From 44d2a72f4d64655f906ba47a5e108733f59e6f28 Mon Sep 17 00:00:00 2001
+From: Deepanshu Kartikey <kartikey406@gmail.com>
+Date: Tue, 23 Sep 2025 19:02:45 +0530
+Subject: ext4: validate ea_ino and size in check_xattrs
+
+From: Deepanshu Kartikey <kartikey406@gmail.com>
+
+commit 44d2a72f4d64655f906ba47a5e108733f59e6f28 upstream.
+
+During xattr block validation, check_xattrs() processes xattr entries
+without validating that entries claiming to use EA inodes have non-zero
+sizes. Corrupted filesystems may contain xattr entries where e_value_size
+is zero but e_value_inum is non-zero, indicating invalid xattr data.
+
+Add validation in check_xattrs() to detect this corruption pattern early
+and return -EFSCORRUPTED, preventing invalid xattr entries from causing
+issues throughout the ext4 codebase.
+
+Cc: stable@kernel.org
+Suggested-by: Theodore Ts'o <tytso@mit.edu>
+Reported-by: syzbot+4c9d23743a2409b80293@syzkaller.appspotmail.com
+Link: https://syzkaller.appspot.com/bug?extid=4c9d23743a2409b80293
+Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Message-ID: <20250923133245.1091761-1-kartikey406@gmail.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/xattr.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -251,6 +251,10 @@ check_xattrs(struct inode *inode, struct
+ err_str = "invalid ea_ino";
+ goto errout;
+ }
++ if (ea_ino && !size) {
++ err_str = "invalid size in ea xattr";
++ goto errout;
++ }
+ if (size > EXT4_XATTR_SIZE_MAX) {
+ err_str = "e_value size too large";
+ goto errout;
--- /dev/null
+From 0a6ce20c156442a4ce2a404747bb0fb05d54eeb3 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Tue, 9 Sep 2025 13:22:07 +0200
+Subject: ext4: verify orphan file size is not too big
+
+From: Jan Kara <jack@suse.cz>
+
+commit 0a6ce20c156442a4ce2a404747bb0fb05d54eeb3 upstream.
+
+In principle orphan file can be arbitrarily large. However orphan replay
+needs to traverse it all and we also pin all its buffers in memory. Thus
+filesystems with absurdly large orphan files can lead to big amounts of
+memory consumed. Limit orphan file size to a sane value and also use
+kvmalloc() for allocating array of block descriptor structures to avoid
+large order allocations for sane but large orphan files.
+
+Reported-by: syzbot+0b92850d68d9b12934f5@syzkaller.appspotmail.com
+Fixes: 02f310fcf47f ("ext4: Speedup ext4 orphan inode handling")
+Cc: stable@kernel.org
+Signed-off-by: Jan Kara <jack@suse.cz>
+Message-ID: <20250909112206.10459-2-jack@suse.cz>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/orphan.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/orphan.c
++++ b/fs/ext4/orphan.c
+@@ -583,9 +583,20 @@ int ext4_init_orphan_info(struct super_b
+ ext4_msg(sb, KERN_ERR, "get orphan inode failed");
+ return PTR_ERR(inode);
+ }
++ /*
++ * This is just an artificial limit to prevent corrupted fs from
++ * consuming absurd amounts of memory when pinning blocks of orphan
++ * file in memory.
++ */
++ if (inode->i_size > 8 << 20) {
++ ext4_msg(sb, KERN_ERR, "orphan file too big: %llu",
++ (unsigned long long)inode->i_size);
++ ret = -EFSCORRUPTED;
++ goto out_put;
++ }
+ oi->of_blocks = inode->i_size >> sb->s_blocksize_bits;
+ oi->of_csum_seed = EXT4_I(inode)->i_csum_seed;
+- oi->of_binfo = kmalloc_array(oi->of_blocks,
++ oi->of_binfo = kvmalloc_array(oi->of_blocks,
+ sizeof(struct ext4_orphan_block),
+ GFP_KERNEL);
+ if (!oi->of_binfo) {
media-iris-fix-missing-last-flag-handling-during-drain.patch
media-iris-fix-format-check-for-capture-plane-in-try_fmt.patch
media-iris-allow-stop-on-firmware-only-if-start-was-issued.patch
+ext4-add-ext4_sb_bread_nofail-helper-function-for-ext4_free_branches.patch
+ext4-fail-unaligned-direct-io-write-with-einval.patch
+ext4-verify-orphan-file-size-is-not-too-big.patch
+ext4-increase-i_disksize-to-offset-len-in-ext4_update_disksize_before_punch.patch
+ext4-correctly-handle-queries-for-metadata-mappings.patch
+ext4-avoid-potential-buffer-over-read-in-parse_apply_sb_mount_options.patch
+ext4-fix-an-off-by-one-issue-during-moving-extents.patch
+ext4-guard-against-ea-inode-refcount-underflow-in-xattr-update.patch
+ext4-validate-ea_ino-and-size-in-check_xattrs.patch