[RFC 8/8] ext4: Adds atomic writes using fsawu

From: Ritesh Harjani (IBM)
Date: Sat Mar 02 2024 - 02:45:30 EST


atomic write using fsawu (filesystem atomic write unit) means, a
filesystem can supports doing atomic writes as long as all of
below constraints are satisfied -
1. underlying block device HW supports atomic writes.
2. fsawu_[min|max] (fs blocksize or bigalloc cluster size), should
be within the HW boundary range of awu_min and awu_max.

If this constraints are satisfied that a filesystem can do atomic
writes. There are no underlying filesystem layout changes required to
enable this. This patch enables this support in ext4 during mount time
if the underlying HW supports it.
We set a runtime mount flag to enable this support.

After this patch ext4 can support atomic writes with pwritev2's
RWF_ATOMIC flag with direct-io with -
1. mkfs.ext4 -b <BS=8k/16k/32k/64k> <dev_path>
(for a large pagesize system)
2. mkfs.ext4 -b <BS> -C <CS> <dev_path> (with bigalloc)

Co-developed-by: Ojaswin Mujoo <ojaswin@xxxxxxxxxxxxx>
Signed-off-by: Ojaswin Mujoo <ojaswin@xxxxxxxxxxxxx>
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@xxxxxxxxx>
---
fs/ext4/ext4.h | 28 ++++++++++++++++++++++++++++
fs/ext4/super.c | 1 +
2 files changed, 29 insertions(+)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index aa7fff2d6f96..529ca32b9813 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -3896,6 +3896,34 @@ static inline void ext4_atomic_write_fsawu(struct super_block *sb,
*fsawu_max = 0;
}

+/**
+ * ext4_init_atomic_write ext4 init atomic writes using fsawu
+ * @sb super_block
+ *
+ * Function to initialize atomic/untorn write support using fsawu.
+ * TODO: In future, when mballoc will get aligned allocations support,
+ * then we can enable atomic write support for ext4 without fsawu restrictions.
+ */
+static inline void ext4_init_atomic_write(struct super_block *sb)
+{
+ struct block_device *bdev = sb->s_bdev;
+ unsigned int fsawu_min, fsawu_max;
+
+ if (!ext4_has_feature_extents(sb))
+ return;
+
+ if (!bdev_can_atomic_write(bdev))
+ return;
+
+ ext4_atomic_write_fsawu(sb, &fsawu_min, &fsawu_max);
+ if (fsawu_min && fsawu_max) {
+ ext4_set_mount_flag(sb, EXT4_MF_ATOMIC_WRITE_FSAWU);
+ ext4_msg(sb, KERN_NOTICE,
+ "Supports atomic writes using EXT4_MF_ATOMIC_WRITE_FSAWU, fsawu_min %u fsawu_max: %u",
+ fsawu_min, fsawu_max);
+ }
+}
+
#endif /* __KERNEL__ */

#define EFSBADCRC EBADMSG /* Bad CRC detected */
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 0f931d0c227d..971bfd093997 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -5352,6 +5352,7 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
mutex_init(&sbi->s_orphan_lock);

ext4_fast_commit_init(sb);
+ ext4_init_atomic_write(sb);

sb->s_root = NULL;

--
2.43.0