NTFS: Fix a bug in fs/ntfs/runlist.c::ntfs_mapping_pairs_decompress() in

the creation of the unmapped runlist element for the base attribute
      extent.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
This commit is contained in:
Anton Altaparmakov 2005-02-03 12:04:36 +00:00
parent c002f42543
commit 1a0df15acd
2 changed files with 37 additions and 22 deletions

View file

@ -60,6 +60,9 @@ ToDo/Notes:
enable bit which is set appropriately and a per inode sparse disable
bit which is preset on some system file inodes as appropriate.
- Enforce that sparse support is disabled on NTFS volumes pre 3.0.
- Fix a bug in fs/ntfs/runlist.c::ntfs_mapping_pairs_decompress() in
the creation of the unmapped runlist element for the base attribute
extent.
2.1.22 - Many bug and race fixes and error handling improvements.

View file

@ -1,7 +1,7 @@
/**
* runlist.c - NTFS runlist handling code. Part of the Linux-NTFS project.
*
* Copyright (c) 2001-2004 Anton Altaparmakov
* Copyright (c) 2001-2005 Anton Altaparmakov
* Copyright (c) 2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
@ -59,7 +59,7 @@ static inline void ntfs_rl_mc(runlist_element *dstbase, int dst,
*
* As the runlists grow, more memory will be required. To prevent the
* kernel having to allocate and reallocate large numbers of small bits of
* memory, this function returns and entire page of memory.
* memory, this function returns an entire page of memory.
*
* It is up to the caller to serialize access to the runlist @rl.
*
@ -855,30 +855,42 @@ runlist_element *ntfs_mapping_pairs_decompress(const ntfs_volume *vol,
if (!attr->data.non_resident.lowest_vcn) {
VCN max_cluster;
max_cluster = (sle64_to_cpu(
max_cluster = ((sle64_to_cpu(
attr->data.non_resident.allocated_size) +
vol->cluster_size - 1) >>
vol->cluster_size_bits;
vol->cluster_size_bits) - 1;
/*
* If there is a difference between the highest_vcn and the
* highest cluster, the runlist is either corrupt or, more
* likely, there are more extents following this one.
* A highest_vcn of zero means this is a single extent
* attribute so simply terminate the runlist with LCN_ENOENT).
*/
if (deltaxcn < --max_cluster) {
ntfs_debug("More extents to follow; deltaxcn = 0x%llx, "
"max_cluster = 0x%llx",
(unsigned long long)deltaxcn,
(unsigned long long)max_cluster);
rl[rlpos].vcn = vcn;
vcn += rl[rlpos].length = max_cluster - deltaxcn;
rl[rlpos].lcn = LCN_RL_NOT_MAPPED;
rlpos++;
} else if (unlikely(deltaxcn > max_cluster)) {
ntfs_error(vol->sb, "Corrupt attribute. deltaxcn = "
"0x%llx, max_cluster = 0x%llx",
(unsigned long long)deltaxcn,
(unsigned long long)max_cluster);
goto mpa_err;
if (deltaxcn) {
/*
* If there is a difference between the highest_vcn and
* the highest cluster, the runlist is either corrupt
* or, more likely, there are more extents following
* this one.
*/
if (deltaxcn < max_cluster) {
ntfs_debug("More extents to follow; deltaxcn "
"= 0x%llx, max_cluster = "
"0x%llx",
(unsigned long long)deltaxcn,
(unsigned long long)
max_cluster);
rl[rlpos].vcn = vcn;
vcn += rl[rlpos].length = max_cluster -
deltaxcn;
rl[rlpos].lcn = LCN_RL_NOT_MAPPED;
rlpos++;
} else if (unlikely(deltaxcn > max_cluster)) {
ntfs_error(vol->sb, "Corrupt attribute. "
"deltaxcn = 0x%llx, "
"max_cluster = 0x%llx",
(unsigned long long)deltaxcn,
(unsigned long long)
max_cluster);
goto mpa_err;
}
}
rl[rlpos].lcn = LCN_ENOENT;
} else /* Not the base extent. There may be more extents to follow. */