* [PATCH RFC v2 0/3] ext4: don't complete atomic writes through buffered I/O
@ 2026-10-12 17:17 Tal Zussman
2026-10-12 17:17 ` [PATCH RFC v2 1/3] ext4: reject atomic writes on inodes that can't do direct I/O Tal Zussman
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Tal Zussman @ 2026-10-12 17:17 UTC (permalink / raw)
To: Theodore Ts'o, Andreas Dilger, Baokun Li, Jan Kara,
Ojaswin Mujoo, Ritesh Harjani (IBM), Zhang Yi, Christoph Hellwig,
John Garry, Darrick J. Wong
Cc: linux-block, linux-ext4, linux-kernel, Sashiko, Tal Zussman
ext4_dio_write_iter() has two ways to finish a write through the page
cache: the fallback for inodes that can't do direct I/O at all, and the
completion of a short direct write. Neither provides torn-write
protection, and neither refuses IOCB_ATOMIC.
Patch 1 fixes a reachable bug: an atomic write to a data-journaled
inode is advertised by statx() and then silently done as a buffered
write. Patch 2 makes a short atomic direct write fail with -EIO instead
of falling back. That path should be unreachable today, so this is
defensive. Patch 3 closes the same kind of gap for DAX inodes,
which ext4_file_write_iter() hands to the DAX path before any atomic
write handling. No DAX-capable device advertises atomic write limits
today, so this one is defensive too, and matches XFS.
With a scsi_debug device, on a data=journal mount, and with chattr +j on
a nodelalloc mount, the unpatched kernel reports atomic write limits via
statx() and completes an O_DIRECT RWF_ATOMIC pwritev2() as a buffered
write. With the series, statx() reports awu_min=0 and the write fails
with -EOPNOTSUPP. Ordinary extent files still complete atomic writes,
and the WARN_ON_ONCE() in patch 2 did not fire under an fio atomic
direct write workload.
---
Changes in v2:
- Patch 1 (new): Reject atomic writes on inodes that can't do direct
I/O at all, where the fallback to buffered I/O is reachable, per
Sashiko.
- Patch 2: Fail a short atomic direct write with -EIO and keep the
WARN_ON_ONCE(), instead of returning the short count.
- Patch 3 (new): don't advertise atomic writes for DAX inodes.
- Link to v1: https://patch.msgid.link/20260909-ext4-atomic-no-fallback-v1-1-5a6b9539c002@columbia.edu
---
Tal Zussman (3):
ext4: reject atomic writes on inodes that can't do direct I/O
ext4: never fall back to buffered I/O for atomic direct writes
ext4: don't advertise atomic writes for DAX inodes
fs/ext4/ext4.h | 9 ++++++++-
fs/ext4/file.c | 17 +++++++++++++----
2 files changed, 21 insertions(+), 5 deletions(-)
---
base-commit: df2908090cda368b01ff43709f51890076c56157
change-id: 20260909-ext4-atomic-no-fallback-b1550a7a3fcf
Best regards,
--
Tal Zussman <tz2294@columbia.edu>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH RFC v2 1/3] ext4: reject atomic writes on inodes that can't do direct I/O
2026-10-12 17:17 [PATCH RFC v2 0/3] ext4: don't complete atomic writes through buffered I/O Tal Zussman
@ 2026-10-12 17:17 ` Tal Zussman
2026-10-12 17:33 ` sashiko-bot
2026-10-13 12:27 ` Jan Kara
2026-10-12 17:17 ` [PATCH RFC v2 2/3] ext4: never fall back to buffered I/O for atomic direct writes Tal Zussman
2026-10-12 17:17 ` [PATCH RFC v2 3/3] ext4: don't advertise atomic writes for DAX inodes Tal Zussman
2 siblings, 2 replies; 10+ messages in thread
From: Tal Zussman @ 2026-10-12 17:17 UTC (permalink / raw)
To: Theodore Ts'o, Andreas Dilger, Baokun Li, Jan Kara,
Ojaswin Mujoo, Ritesh Harjani (IBM), Zhang Yi, Christoph Hellwig,
John Garry, Darrick J. Wong
Cc: linux-block, linux-ext4, linux-kernel, Sashiko, Tal Zussman
ext4_dio_write_iter() falls back to buffered I/O when the inode can't do
direct I/O at all, i.e. journaled data, inline data or verity. That
fallback runs before any atomic write handling, and
ext4_buffered_write_iter() doesn't look at IOCB_ATOMIC, so an atomic
write to such an inode is silently done as a plain buffered write with
no torn-write protection.
ext4_inode_can_atomic_write() makes it worse for journaled data by
advertising atomic writes for those inodes: statx() reports atomic write
limits and the file gets FMODE_CAN_ATOMIC_WRITE, so the write passes the
VFS checks and reaches the fallback. This is reachable with
data=journal, or with chattr +j on a nodelalloc mount. Inline data
inodes don't have the extents flag and verity files can't be opened for
writing, so those are refused before ext4 sees the write, but the
fallback would still accept them.
Reject IOCB_ATOMIC in ext4_buffered_write_iter(), next to the existing
IOCB_NOWAIT rejection, so neither fallback into it can complete an
atomic write non-atomically. Also require ext4_dio_alignment() to be
nonzero in ext4_inode_can_atomic_write(), so statx() stops advertising
atomic writes for these inodes and VFS refuses RWF_ATOMIC early. The
runtime check is still needed, as the journal data flag can be changed
on an open file.
Fixes: b7987a7d69a4 ("ext4: Support setting FMODE_CAN_ATOMIC_WRITE")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/20260909-ext4-atomic-no-fallback-v1-1-5a6b9539c002%40columbia.edu
Signed-off-by: Tal Zussman <tz2294@columbia.edu>
---
fs/ext4/ext4.h | 8 +++++++-
fs/ext4/file.c | 8 ++++++++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 724a27e8be61..5115f067a9f5 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -4057,12 +4057,18 @@ static inline int ext4_buffer_uptodate(struct buffer_head *bh)
return buffer_uptodate(bh);
}
+/*
+ * Atomic writes are only supported through direct I/O, so an inode that
+ * can't do direct I/O at all (journaled data, inline data, verity) can't do
+ * atomic writes either.
+ */
static inline bool ext4_inode_can_atomic_write(struct inode *inode)
{
return S_ISREG(inode->i_mode) &&
ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
- EXT4_SB(inode->i_sb)->s_awu_min > 0;
+ EXT4_SB(inode->i_sb)->s_awu_min > 0 &&
+ ext4_dio_alignment(inode) != 0;
}
extern int ext4_block_write_begin(handle_t *handle, struct folio *folio,
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 374b4bc25bd5..19a8843ac420 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -339,6 +339,14 @@ static ssize_t ext4_buffered_write_iter(struct kiocb *iocb,
if (iocb->ki_flags & IOCB_NOWAIT)
return -EOPNOTSUPP;
+ /*
+ * Buffered I/O provides no torn-write protection. The direct I/O path
+ * falls back here for inodes that can't do direct I/O at all, so an
+ * atomic write must be rejected rather than silently done non-atomically.
+ */
+ if (iocb->ki_flags & IOCB_ATOMIC)
+ return -EOPNOTSUPP;
+
inode_lock(inode);
/*
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH RFC v2 2/3] ext4: never fall back to buffered I/O for atomic direct writes
2026-10-12 17:17 [PATCH RFC v2 0/3] ext4: don't complete atomic writes through buffered I/O Tal Zussman
2026-10-12 17:17 ` [PATCH RFC v2 1/3] ext4: reject atomic writes on inodes that can't do direct I/O Tal Zussman
@ 2026-10-12 17:17 ` Tal Zussman
2026-10-12 17:28 ` sashiko-bot
2026-10-13 12:28 ` Jan Kara
2026-10-12 17:17 ` [PATCH RFC v2 3/3] ext4: don't advertise atomic writes for DAX inodes Tal Zussman
2 siblings, 2 replies; 10+ messages in thread
From: Tal Zussman @ 2026-10-12 17:17 UTC (permalink / raw)
To: Theodore Ts'o, Andreas Dilger, Baokun Li, Jan Kara,
Ojaswin Mujoo, Ritesh Harjani (IBM), Zhang Yi, Christoph Hellwig,
John Garry, Darrick J. Wong
Cc: linux-block, linux-ext4, linux-kernel, Tal Zussman
ext4_dio_write_iter() finishes a short direct write through the page
cache. ext4_buffered_write_iter() now rejects IOCB_ATOMIC, so a short
atomic write would warn and then fail with -EOPNOTSUPP, as if atomic
writes were unsupported on the inode.
This came out of a block device fix [1], where an IOCB_ATOMIC direct
write could complete short when only part of the buffer could be
pinned, with the rest going through the buffered fallback. Christoph
Hellwig noted that ext4 has the same fallback and only warns in it [2],
and John Garry agreed it should reject the write instead [3].
In contrast to the block device, nothing reaches the branch on ext4
today: iomap requires the mapping to cover the whole atomic write, a
buffer that can't be pinned in full fails in iomap before the bio is
submitted, and a failed page cache invalidation returns -EAGAIN rather
than reaching the buffered fallback. A short atomic write is therefore
a bug, and neither a short count nor -EOPNOTSUPP is a valid result for
one. Fail the write with -EIO before the fallback, keeping the WARN()
so any future bug is visible.
Link: https://lore.kernel.org/linux-block/20260828-blkdev-fixes-v2-0-32f3f40cebed@columbia.edu/ [1]
Link: https://lore.kernel.org/linux-block/20260907071217.GD934@lst.de/ [2]
Link: https://lore.kernel.org/linux-block/a7752d1e-8ec1-44d1-a266-c287c315e8ab@oracle.com/ [3]
Signed-off-by: Tal Zussman <tz2294@columbia.edu>
---
fs/ext4/file.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 19a8843ac420..11e375bd4ed1 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -679,11 +679,12 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)
loff_t endbyte;
/*
- * There is no support for atomic writes on buffered-io yet,
- * we should never fallback to buffered-io for DIO atomic
- * writes.
+ * Buffered I/O provides no torn-write protection, so never
+ * finish an atomic write through the page cache. iomap must
+ * not return a short atomic write, so treat one as a bug.
*/
- WARN_ON_ONCE(iocb->ki_flags & IOCB_ATOMIC);
+ if (WARN_ON_ONCE(iocb->ki_flags & IOCB_ATOMIC))
+ return -EIO;
offset = iocb->ki_pos;
err = ext4_buffered_write_iter(iocb, from);
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH RFC v2 3/3] ext4: don't advertise atomic writes for DAX inodes
2026-10-12 17:17 [PATCH RFC v2 0/3] ext4: don't complete atomic writes through buffered I/O Tal Zussman
2026-10-12 17:17 ` [PATCH RFC v2 1/3] ext4: reject atomic writes on inodes that can't do direct I/O Tal Zussman
2026-10-12 17:17 ` [PATCH RFC v2 2/3] ext4: never fall back to buffered I/O for atomic direct writes Tal Zussman
@ 2026-10-12 17:17 ` Tal Zussman
2026-10-12 17:25 ` sashiko-bot
2026-10-13 12:30 ` Jan Kara
2 siblings, 2 replies; 10+ messages in thread
From: Tal Zussman @ 2026-10-12 17:17 UTC (permalink / raw)
To: Theodore Ts'o, Andreas Dilger, Baokun Li, Jan Kara,
Ojaswin Mujoo, Ritesh Harjani (IBM), Zhang Yi, Christoph Hellwig,
John Garry, Darrick J. Wong
Cc: linux-block, linux-ext4, linux-kernel, Tal Zussman
ext4_file_write_iter() hands DAX inodes to ext4_dax_write_iter() before
any of the atomic write handling, and the DAX path neither checks
IOCB_ATOMIC nor provides torn-write protection.
ext4_inode_can_atomic_write() doesn't exclude DAX inodes, so on a device
that supported both DAX and atomic writes, statx() would advertise
atomic writes for such an inode and the VFS would let an RWF_ATOMIC
write through to a plain DAX write.
No DAX-capable block device advertises atomic write limits today, so
this isn't reachable. When XFS gained its corresponding check, Ritesh
Harjani suggested excluding DAX inodes in ext4 anyway [1], so that what
is advertised matches what the write path can do. XFS does the same in
xfs_inode_can_hw_atomic_write() and xfs_inode_can_sw_atomic_write().
Link: https://lore.kernel.org/linux-ext4/87a54e4cdn.fsf@gmail.com/ [1]
Signed-off-by: Tal Zussman <tz2294@columbia.edu>
---
fs/ext4/ext4.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 5115f067a9f5..1520baf581b6 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -4060,12 +4060,13 @@ static inline int ext4_buffer_uptodate(struct buffer_head *bh)
/*
* Atomic writes are only supported through direct I/O, so an inode that
* can't do direct I/O at all (journaled data, inline data, verity) can't do
- * atomic writes either.
+ * atomic writes either. DAX inodes bypass the direct I/O path entirely.
*/
static inline bool ext4_inode_can_atomic_write(struct inode *inode)
{
return S_ISREG(inode->i_mode) &&
+ !IS_DAX(inode) &&
ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
EXT4_SB(inode->i_sb)->s_awu_min > 0 &&
ext4_dio_alignment(inode) != 0;
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH RFC v2 3/3] ext4: don't advertise atomic writes for DAX inodes
2026-10-12 17:17 ` [PATCH RFC v2 3/3] ext4: don't advertise atomic writes for DAX inodes Tal Zussman
@ 2026-10-12 17:25 ` sashiko-bot
2026-10-13 12:30 ` Jan Kara
1 sibling, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-10-12 17:25 UTC (permalink / raw)
To: Tal Zussman; +Cc: tytso, linux-ext4
> ext4_file_write_iter() hands DAX inodes to ext4_dax_write_iter() before
> any of the atomic write handling, and the DAX path neither checks
> IOCB_ATOMIC nor provides torn-write protection.
> ext4_inode_can_atomic_write() doesn't exclude DAX inodes, so on a device
> that supported both DAX and atomic writes, statx() would advertise
> atomic writes for such an inode and the VFS would let an RWF_ATOMIC
> write through to a plain DAX write.
>
> No DAX-capable block device advertises atomic write limits today, so
> this isn't reachable. When XFS gained its corresponding check, Ritesh
> Harjani suggested excluding DAX inodes in ext4 anyway [1], so that what
> is advertised matches what the write path can do. XFS does the same in
> xfs_inode_can_hw_atomic_write() and xfs_inode_can_sw_atomic_write().
>
> Link: https://lore.kernel.org/linux-ext4/87a54e4cdn.fsf@gmail.com/ [1]
> Signed-off-by: Tal Zussman <tz2294@columbia.edu>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261012-ext4-atomic-no-fallback-v2-0-c4b30c60e500@columbia.edu?part=3
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH RFC v2 2/3] ext4: never fall back to buffered I/O for atomic direct writes
2026-10-12 17:17 ` [PATCH RFC v2 2/3] ext4: never fall back to buffered I/O for atomic direct writes Tal Zussman
@ 2026-10-12 17:28 ` sashiko-bot
2026-10-13 12:28 ` Jan Kara
1 sibling, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-10-12 17:28 UTC (permalink / raw)
To: Tal Zussman; +Cc: linux-ext4, tytso
> ext4_dio_write_iter() finishes a short direct write through the page
> cache. ext4_buffered_write_iter() now rejects IOCB_ATOMIC, so a short
> atomic write would warn and then fail with -EOPNOTSUPP, as if atomic
> writes were unsupported on the inode.
>
> This came out of a block device fix [1], where an IOCB_ATOMIC direct
> write could complete short when only part of the buffer could be
> pinned, with the rest going through the buffered fallback. Christoph
> Hellwig noted that ext4 has the same fallback and only warns in it [2],
> and John Garry agreed it should reject the write instead [3].
>
> In contrast to the block device, nothing reaches the branch on ext4
> today: iomap requires the mapping to cover the whole atomic write, a
> buffer that can't be pinned in full fails in iomap before the bio is
> submitted, and a failed page cache invalidation returns -EAGAIN rather
> than reaching the buffered fallback. A short atomic write is therefore
> a bug, and neither a short count nor -EOPNOTSUPP is a valid result for
> one. Fail the write with -EIO before the fallback, keeping the WARN()
> so any future bug is visible.
>
> Link: https://lore.kernel.org/linux-block/20260828-blkdev-fixes-v2-0-32f3f40cebed@columbia.edu/ [1]
> Link: https://lore.kernel.org/linux-block/20260907071217.GD934@lst.de/ [2]
> Link: https://lore.kernel.org/linux-block/a7752d1e-8ec1-44d1-a266-c287c315e8ab@oracle.com/ [3]
> Signed-off-by: Tal Zussman <tz2294@columbia.edu>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261012-ext4-atomic-no-fallback-v2-0-c4b30c60e500@columbia.edu?part=2
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH RFC v2 1/3] ext4: reject atomic writes on inodes that can't do direct I/O
2026-10-12 17:17 ` [PATCH RFC v2 1/3] ext4: reject atomic writes on inodes that can't do direct I/O Tal Zussman
@ 2026-10-12 17:33 ` sashiko-bot
2026-10-13 12:27 ` Jan Kara
1 sibling, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-10-12 17:33 UTC (permalink / raw)
To: Tal Zussman; +Cc: tytso, linux-ext4
> ext4_dio_write_iter() falls back to buffered I/O when the inode can't do
> direct I/O at all, i.e. journaled data, inline data or verity. That
> fallback runs before any atomic write handling, and
> ext4_buffered_write_iter() doesn't look at IOCB_ATOMIC, so an atomic
> write to such an inode is silently done as a plain buffered write with
> no torn-write protection.
>
> ext4_inode_can_atomic_write() makes it worse for journaled data by
> advertising atomic writes for those inodes: statx() reports atomic write
> limits and the file gets FMODE_CAN_ATOMIC_WRITE, so the write passes the
> VFS checks and reaches the fallback. This is reachable with
> data=journal, or with chattr +j on a nodelalloc mount. Inline data
> inodes don't have the extents flag and verity files can't be opened for
> writing, so those are refused before ext4 sees the write, but the
> fallback would still accept them.
>
> Reject IOCB_ATOMIC in ext4_buffered_write_iter(), next to the existing
> IOCB_NOWAIT rejection, so neither fallback into it can complete an
> atomic write non-atomically. Also require ext4_dio_alignment() to be
> nonzero in ext4_inode_can_atomic_write(), so statx() stops advertising
> atomic writes for these inodes and VFS refuses RWF_ATOMIC early. The
> runtime check is still needed, as the journal data flag can be changed
> on an open file.
>
> Fixes: b7987a7d69a4 ("ext4: Support setting FMODE_CAN_ATOMIC_WRITE")
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Link: https://sashiko.dev/#/patchset/20260909-ext4-atomic-no-fallback-v1-1-5a6b9539c002%40columbia.edu
> Signed-off-by: Tal Zussman <tz2294@columbia.edu>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261012-ext4-atomic-no-fallback-v2-0-c4b30c60e500@columbia.edu?part=1
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH RFC v2 1/3] ext4: reject atomic writes on inodes that can't do direct I/O
2026-10-12 17:17 ` [PATCH RFC v2 1/3] ext4: reject atomic writes on inodes that can't do direct I/O Tal Zussman
2026-10-12 17:33 ` sashiko-bot
@ 2026-10-13 12:27 ` Jan Kara
1 sibling, 0 replies; 10+ messages in thread
From: Jan Kara @ 2026-10-13 12:27 UTC (permalink / raw)
To: Tal Zussman
Cc: Theodore Ts'o, Andreas Dilger, Baokun Li, Jan Kara,
Ojaswin Mujoo, Ritesh Harjani (IBM), Zhang Yi, Christoph Hellwig,
John Garry, Darrick J. Wong, linux-block, linux-ext4,
linux-kernel, Sashiko
On Mon 12-10-26 13:17:40, Tal Zussman wrote:
> ext4_dio_write_iter() falls back to buffered I/O when the inode can't do
> direct I/O at all, i.e. journaled data, inline data or verity. That
> fallback runs before any atomic write handling, and
> ext4_buffered_write_iter() doesn't look at IOCB_ATOMIC, so an atomic
> write to such an inode is silently done as a plain buffered write with
> no torn-write protection.
>
> ext4_inode_can_atomic_write() makes it worse for journaled data by
> advertising atomic writes for those inodes: statx() reports atomic write
> limits and the file gets FMODE_CAN_ATOMIC_WRITE, so the write passes the
> VFS checks and reaches the fallback. This is reachable with
> data=journal, or with chattr +j on a nodelalloc mount. Inline data
> inodes don't have the extents flag and verity files can't be opened for
> writing, so those are refused before ext4 sees the write, but the
> fallback would still accept them.
>
> Reject IOCB_ATOMIC in ext4_buffered_write_iter(), next to the existing
> IOCB_NOWAIT rejection, so neither fallback into it can complete an
> atomic write non-atomically. Also require ext4_dio_alignment() to be
> nonzero in ext4_inode_can_atomic_write(), so statx() stops advertising
> atomic writes for these inodes and VFS refuses RWF_ATOMIC early. The
> runtime check is still needed, as the journal data flag can be changed
> on an open file.
>
> Fixes: b7987a7d69a4 ("ext4: Support setting FMODE_CAN_ATOMIC_WRITE")
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Link: https://sashiko.dev/#/patchset/20260909-ext4-atomic-no-fallback-v1-1-5a6b9539c002%40columbia.edu
> Signed-off-by: Tal Zussman <tz2294@columbia.edu>
Looks good. Feel free to add:
Reviewed-by: Jan Kara <jack@suse.cz>
Honza
> ---
> fs/ext4/ext4.h | 8 +++++++-
> fs/ext4/file.c | 8 ++++++++
> 2 files changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> index 724a27e8be61..5115f067a9f5 100644
> --- a/fs/ext4/ext4.h
> +++ b/fs/ext4/ext4.h
> @@ -4057,12 +4057,18 @@ static inline int ext4_buffer_uptodate(struct buffer_head *bh)
> return buffer_uptodate(bh);
> }
>
> +/*
> + * Atomic writes are only supported through direct I/O, so an inode that
> + * can't do direct I/O at all (journaled data, inline data, verity) can't do
> + * atomic writes either.
> + */
> static inline bool ext4_inode_can_atomic_write(struct inode *inode)
> {
>
> return S_ISREG(inode->i_mode) &&
> ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
> - EXT4_SB(inode->i_sb)->s_awu_min > 0;
> + EXT4_SB(inode->i_sb)->s_awu_min > 0 &&
> + ext4_dio_alignment(inode) != 0;
> }
>
> extern int ext4_block_write_begin(handle_t *handle, struct folio *folio,
> diff --git a/fs/ext4/file.c b/fs/ext4/file.c
> index 374b4bc25bd5..19a8843ac420 100644
> --- a/fs/ext4/file.c
> +++ b/fs/ext4/file.c
> @@ -339,6 +339,14 @@ static ssize_t ext4_buffered_write_iter(struct kiocb *iocb,
> if (iocb->ki_flags & IOCB_NOWAIT)
> return -EOPNOTSUPP;
>
> + /*
> + * Buffered I/O provides no torn-write protection. The direct I/O path
> + * falls back here for inodes that can't do direct I/O at all, so an
> + * atomic write must be rejected rather than silently done non-atomically.
> + */
> + if (iocb->ki_flags & IOCB_ATOMIC)
> + return -EOPNOTSUPP;
> +
> inode_lock(inode);
>
> /*
>
> --
> 2.39.5
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH RFC v2 2/3] ext4: never fall back to buffered I/O for atomic direct writes
2026-10-12 17:17 ` [PATCH RFC v2 2/3] ext4: never fall back to buffered I/O for atomic direct writes Tal Zussman
2026-10-12 17:28 ` sashiko-bot
@ 2026-10-13 12:28 ` Jan Kara
1 sibling, 0 replies; 10+ messages in thread
From: Jan Kara @ 2026-10-13 12:28 UTC (permalink / raw)
To: Tal Zussman
Cc: Theodore Ts'o, Andreas Dilger, Baokun Li, Jan Kara,
Ojaswin Mujoo, Ritesh Harjani (IBM), Zhang Yi, Christoph Hellwig,
John Garry, Darrick J. Wong, linux-block, linux-ext4,
linux-kernel
On Mon 12-10-26 13:17:41, Tal Zussman wrote:
> ext4_dio_write_iter() finishes a short direct write through the page
> cache. ext4_buffered_write_iter() now rejects IOCB_ATOMIC, so a short
> atomic write would warn and then fail with -EOPNOTSUPP, as if atomic
> writes were unsupported on the inode.
>
> This came out of a block device fix [1], where an IOCB_ATOMIC direct
> write could complete short when only part of the buffer could be
> pinned, with the rest going through the buffered fallback. Christoph
> Hellwig noted that ext4 has the same fallback and only warns in it [2],
> and John Garry agreed it should reject the write instead [3].
>
> In contrast to the block device, nothing reaches the branch on ext4
> today: iomap requires the mapping to cover the whole atomic write, a
> buffer that can't be pinned in full fails in iomap before the bio is
> submitted, and a failed page cache invalidation returns -EAGAIN rather
> than reaching the buffered fallback. A short atomic write is therefore
> a bug, and neither a short count nor -EOPNOTSUPP is a valid result for
> one. Fail the write with -EIO before the fallback, keeping the WARN()
> so any future bug is visible.
>
> Link: https://lore.kernel.org/linux-block/20260828-blkdev-fixes-v2-0-32f3f40cebed@columbia.edu/ [1]
> Link: https://lore.kernel.org/linux-block/20260907071217.GD934@lst.de/ [2]
> Link: https://lore.kernel.org/linux-block/a7752d1e-8ec1-44d1-a266-c287c315e8ab@oracle.com/ [3]
> Signed-off-by: Tal Zussman <tz2294@columbia.edu>
Looks good. Feel free to add:
Reviewed-by: Jan Kara <jack@suse.cz>
Honza
> ---
> fs/ext4/file.c | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/fs/ext4/file.c b/fs/ext4/file.c
> index 19a8843ac420..11e375bd4ed1 100644
> --- a/fs/ext4/file.c
> +++ b/fs/ext4/file.c
> @@ -679,11 +679,12 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)
> loff_t endbyte;
>
> /*
> - * There is no support for atomic writes on buffered-io yet,
> - * we should never fallback to buffered-io for DIO atomic
> - * writes.
> + * Buffered I/O provides no torn-write protection, so never
> + * finish an atomic write through the page cache. iomap must
> + * not return a short atomic write, so treat one as a bug.
> */
> - WARN_ON_ONCE(iocb->ki_flags & IOCB_ATOMIC);
> + if (WARN_ON_ONCE(iocb->ki_flags & IOCB_ATOMIC))
> + return -EIO;
>
> offset = iocb->ki_pos;
> err = ext4_buffered_write_iter(iocb, from);
>
> --
> 2.39.5
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH RFC v2 3/3] ext4: don't advertise atomic writes for DAX inodes
2026-10-12 17:17 ` [PATCH RFC v2 3/3] ext4: don't advertise atomic writes for DAX inodes Tal Zussman
2026-10-12 17:25 ` sashiko-bot
@ 2026-10-13 12:30 ` Jan Kara
1 sibling, 0 replies; 10+ messages in thread
From: Jan Kara @ 2026-10-13 12:30 UTC (permalink / raw)
To: Tal Zussman
Cc: Theodore Ts'o, Andreas Dilger, Baokun Li, Jan Kara,
Ojaswin Mujoo, Ritesh Harjani (IBM), Zhang Yi, Christoph Hellwig,
John Garry, Darrick J. Wong, linux-block, linux-ext4,
linux-kernel
On Mon 12-10-26 13:17:42, Tal Zussman wrote:
> ext4_file_write_iter() hands DAX inodes to ext4_dax_write_iter() before
> any of the atomic write handling, and the DAX path neither checks
> IOCB_ATOMIC nor provides torn-write protection.
> ext4_inode_can_atomic_write() doesn't exclude DAX inodes, so on a device
> that supported both DAX and atomic writes, statx() would advertise
> atomic writes for such an inode and the VFS would let an RWF_ATOMIC
> write through to a plain DAX write.
>
> No DAX-capable block device advertises atomic write limits today, so
> this isn't reachable. When XFS gained its corresponding check, Ritesh
> Harjani suggested excluding DAX inodes in ext4 anyway [1], so that what
> is advertised matches what the write path can do. XFS does the same in
> xfs_inode_can_hw_atomic_write() and xfs_inode_can_sw_atomic_write().
>
> Link: https://lore.kernel.org/linux-ext4/87a54e4cdn.fsf@gmail.com/ [1]
> Signed-off-by: Tal Zussman <tz2294@columbia.edu>
Looks good. Feel free to add:
Reviewed-by: Jan Kara <jack@suse.cz>
Honza
> ---
> fs/ext4/ext4.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> index 5115f067a9f5..1520baf581b6 100644
> --- a/fs/ext4/ext4.h
> +++ b/fs/ext4/ext4.h
> @@ -4060,12 +4060,13 @@ static inline int ext4_buffer_uptodate(struct buffer_head *bh)
> /*
> * Atomic writes are only supported through direct I/O, so an inode that
> * can't do direct I/O at all (journaled data, inline data, verity) can't do
> - * atomic writes either.
> + * atomic writes either. DAX inodes bypass the direct I/O path entirely.
> */
> static inline bool ext4_inode_can_atomic_write(struct inode *inode)
> {
>
> return S_ISREG(inode->i_mode) &&
> + !IS_DAX(inode) &&
> ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
> EXT4_SB(inode->i_sb)->s_awu_min > 0 &&
> ext4_dio_alignment(inode) != 0;
>
> --
> 2.39.5
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-10-13 12:30 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-12 17:17 [PATCH RFC v2 0/3] ext4: don't complete atomic writes through buffered I/O Tal Zussman
2026-10-12 17:17 ` [PATCH RFC v2 1/3] ext4: reject atomic writes on inodes that can't do direct I/O Tal Zussman
2026-10-12 17:33 ` sashiko-bot
2026-10-13 12:27 ` Jan Kara
2026-10-12 17:17 ` [PATCH RFC v2 2/3] ext4: never fall back to buffered I/O for atomic direct writes Tal Zussman
2026-10-12 17:28 ` sashiko-bot
2026-10-13 12:28 ` Jan Kara
2026-10-12 17:17 ` [PATCH RFC v2 3/3] ext4: don't advertise atomic writes for DAX inodes Tal Zussman
2026-10-12 17:25 ` sashiko-bot
2026-10-13 12:30 ` Jan Kara
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox