diff options
| author | Konstantin Komarov <almaz.alexandrovich@paragon-software.com> | 2025-10-30 23:45:33 +0300 |
|---|---|---|
| committer | Konstantin Komarov <almaz.alexandrovich@paragon-software.com> | 2025-11-17 09:09:13 +0100 |
| commit | d8e1e0d33d975952e65945c9dd68c76c7f946435 (patch) | |
| tree | 7525a352dce488a5dcad0364ea0dd9c366cabc78 | |
| parent | ae91dfe38966fa30d713e705a69bf6c5c7f4c2aa (diff) | |
fs/ntfs3: check minimum alignment for direct I/O
Add a check for minimum alignment when performing direct I/O reads. If the
file offset or user buffer is not aligned to the device's logical block
size, fall back to buffered I/O instead of continuing with unaligned direct I/O.
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
| -rw-r--r-- | fs/ntfs3/file.c | 10 | ||||
| -rw-r--r-- | fs/ntfs3/ntfs_fs.h | 1 | ||||
| -rw-r--r-- | fs/ntfs3/super.c | 1 |
3 files changed, 12 insertions, 0 deletions
diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c index b9484f48db34..3b22c7375616 100644 --- a/fs/ntfs3/file.c +++ b/fs/ntfs3/file.c @@ -941,6 +941,16 @@ static ssize_t ntfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) file->f_ra.ra_pages = 0; } + /* Check minimum alignment for dio. */ + if (iocb->ki_flags & IOCB_DIRECT) { + struct super_block *sb = inode->i_sb; + struct ntfs_sb_info *sbi = sb->s_fs_info; + if ((iocb->ki_pos | iov_iter_alignment(iter)) & + sbi->bdev_blocksize_mask) { + iocb->ki_flags &= ~IOCB_DIRECT; + } + } + return generic_file_read_iter(iocb, iter); } diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h index 8ff49c5a2973..a4559c9f64e6 100644 --- a/fs/ntfs3/ntfs_fs.h +++ b/fs/ntfs3/ntfs_fs.h @@ -212,6 +212,7 @@ struct ntfs_sb_info { u32 discard_granularity; u64 discard_granularity_mask_inv; // ~(discard_granularity_mask_inv-1) + u32 bdev_blocksize_mask; // bdev_logical_block_size(bdev) - 1; u32 cluster_size; // bytes per cluster u32 cluster_mask; // == cluster_size - 1 diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c index 96f56333cf99..f481e9df0237 100644 --- a/fs/ntfs3/super.c +++ b/fs/ntfs3/super.c @@ -1075,6 +1075,7 @@ read_boot: dev_size += sector_size - 1; } + sbi->bdev_blocksize_mask = max(boot_sector_size, sector_size) - 1; sbi->mft.lbo = mlcn << cluster_bits; sbi->mft.lbo2 = mlcn2 << cluster_bits; |