* [PATCH] ntfs: mount read-only when mft records are smaller than the device block
@ 2026-08-23 17:45 Dennis Tighe
2026-08-24 9:37 ` Hyunchul Lee
2026-08-25 5:47 ` [PATCH] " Christoph Hellwig
0 siblings, 2 replies; 6+ messages in thread
From: Dennis Tighe @ 2026-08-23 17:45 UTC (permalink / raw)
To: Namjae Jeon, Hyunchul Lee; +Cc: ntfs, linux-kernel
An mft record is written with a single bio of exactly mft_record_size
bytes. bio_unaligned() rejects a bio whose size is not a multiple of the
device's logical block size, so on a volume whose mft records are smaller
than that block no mft record can be written at all.
On 512n and 512e drives this is a non-issue; however, on 4Kn drives when
the mft record (1k) is smaller than the logical block size (4k) mft
writes begin to fail. At the same time, other writes that use all 4k
will succeed leading to a corruption situation.
This is a stopgap change that mounts as read-only. The longer term fix is
to perform 4k writes on 4Kn devices when writing the mft; however, that's
more involved.
Assisted-by: claude:claude-opus-5
Signed-off-by: Dennis Tighe <dennis.tighe@gmail.com>
---
From my testing:
Before this patch, on a volume with 20 files already on it:
ro mount rc=0
files visible: 20 <- reads are fine
rw mount rc=0
files created: 48 <- every creation reported success
umount rc=0
5 I/O errors logged
next mount:
ntfs_mft_record_check(): Record 64 has no FILE magic (0x0)
map_mft_record(): Failed with error code 5.
ntfs_lookup(): Found stale reference to inode 0x40 ... returning -EIO
files: 0
The volume would still mount at the end, but the directory read as empty.
Looking at the disk, the mft had not been updated but 4 INDX blocks in the
root directory had been written. This occurred since the mft writes from
the original mount were failing while other data writes were succeeding.
With this patch, same volume and device on my test script:
ntfs: (device vda): ntfs_fill_super(): mft record size (1024) is smaller
than the device logical block size (4096). Mft records cannot be
written. Mounting read-only.
mount rc=0
/dev/vda on /mnt/t type ntfs (ro,relatime,...)
Reproducing can be done without 4Kn hardware. I used a 4k image and qemu's
virtio-blk with logical_block_size=4096.
I noted this in the commit message, but this is very much a stopgap
measure to prevent corruption before full 4Kn support is added. It
seemed safer to me to fallback to read only for now and determine the
right path forward later. I believe there are a few options there that
are worth some discussion.
fs/ntfs/super.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 30481e5d5dd4..ed587bc5e477 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -2298,6 +2298,22 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
ntfs_debug("Changed device block size to %i bytes (block size bits %i) to match volume sector size.",
blocksize, sb->s_blocksize_bits);
}
+
+ /*
+ * If the device's logical block size is larger than the mft record (1k)
+ * writes to it will currently fail. Reads are unaffected, so we can still
+ * mount the volume as read-only.
+ */
+ if (vol->mft_record_size < bdev_logical_block_size(sb->s_bdev)) {
+ if (!sb_rdonly(sb)) {
+ ntfs_error(sb,
+ "mft record size (%i) is smaller than the device logical block size (%u). Mft records cannot be written. Mounting read-only.",
+ vol->mft_record_size,
+ bdev_logical_block_size(sb->s_bdev));
+ sb->s_flags |= SB_RDONLY;
+ }
+ }
+
/* Initialize the cluster and mft allocators. */
ntfs_setup_allocators(vol);
/* Setup remaining fields in the super block. */
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] ntfs: mount read-only when mft records are smaller than the device block
2026-08-23 17:45 [PATCH] ntfs: mount read-only when mft records are smaller than the device block Dennis Tighe
@ 2026-08-24 9:37 ` Hyunchul Lee
2026-08-24 14:42 ` [PATCH v2] " Dennis Tighe
2026-08-25 5:47 ` [PATCH] " Christoph Hellwig
1 sibling, 1 reply; 6+ messages in thread
From: Hyunchul Lee @ 2026-08-24 9:37 UTC (permalink / raw)
To: Dennis Tighe; +Cc: Namjae Jeon, ntfs, linux-kernel
Hi Dennis,
2026년 8월 24일 (월) 오전 2:45, Dennis Tighe <dennis.tighe@gmail.com>님이 작성:
> + if (vol->mft_record_size < bdev_logical_block_size(sb->s_bdev)) {
> + if (!sb_rdonly(sb)) {
> + ntfs_error(sb,
> + "mft record size (%i) is smaller than the device logical block size (%u). Mft records cannot be written. Mounting read-only.",
> + vol->mft_record_size,
> + bdev_logical_block_size(sb->s_bdev));
> + sb->s_flags |= SB_RDONLY;
> + }
> + }
This check is performed only during the initial mount.
A file system can be remounted read-write through
ntfs_reconfigure().
Please add this check to ntfs_reconfigure().
> +
> /* Initialize the cluster and mft allocators. */
> ntfs_setup_allocators(vol);
> /* Setup remaining fields in the super block. */
> --
> 2.43.0
>
--
Thanks,
Hyunchul
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2] ntfs: mount read-only when mft records are smaller than the device block
2026-08-24 9:37 ` Hyunchul Lee
@ 2026-08-24 14:42 ` Dennis Tighe
2026-08-25 1:30 ` Hyunchul Lee
0 siblings, 1 reply; 6+ messages in thread
From: Dennis Tighe @ 2026-08-24 14:42 UTC (permalink / raw)
To: Hyunchul Lee, Namjae Jeon; +Cc: ntfs, linux-kernel
An mft record is written with a single bio of exactly mft_record_size
bytes. bio_unaligned() rejects a bio whose size is not a multiple of the
device's logical block size, so on a volume whose mft records are smaller
than that block no mft record can be written at all.
On 512n and 512e drives this is a non-issue, since both report a 512-byte
logical block and a 1k record is a clean multiple of it. On 4Kn drives the
mft record (1k) is smaller than the 4k logical block, so every mft write
fails. At the same time, other writes (like directory index entries) that
are 4k will succeed leading references to unwritten mft records and a
corruption situation.
Reads are unaffected, so mount read-only rather than refusing outright,
and refuse a later remount read-write for the same reason.
This is a stopgap. Writing these volumes needs read-modify-write at the
device's block size, which this does not implement.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Dennis Tighe <dennis.tighe@gmail.com>
---
Changes in v2:
* Add the same check to ntfs_reconfigure(), so a later
"mount -o remount,rw" is refused rather than silently re-enabling the
writes. Thanks to Hyunchul Lee for catching this.
fs/ntfs/super.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 30481e5d5dd4..5de07fab101c 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -304,6 +304,12 @@ static int ntfs_reconfigure(struct fs_context *fc)
le16_to_cpu(vol->vol_flags), es);
return -EROFS;
}
+ if (vol->mft_record_size < bdev_logical_block_size(sb->s_bdev)) {
+ ntfs_error(sb, "mft record size (%i) is below the device block size (%u)%s",
+ vol->mft_record_size,
+ bdev_logical_block_size(sb->s_bdev), es);
+ return -EROFS;
+ }
if (vol->logfile_ino && !ntfs_empty_logfile(vol->logfile_ino)) {
ntfs_error(sb, "Failed to empty journal LogFile%s",
es);
@@ -2298,6 +2304,22 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
ntfs_debug("Changed device block size to %i bytes (block size bits %i) to match volume sector size.",
blocksize, sb->s_blocksize_bits);
}
+
+ /*
+ * If the device's logical block size is larger than the mft record (1k)
+ * writes to it will currently fail. Reads are unaffected, so we can still
+ * mount the volume as read-only.
+ */
+ if (vol->mft_record_size < bdev_logical_block_size(sb->s_bdev)) {
+ if (!sb_rdonly(sb)) {
+ ntfs_error(sb,
+ "mft record size (%i) is smaller than the device logical block size (%u). Mft records cannot be written. Mounting read-only.",
+ vol->mft_record_size,
+ bdev_logical_block_size(sb->s_bdev));
+ sb->s_flags |= SB_RDONLY;
+ }
+ }
+
/* Initialize the cluster and mft allocators. */
ntfs_setup_allocators(vol);
/* Setup remaining fields in the super block. */
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2] ntfs: mount read-only when mft records are smaller than the device block
2026-08-24 14:42 ` [PATCH v2] " Dennis Tighe
@ 2026-08-25 1:30 ` Hyunchul Lee
0 siblings, 0 replies; 6+ messages in thread
From: Hyunchul Lee @ 2026-08-25 1:30 UTC (permalink / raw)
To: Dennis Tighe; +Cc: Namjae Jeon, ntfs, linux-kernel
2026년 8월 24일 (월) 오후 11:42, Dennis Tighe <dennis.tighe@gmail.com>님이 작성:
>
> An mft record is written with a single bio of exactly mft_record_size
> bytes. bio_unaligned() rejects a bio whose size is not a multiple of the
> device's logical block size, so on a volume whose mft records are smaller
> than that block no mft record can be written at all.
>
> On 512n and 512e drives this is a non-issue, since both report a 512-byte
> logical block and a 1k record is a clean multiple of it. On 4Kn drives the
> mft record (1k) is smaller than the 4k logical block, so every mft write
> fails. At the same time, other writes (like directory index entries) that
> are 4k will succeed leading references to unwritten mft records and a
> corruption situation.
>
> Reads are unaffected, so mount read-only rather than refusing outright,
> and refuse a later remount read-write for the same reason.
>
> This is a stopgap. Writing these volumes needs read-modify-write at the
> device's block size, which this does not implement.
>
> Assisted-by: Claude:claude-opus-5
> Signed-off-by: Dennis Tighe <dennis.tighe@gmail.com>
Looks good to me.
Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
--
Thanks,
Hyunchul
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ntfs: mount read-only when mft records are smaller than the device block
2026-08-23 17:45 [PATCH] ntfs: mount read-only when mft records are smaller than the device block Dennis Tighe
2026-08-24 9:37 ` Hyunchul Lee
@ 2026-08-25 5:47 ` Christoph Hellwig
2026-08-25 7:28 ` Namjae Jeon
1 sibling, 1 reply; 6+ messages in thread
From: Christoph Hellwig @ 2026-08-25 5:47 UTC (permalink / raw)
To: Dennis Tighe; +Cc: Namjae Jeon, Hyunchul Lee, ntfs, linux-kernel
On Sun, Aug 23, 2026 at 10:45:48AM -0700, Dennis Tighe wrote:
> An mft record is written with a single bio of exactly mft_record_size
> bytes. bio_unaligned() rejects a bio whose size is not a multiple of the
> device's logical block size, so on a volume whose mft records are smaller
> than that block no mft record can be written at all.
>
> On 512n and 512e drives this is a non-issue; however, on 4Kn drives when
> the mft record (1k) is smaller than the logical block size (4k) mft
> writes begin to fail. At the same time, other writes that use all 4k
> will succeed leading to a corruption situation.
>
> This is a stopgap change that mounts as read-only. The longer term fix is
> to perform 4k writes on 4Kn devices when writing the mft; however, that's
> more involved.
Between this and your previous patch it is pretty clear that a sector
size > 512 bytes is not supported. So instead of adding predicted
band aids, reject this entirely for now and let someone who has the time
actually understand this for real fix it with a real design test plan
and all the others bits needed.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ntfs: mount read-only when mft records are smaller than the device block
2026-08-25 5:47 ` [PATCH] " Christoph Hellwig
@ 2026-08-25 7:28 ` Namjae Jeon
0 siblings, 0 replies; 6+ messages in thread
From: Namjae Jeon @ 2026-08-25 7:28 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Dennis Tighe, Hyunchul Lee, ntfs, linux-kernel
On Tue, Aug 25, 2026 at 2:47 PM Christoph Hellwig <hch@infradead.org> wrote:
>
> On Sun, Aug 23, 2026 at 10:45:48AM -0700, Dennis Tighe wrote:
> > An mft record is written with a single bio of exactly mft_record_size
> > bytes. bio_unaligned() rejects a bio whose size is not a multiple of the
> > device's logical block size, so on a volume whose mft records are smaller
> > than that block no mft record can be written at all.
> >
> > On 512n and 512e drives this is a non-issue; however, on 4Kn drives when
> > the mft record (1k) is smaller than the logical block size (4k) mft
> > writes begin to fail. At the same time, other writes that use all 4k
> > will succeed leading to a corruption situation.
> >
> > This is a stopgap change that mounts as read-only. The longer term fix is
> > to perform 4k writes on 4Kn devices when writing the mft; however, that's
> > more involved.
>
> Between this and your previous patch it is pretty clear that a sector
> size > 512 bytes is not supported. So instead of adding predicted
> band aids, reject this entirely for now and let someone who has the time
> actually understand this for real fix it with a real design test plan
> and all the others bits needed.
NTFS previously supported 4K native, so this seems to be a regression
introduced by some changes.
We will look into it a bit more and then decide whether to reject the mount.
Thanks!
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-08-25 7:28 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-23 17:45 [PATCH] ntfs: mount read-only when mft records are smaller than the device block Dennis Tighe
2026-08-24 9:37 ` Hyunchul Lee
2026-08-24 14:42 ` [PATCH v2] " Dennis Tighe
2026-08-25 1:30 ` Hyunchul Lee
2026-08-25 5:47 ` [PATCH] " Christoph Hellwig
2026-08-25 7:28 ` Namjae Jeon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox