mirror of
https://github.com/torvalds/linux.git
synced 2026-09-12 04:23:03 +02:00
ntfs: compute bi_sector in 512-byte units
bi_sector counts in 512 byte sectors and not in multiples of the
volume's sector size. Under "normal" circumstances (with 512 byte
sectors in NTFS) the current code works as is; however, when we have
a 4k sector size on the volume the current usage of NTFS_B_TO_SECTOR()
and ntfs_bytes_to_sector() end up converting to the number of 4k
sectors after mount.
Reads work today on 4k volumes as bdev-io.c as performing the shift
correctly inline. With writes, we end up with significant silent disk
corruption on these volumes.
This fixes changes to use the new ntfs_bytes_to_bio_sector() function
everywhere we're performing this calculation (including the existing
read path). For the change in inode.c it removes a dead code block
rather than updating.
Fixes: 4079605199 ("ntfs: update in-memory, on-disk structures and headers")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Dennis Tighe <dennis.tighe@gmail.com>
Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit is contained in:
parent
323751a604
commit
6faa235a64
|
|
@ -34,7 +34,7 @@ int ntfs_bdev_read(struct block_device *bdev, char *data, loff_t start, size_t s
|
|||
int error;
|
||||
struct bio *bio;
|
||||
blk_opf_t op;
|
||||
sector_t sector = start >> SECTOR_SHIFT;
|
||||
sector_t sector = ntfs_bytes_to_bio_sector(start);
|
||||
|
||||
if (start & (SECTOR_SIZE - 1))
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -1414,7 +1414,7 @@ static int ntfs_write_cb(struct ntfs_inode *ni, loff_t pos, struct page **pages,
|
|||
bio_pos = ntfs_cluster_to_bytes(vol, bio_lcn);
|
||||
bio = bio_alloc(vol->sb->s_bdev, DIV_ROUND_UP(bio_size, PAGE_SIZE),
|
||||
REQ_OP_WRITE, GFP_NOIO);
|
||||
bio->bi_iter.bi_sector = ntfs_bytes_to_sector(vol, bio_pos);
|
||||
bio->bi_iter.bi_sector = ntfs_bytes_to_bio_sector(bio_pos);
|
||||
|
||||
for (i = 0; bio_size; i++) {
|
||||
unsigned int len = min_t(unsigned int, bio_size, PAGE_SIZE);
|
||||
|
|
|
|||
|
|
@ -1852,7 +1852,7 @@ int ntfs_read_inode_mount(struct inode *vi)
|
|||
struct mft_record *m = NULL;
|
||||
struct attr_record *a;
|
||||
struct ntfs_attr_search_ctx *ctx;
|
||||
unsigned int i, nr_blocks;
|
||||
unsigned int i;
|
||||
int err;
|
||||
size_t new_rl_count;
|
||||
|
||||
|
|
@ -1896,11 +1896,6 @@ int ntfs_read_inode_mount(struct inode *vi)
|
|||
goto err_out;
|
||||
}
|
||||
|
||||
/* Determine the first block of the $MFT/$DATA attribute. */
|
||||
nr_blocks = ntfs_bytes_to_sector(vol, vol->mft_record_size);
|
||||
if (!nr_blocks)
|
||||
nr_blocks = 1;
|
||||
|
||||
/* Load $MFT/$DATA's first mft record. */
|
||||
err = ntfs_bdev_read(sb->s_bdev, (char *)m,
|
||||
ntfs_cluster_to_bytes(vol, vol->mft_lcn), i);
|
||||
|
|
@ -3780,8 +3775,7 @@ static s64 __ntfs_inode_non_resident_attr_pwrite(struct inode *vi,
|
|||
bio = bio_alloc(vol->sb->s_bdev, 1, REQ_OP_WRITE,
|
||||
GFP_NOIO);
|
||||
bio->bi_iter.bi_sector =
|
||||
ntfs_bytes_to_sector(vol,
|
||||
ntfs_cluster_to_bytes(vol, lcn) +
|
||||
ntfs_bytes_to_bio_sector(ntfs_cluster_to_bytes(vol, lcn) +
|
||||
lcn_folio_off);
|
||||
|
||||
length = min_t(unsigned long,
|
||||
|
|
|
|||
|
|
@ -499,8 +499,8 @@ int ntfs_sync_mft_mirror(struct ntfs_volume *vol, const u64 mft_no,
|
|||
|
||||
bio = bio_alloc(vol->sb->s_bdev, 1, REQ_OP_WRITE, GFP_NOIO);
|
||||
bio->bi_iter.bi_sector =
|
||||
NTFS_B_TO_SECTOR(vol, NTFS_CLU_TO_B(vol, vol->mftmirr_lcn) +
|
||||
lcn_folio_off + folio_ofs);
|
||||
ntfs_bytes_to_bio_sector(NTFS_CLU_TO_B(vol, vol->mftmirr_lcn) +
|
||||
lcn_folio_off + folio_ofs);
|
||||
|
||||
if (bio_add_folio(bio, folio, vol->mft_record_size, folio_ofs))
|
||||
err = submit_bio_wait(bio);
|
||||
|
|
@ -592,8 +592,8 @@ int write_mft_record_nolock(struct ntfs_inode *ni, struct mft_record *m, int syn
|
|||
|
||||
bio = bio_alloc(vol->sb->s_bdev, 1, REQ_OP_WRITE, GFP_NOIO);
|
||||
bio->bi_iter.bi_sector =
|
||||
NTFS_B_TO_SECTOR(vol, NTFS_CLU_TO_B(vol, ni->mft_lcn[i]) +
|
||||
clu_off);
|
||||
ntfs_bytes_to_bio_sector(NTFS_CLU_TO_B(vol, ni->mft_lcn[i]) +
|
||||
clu_off);
|
||||
|
||||
if (!bio_add_folio(bio, folio, folio_size,
|
||||
ni->folio_ofs + offset)) {
|
||||
|
|
@ -2742,8 +2742,8 @@ static int ntfs_write_mft_block(struct folio *folio, struct writeback_control *w
|
|||
bio = bio_alloc(vol->sb->s_bdev, 1, REQ_OP_WRITE,
|
||||
GFP_NOIO);
|
||||
bio->bi_iter.bi_sector =
|
||||
ntfs_bytes_to_sector(vol,
|
||||
ntfs_cluster_to_bytes(vol, lcn) + off);
|
||||
ntfs_bytes_to_bio_sector(
|
||||
ntfs_cluster_to_bytes(vol, lcn) + off);
|
||||
}
|
||||
|
||||
if (vol->cluster_size == NTFS_BLOCK_SIZE &&
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/nls.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/blk_types.h>
|
||||
#include <linux/uidgid.h>
|
||||
|
||||
#include "volume.h"
|
||||
|
|
@ -71,8 +72,6 @@
|
|||
#define NTFS_CLU_TO_POFS(vol, clu) (((u64)(clu) << (vol)->cluster_size_bits) & \
|
||||
~PAGE_MASK)
|
||||
|
||||
#define NTFS_B_TO_SECTOR(vol, b) ((b) >> ((vol)->sb)->s_blocksize_bits)
|
||||
|
||||
enum {
|
||||
NTFS_BLOCK_SIZE = 512,
|
||||
NTFS_BLOCK_SIZE_BITS = 9,
|
||||
|
|
@ -154,11 +153,10 @@ static inline u64 ntfs_cluster_to_poff(const struct ntfs_volume *vol,
|
|||
return (clu << vol->cluster_size_bits) & ~PAGE_MASK;
|
||||
}
|
||||
|
||||
/* Convert byte offset to sector (block) number. */
|
||||
static inline sector_t ntfs_bytes_to_sector(const struct ntfs_volume *vol,
|
||||
u64 bytes)
|
||||
/* Convert a byte offset on the volume to a bio sector number. */
|
||||
static inline sector_t ntfs_bytes_to_bio_sector(u64 bytes)
|
||||
{
|
||||
return bytes >> vol->sb->s_blocksize_bits;
|
||||
return bytes >> SECTOR_SHIFT;
|
||||
}
|
||||
|
||||
/* Global variables. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user