mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
ntfs: update mft operations
Refactors MFT record handling to use folio APIs with consistency validation, and improving allocation extension and writeback paths for and . Acked-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit is contained in:
2483
fs/ntfs/mft.c
2483
fs/ntfs/mft.c
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,15 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* mst.c - NTFS multi sector transfer protection handling code. Part of the
|
||||
* Linux-NTFS project.
|
||||
* NTFS multi sector transfer protection handling code.
|
||||
*
|
||||
* Copyright (c) 2001-2004 Anton Altaparmakov
|
||||
*/
|
||||
|
||||
#include <linux/ratelimit.h>
|
||||
|
||||
#include "ntfs.h"
|
||||
|
||||
/**
|
||||
/*
|
||||
* post_read_mst_fixup - deprotect multi sector transfer protected data
|
||||
* @b: pointer to the data to deprotect
|
||||
* @size: size in bytes of @b
|
||||
@@ -25,7 +26,7 @@
|
||||
* be fixed up. Thus, we return success and not failure in this case. This is
|
||||
* in contrast to pre_write_mst_fixup(), see below.
|
||||
*/
|
||||
int post_read_mst_fixup(NTFS_RECORD *b, const u32 size)
|
||||
int post_read_mst_fixup(struct ntfs_record *b, const u32 size)
|
||||
{
|
||||
u16 usa_ofs, usa_count, usn;
|
||||
u16 *usa_pos, *data_pos;
|
||||
@@ -35,13 +36,12 @@ int post_read_mst_fixup(NTFS_RECORD *b, const u32 size)
|
||||
/* Decrement usa_count to get number of fixups. */
|
||||
usa_count = le16_to_cpu(b->usa_count) - 1;
|
||||
/* Size and alignment checks. */
|
||||
if ( size & (NTFS_BLOCK_SIZE - 1) ||
|
||||
usa_ofs & 1 ||
|
||||
usa_ofs + (usa_count * 2) > size ||
|
||||
(size >> NTFS_BLOCK_SIZE_BITS) != usa_count)
|
||||
if (size & (NTFS_BLOCK_SIZE - 1) || usa_ofs & 1 ||
|
||||
usa_ofs + (usa_count * 2) > size ||
|
||||
(size >> NTFS_BLOCK_SIZE_BITS) != usa_count)
|
||||
return 0;
|
||||
/* Position of usn in update sequence array. */
|
||||
usa_pos = (u16*)b + usa_ofs/sizeof(u16);
|
||||
usa_pos = (u16 *)b + usa_ofs/sizeof(u16);
|
||||
/*
|
||||
* The update sequence number which has to be equal to each of the
|
||||
* u16 values before they are fixed up. Note no need to care for
|
||||
@@ -53,12 +53,18 @@ int post_read_mst_fixup(NTFS_RECORD *b, const u32 size)
|
||||
/*
|
||||
* Position in protected data of first u16 that needs fixing up.
|
||||
*/
|
||||
data_pos = (u16*)b + NTFS_BLOCK_SIZE/sizeof(u16) - 1;
|
||||
data_pos = (u16 *)b + NTFS_BLOCK_SIZE / sizeof(u16) - 1;
|
||||
/*
|
||||
* Check for incomplete multi sector transfer(s).
|
||||
*/
|
||||
while (usa_count--) {
|
||||
if (*data_pos != usn) {
|
||||
struct mft_record *m = (struct mft_record *)b;
|
||||
|
||||
pr_err_ratelimited("ntfs: Incomplete multi sector transfer detected! (Record magic : 0x%x, mft number : 0x%x, base mft number : 0x%lx, mft in use : %d, data : 0x%x, usn 0x%x)\n",
|
||||
le32_to_cpu(m->magic), le32_to_cpu(m->mft_record_number),
|
||||
MREF_LE(m->base_mft_record), m->flags & MFT_RECORD_IN_USE,
|
||||
*data_pos, usn);
|
||||
/*
|
||||
* Incomplete multi sector transfer detected! )-:
|
||||
* Set the magic to "BAAD" and return failure.
|
||||
@@ -67,11 +73,11 @@ int post_read_mst_fixup(NTFS_RECORD *b, const u32 size)
|
||||
b->magic = magic_BAAD;
|
||||
return -EINVAL;
|
||||
}
|
||||
data_pos += NTFS_BLOCK_SIZE/sizeof(u16);
|
||||
data_pos += NTFS_BLOCK_SIZE / sizeof(u16);
|
||||
}
|
||||
/* Re-setup the variables. */
|
||||
usa_count = le16_to_cpu(b->usa_count) - 1;
|
||||
data_pos = (u16*)b + NTFS_BLOCK_SIZE/sizeof(u16) - 1;
|
||||
data_pos = (u16 *)b + NTFS_BLOCK_SIZE / sizeof(u16) - 1;
|
||||
/* Fixup all sectors. */
|
||||
while (usa_count--) {
|
||||
/*
|
||||
@@ -85,7 +91,7 @@ int post_read_mst_fixup(NTFS_RECORD *b, const u32 size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* pre_write_mst_fixup - apply multi sector transfer protection
|
||||
* @b: pointer to the data to protect
|
||||
* @size: size in bytes of @b
|
||||
@@ -106,28 +112,27 @@ int post_read_mst_fixup(NTFS_RECORD *b, const u32 size)
|
||||
* otherwise a random word will be used (whatever was in the record at that
|
||||
* position at that time).
|
||||
*/
|
||||
int pre_write_mst_fixup(NTFS_RECORD *b, const u32 size)
|
||||
int pre_write_mst_fixup(struct ntfs_record *b, const u32 size)
|
||||
{
|
||||
le16 *usa_pos, *data_pos;
|
||||
__le16 *usa_pos, *data_pos;
|
||||
u16 usa_ofs, usa_count, usn;
|
||||
le16 le_usn;
|
||||
__le16 le_usn;
|
||||
|
||||
/* Sanity check + only fixup if it makes sense. */
|
||||
if (!b || ntfs_is_baad_record(b->magic) ||
|
||||
ntfs_is_hole_record(b->magic))
|
||||
ntfs_is_hole_record(b->magic))
|
||||
return -EINVAL;
|
||||
/* Setup the variables. */
|
||||
usa_ofs = le16_to_cpu(b->usa_ofs);
|
||||
/* Decrement usa_count to get number of fixups. */
|
||||
usa_count = le16_to_cpu(b->usa_count) - 1;
|
||||
/* Size and alignment checks. */
|
||||
if ( size & (NTFS_BLOCK_SIZE - 1) ||
|
||||
usa_ofs & 1 ||
|
||||
usa_ofs + (usa_count * 2) > size ||
|
||||
(size >> NTFS_BLOCK_SIZE_BITS) != usa_count)
|
||||
if (size & (NTFS_BLOCK_SIZE - 1) || usa_ofs & 1 ||
|
||||
usa_ofs + (usa_count * 2) > size ||
|
||||
(size >> NTFS_BLOCK_SIZE_BITS) != usa_count)
|
||||
return -EINVAL;
|
||||
/* Position of usn in update sequence array. */
|
||||
usa_pos = (le16*)((u8*)b + usa_ofs);
|
||||
usa_pos = (__le16 *)((u8 *)b + usa_ofs);
|
||||
/*
|
||||
* Cyclically increment the update sequence number
|
||||
* (skipping 0 and -1, i.e. 0xffff).
|
||||
@@ -138,7 +143,7 @@ int pre_write_mst_fixup(NTFS_RECORD *b, const u32 size)
|
||||
le_usn = cpu_to_le16(usn);
|
||||
*usa_pos = le_usn;
|
||||
/* Position in data of first u16 that needs fixing up. */
|
||||
data_pos = (le16*)b + NTFS_BLOCK_SIZE/sizeof(le16) - 1;
|
||||
data_pos = (__le16 *)b + NTFS_BLOCK_SIZE/sizeof(__le16) - 1;
|
||||
/* Fixup all sectors. */
|
||||
while (usa_count--) {
|
||||
/*
|
||||
@@ -149,12 +154,12 @@ int pre_write_mst_fixup(NTFS_RECORD *b, const u32 size)
|
||||
/* Apply fixup to data. */
|
||||
*data_pos = le_usn;
|
||||
/* Increment position in data as well. */
|
||||
data_pos += NTFS_BLOCK_SIZE/sizeof(le16);
|
||||
data_pos += NTFS_BLOCK_SIZE / sizeof(__le16);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* post_write_mst_fixup - fast deprotect multi sector transfer protected data
|
||||
* @b: pointer to the data to deprotect
|
||||
*
|
||||
@@ -162,18 +167,18 @@ int pre_write_mst_fixup(NTFS_RECORD *b, const u32 size)
|
||||
* for any errors, because we assume we have just used pre_write_mst_fixup(),
|
||||
* thus the data will be fine or we would never have gotten here.
|
||||
*/
|
||||
void post_write_mst_fixup(NTFS_RECORD *b)
|
||||
void post_write_mst_fixup(struct ntfs_record *b)
|
||||
{
|
||||
le16 *usa_pos, *data_pos;
|
||||
__le16 *usa_pos, *data_pos;
|
||||
|
||||
u16 usa_ofs = le16_to_cpu(b->usa_ofs);
|
||||
u16 usa_count = le16_to_cpu(b->usa_count) - 1;
|
||||
|
||||
/* Position of usn in update sequence array. */
|
||||
usa_pos = (le16*)b + usa_ofs/sizeof(le16);
|
||||
usa_pos = (__le16 *)b + usa_ofs/sizeof(__le16);
|
||||
|
||||
/* Position in protected data of first u16 that needs fixing up. */
|
||||
data_pos = (le16*)b + NTFS_BLOCK_SIZE/sizeof(le16) - 1;
|
||||
data_pos = (__le16 *)b + NTFS_BLOCK_SIZE/sizeof(__le16) - 1;
|
||||
|
||||
/* Fixup all sectors. */
|
||||
while (usa_count--) {
|
||||
@@ -184,6 +189,6 @@ void post_write_mst_fixup(NTFS_RECORD *b)
|
||||
*data_pos = *(++usa_pos);
|
||||
|
||||
/* Increment position in data as well. */
|
||||
data_pos += NTFS_BLOCK_SIZE/sizeof(le16);
|
||||
data_pos += NTFS_BLOCK_SIZE/sizeof(__le16);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user