diff options
-rw-r--r-- | fs/ntfs/ChangeLog | 3 | ||||
-rw-r--r-- | fs/ntfs/runlist.c | 56 |
2 files changed, 37 insertions, 22 deletions
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 3f78fff45448..b40c334e616f 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog | |||
@@ -60,6 +60,9 @@ ToDo/Notes: | |||
60 | enable bit which is set appropriately and a per inode sparse disable | 60 | enable bit which is set appropriately and a per inode sparse disable |
61 | bit which is preset on some system file inodes as appropriate. | 61 | bit which is preset on some system file inodes as appropriate. |
62 | - Enforce that sparse support is disabled on NTFS volumes pre 3.0. | 62 | - Enforce that sparse support is disabled on NTFS volumes pre 3.0. |
63 | - Fix a bug in fs/ntfs/runlist.c::ntfs_mapping_pairs_decompress() in | ||
64 | the creation of the unmapped runlist element for the base attribute | ||
65 | extent. | ||
63 | 66 | ||
64 | 2.1.22 - Many bug and race fixes and error handling improvements. | 67 | 2.1.22 - Many bug and race fixes and error handling improvements. |
65 | 68 | ||
diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c index 8438fb1da219..5244687dfaa8 100644 --- a/fs/ntfs/runlist.c +++ b/fs/ntfs/runlist.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /** | 1 | /** |
2 | * runlist.c - NTFS runlist handling code. Part of the Linux-NTFS project. | 2 | * runlist.c - NTFS runlist handling code. Part of the Linux-NTFS project. |
3 | * | 3 | * |
4 | * Copyright (c) 2001-2004 Anton Altaparmakov | 4 | * Copyright (c) 2001-2005 Anton Altaparmakov |
5 | * Copyright (c) 2002 Richard Russon | 5 | * Copyright (c) 2002 Richard Russon |
6 | * | 6 | * |
7 | * This program/include file is free software; you can redistribute it and/or | 7 | * 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, | |||
59 | * | 59 | * |
60 | * As the runlists grow, more memory will be required. To prevent the | 60 | * As the runlists grow, more memory will be required. To prevent the |
61 | * kernel having to allocate and reallocate large numbers of small bits of | 61 | * kernel having to allocate and reallocate large numbers of small bits of |
62 | * memory, this function returns and entire page of memory. | 62 | * memory, this function returns an entire page of memory. |
63 | * | 63 | * |
64 | * It is up to the caller to serialize access to the runlist @rl. | 64 | * It is up to the caller to serialize access to the runlist @rl. |
65 | * | 65 | * |
@@ -855,30 +855,42 @@ mpa_err: | |||
855 | if (!attr->data.non_resident.lowest_vcn) { | 855 | if (!attr->data.non_resident.lowest_vcn) { |
856 | VCN max_cluster; | 856 | VCN max_cluster; |
857 | 857 | ||
858 | max_cluster = (sle64_to_cpu( | 858 | max_cluster = ((sle64_to_cpu( |
859 | attr->data.non_resident.allocated_size) + | 859 | attr->data.non_resident.allocated_size) + |
860 | vol->cluster_size - 1) >> | 860 | vol->cluster_size - 1) >> |
861 | vol->cluster_size_bits; | 861 | vol->cluster_size_bits) - 1; |
862 | /* | 862 | /* |
863 | * If there is a difference between the highest_vcn and the | 863 | * A highest_vcn of zero means this is a single extent |
864 | * highest cluster, the runlist is either corrupt or, more | 864 | * attribute so simply terminate the runlist with LCN_ENOENT). |
865 | * likely, there are more extents following this one. | ||
866 | */ | 865 | */ |
867 | if (deltaxcn < --max_cluster) { | 866 | if (deltaxcn) { |
868 | ntfs_debug("More extents to follow; deltaxcn = 0x%llx, " | 867 | /* |
869 | "max_cluster = 0x%llx", | 868 | * If there is a difference between the highest_vcn and |
870 | (unsigned long long)deltaxcn, | 869 | * the highest cluster, the runlist is either corrupt |
871 | (unsigned long long)max_cluster); | 870 | * or, more likely, there are more extents following |
872 | rl[rlpos].vcn = vcn; | 871 | * this one. |
873 | vcn += rl[rlpos].length = max_cluster - deltaxcn; | 872 | */ |
874 | rl[rlpos].lcn = LCN_RL_NOT_MAPPED; | 873 | if (deltaxcn < max_cluster) { |
875 | rlpos++; | 874 | ntfs_debug("More extents to follow; deltaxcn " |
876 | } else if (unlikely(deltaxcn > max_cluster)) { | 875 | "= 0x%llx, max_cluster = " |
877 | ntfs_error(vol->sb, "Corrupt attribute. deltaxcn = " | 876 | "0x%llx", |
878 | "0x%llx, max_cluster = 0x%llx", | 877 | (unsigned long long)deltaxcn, |
879 | (unsigned long long)deltaxcn, | 878 | (unsigned long long) |
880 | (unsigned long long)max_cluster); | 879 | max_cluster); |
881 | goto mpa_err; | 880 | rl[rlpos].vcn = vcn; |
881 | vcn += rl[rlpos].length = max_cluster - | ||
882 | deltaxcn; | ||
883 | rl[rlpos].lcn = LCN_RL_NOT_MAPPED; | ||
884 | rlpos++; | ||
885 | } else if (unlikely(deltaxcn > max_cluster)) { | ||
886 | ntfs_error(vol->sb, "Corrupt attribute. " | ||
887 | "deltaxcn = 0x%llx, " | ||
888 | "max_cluster = 0x%llx", | ||
889 | (unsigned long long)deltaxcn, | ||
890 | (unsigned long long) | ||
891 | max_cluster); | ||
892 | goto mpa_err; | ||
893 | } | ||
882 | } | 894 | } |
883 | rl[rlpos].lcn = LCN_ENOENT; | 895 | rl[rlpos].lcn = LCN_ENOENT; |
884 | } else /* Not the base extent. There may be more extents to follow. */ | 896 | } else /* Not the base extent. There may be more extents to follow. */ |