Windows cares only about first 4 records in $MFTMirr and ignores
everything beyond them. Update libntfs behaviour to be like in windows. Leave @mftmirr_size for case if will want to change something in the future.edge.strict_endians
parent
ef66794423
commit
a604622314
|
@ -69,6 +69,9 @@ xx/xx/2006 - x.xx.x - .
|
|||
NTFS_MNT_CASE_SENSITIVE. (Yura)
|
||||
- Treat filenames in POSIX namespace as case insensitive in case of
|
||||
case insensitive mounts. (Anton, Yura)
|
||||
- Windows cares only about first 4 records in $MFTMirr and ignores
|
||||
everything beyond them. Update libntfs behaviour to be like in
|
||||
windows. (Yura)
|
||||
|
||||
21/06/2006 - 1.13.1 - Various fixes.
|
||||
|
||||
|
|
|
@ -261,16 +261,9 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
|
|||
(unsigned)vol->indx_record_size);
|
||||
ntfs_log_debug("INDXRecordSizeBits = %u\n", vol->indx_record_size_bits);
|
||||
/*
|
||||
* Work out the size of the MFT mirror in number of mft records. If the
|
||||
* cluster size is less than or equal to the size taken by four mft
|
||||
* records, the mft mirror stores the first four mft records. If the
|
||||
* cluster size is bigger than the size taken by four mft records, the
|
||||
* mft mirror contains as many mft records as will fit into one
|
||||
* cluster.
|
||||
* Windows cares only about first 4 records in $MFTMirr and inores
|
||||
* everything beyend them.
|
||||
*/
|
||||
if (vol->cluster_size <= 4 * vol->mft_record_size)
|
||||
vol->mftmirr_size = 4;
|
||||
else
|
||||
vol->mftmirr_size = vol->cluster_size / vol->mft_record_size;
|
||||
vol->mftmirr_size = 4;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@ int ntfs_mft_records_write(const ntfs_volume *vol, const MFT_REF mref,
|
|||
if (bw != -1)
|
||||
errno = EIO;
|
||||
if (bw >= 0)
|
||||
ntfs_log_debug("Error: partial write while writing $Mft "
|
||||
ntfs_log_error("Partial write while writing $Mft "
|
||||
"record(s)!\n");
|
||||
else
|
||||
ntfs_log_perror("Error writing $Mft record(s)");
|
||||
|
|
|
@ -340,8 +340,7 @@ error_exit:
|
|||
*/
|
||||
static int ntfs_mftmirr_load(ntfs_volume *vol)
|
||||
{
|
||||
int i;
|
||||
runlist_element rl[2];
|
||||
int err;
|
||||
|
||||
vol->mftmirr_ni = ntfs_inode_open(vol, FILE_MFTMirr);
|
||||
if (!vol->mftmirr_ni) {
|
||||
|
@ -359,36 +358,27 @@ static int ntfs_mftmirr_load(ntfs_volume *vol)
|
|||
ntfs_log_perror("Failed to map runlist of $MFTMirr/$DATA");
|
||||
goto error_exit;
|
||||
}
|
||||
/* Construct the mft mirror runlist. */
|
||||
rl[0].vcn = 0;
|
||||
rl[0].lcn = vol->mftmirr_lcn;
|
||||
rl[0].length = (vol->mftmirr_size * vol->mft_record_size +
|
||||
vol->cluster_size - 1) / vol->cluster_size;
|
||||
rl[1].vcn = rl[0].length;
|
||||
rl[1].lcn = LCN_ENOENT;
|
||||
rl[1].length = 0;
|
||||
/* Compare the two runlists. They must be identical. */
|
||||
i = 0;
|
||||
do {
|
||||
if (rl[i].vcn != vol->mftmirr_na->rl[i].vcn ||
|
||||
rl[i].lcn != vol->mftmirr_na->rl[i].lcn ||
|
||||
rl[i].length != vol->mftmirr_na->rl[i].length) {
|
||||
ntfs_log_debug("Error: $MFTMirr location mismatch! Run "
|
||||
"chkdsk.\n");
|
||||
errno = EIO;
|
||||
goto error_exit;
|
||||
}
|
||||
} while (rl[i++].length);
|
||||
/* Check $MFTMirr runlist. */
|
||||
if (vol->mftmirr_na->rl[0].lcn != vol->mftmirr_lcn ||
|
||||
vol->mftmirr_na->rl[0].length < (vol->mftmirr_size *
|
||||
vol->mft_record_size + vol->cluster_size - 1) /
|
||||
vol->cluster_size) {
|
||||
ntfs_log_error("$MFTMirr location mismatch or first 4 records "
|
||||
"are fragmented. Run chkdsk.\n");
|
||||
errno = EIO;
|
||||
goto error_exit;
|
||||
|
||||
}
|
||||
return 0;
|
||||
error_exit:
|
||||
i = errno;
|
||||
err = errno;
|
||||
if (vol->mftmirr_na) {
|
||||
ntfs_attr_close(vol->mftmirr_na);
|
||||
vol->mftmirr_na = NULL;
|
||||
}
|
||||
ntfs_inode_close(vol->mftmirr_ni);
|
||||
vol->mftmirr_ni = NULL;
|
||||
errno = i;
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue