Unverified Commit d8e1e0d3 authored by Konstantin Komarov's avatar Konstantin Komarov
Browse files

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: default avatarKonstantin Komarov <almaz.alexandrovich@paragon-software.com>
parent ae91dfe3
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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);
}

+1 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -1075,6 +1075,7 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
		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;