diff options
| author | Anton Altaparmakov <aia21@cantab.net> | 2005-06-25 12:15:36 -0400 |
|---|---|---|
| committer | Anton Altaparmakov <aia21@cantab.net> | 2005-06-25 12:15:36 -0400 |
| commit | fa3be92317c4ae34edcf5274e8bbeff181e20b7a (patch) | |
| tree | 84ae4ace6c891aa95b804950283e1f8f3e46c730 | |
| parent | 1d58b27b8d77ecb816cfa8f846b78c845675eb89 (diff) | |
NTFS: Add an extra parameter @last_vcn to ntfs_get_size_for_mapping_pairs()
and ntfs_mapping_pairs_build() to allow the runlist encoding to be
partial which is desirable when filling holes in sparse attributes.
Update all callers.
Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
| -rw-r--r-- | fs/ntfs/ChangeLog | 4 | ||||
| -rw-r--r-- | fs/ntfs/attrib.c | 4 | ||||
| -rw-r--r-- | fs/ntfs/mft.c | 12 | ||||
| -rw-r--r-- | fs/ntfs/runlist.c | 167 | ||||
| -rw-r--r-- | fs/ntfs/runlist.h | 5 |
5 files changed, 132 insertions, 60 deletions
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index aff749db314c..67994c9c248f 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog | |||
| @@ -135,6 +135,10 @@ ToDo/Notes: | |||
| 135 | - Change the runlist terminator of the newly allocated cluster(s) to | 135 | - Change the runlist terminator of the newly allocated cluster(s) to |
| 136 | LCN_ENOENT in ntfs_attr_make_non_resident(). Otherwise the runlist | 136 | LCN_ENOENT in ntfs_attr_make_non_resident(). Otherwise the runlist |
| 137 | code gets confused. | 137 | code gets confused. |
| 138 | - Add an extra parameter @last_vcn to ntfs_get_size_for_mapping_pairs() | ||
| 139 | and ntfs_mapping_pairs_build() to allow the runlist encoding to be | ||
| 140 | partial which is desirable when filling holes in sparse attributes. | ||
| 141 | Update all callers. | ||
| 138 | 142 | ||
| 139 | 2.1.22 - Many bug and race fixes and error handling improvements. | 143 | 2.1.22 - Many bug and race fixes and error handling improvements. |
| 140 | 144 | ||
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 34ea405b883d..c6b2bb64d651 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c | |||
| @@ -1317,7 +1317,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni) | |||
| 1317 | page = NULL; | 1317 | page = NULL; |
| 1318 | } | 1318 | } |
| 1319 | /* Determine the size of the mapping pairs array. */ | 1319 | /* Determine the size of the mapping pairs array. */ |
| 1320 | mp_size = ntfs_get_size_for_mapping_pairs(vol, rl, 0); | 1320 | mp_size = ntfs_get_size_for_mapping_pairs(vol, rl, 0, -1); |
| 1321 | if (unlikely(mp_size < 0)) { | 1321 | if (unlikely(mp_size < 0)) { |
| 1322 | err = mp_size; | 1322 | err = mp_size; |
| 1323 | ntfs_debug("Failed to get size for mapping pairs array, error " | 1323 | ntfs_debug("Failed to get size for mapping pairs array, error " |
| @@ -1416,7 +1416,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni) | |||
| 1416 | cpu_to_sle64(attr_size); | 1416 | cpu_to_sle64(attr_size); |
| 1417 | /* Generate the mapping pairs array into the attribute record. */ | 1417 | /* Generate the mapping pairs array into the attribute record. */ |
| 1418 | err = ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs, | 1418 | err = ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs, |
| 1419 | arec_size - mp_ofs, rl, 0, NULL); | 1419 | arec_size - mp_ofs, rl, 0, -1, NULL); |
| 1420 | if (unlikely(err)) { | 1420 | if (unlikely(err)) { |
| 1421 | ntfs_debug("Failed to build mapping pairs, error code %i.", | 1421 | ntfs_debug("Failed to build mapping pairs, error code %i.", |
| 1422 | err); | 1422 | err); |
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c index 61ce09f1b652..3d0ba8e60adc 100644 --- a/fs/ntfs/mft.c +++ b/fs/ntfs/mft.c | |||
| @@ -1407,7 +1407,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) | |||
| 1407 | BUG_ON(ll < rl2->vcn); | 1407 | BUG_ON(ll < rl2->vcn); |
| 1408 | BUG_ON(ll >= rl2->vcn + rl2->length); | 1408 | BUG_ON(ll >= rl2->vcn + rl2->length); |
| 1409 | /* Get the size for the new mapping pairs array for this extent. */ | 1409 | /* Get the size for the new mapping pairs array for this extent. */ |
| 1410 | mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll); | 1410 | mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1); |
| 1411 | if (unlikely(mp_size <= 0)) { | 1411 | if (unlikely(mp_size <= 0)) { |
| 1412 | ntfs_error(vol->sb, "Get size for mapping pairs failed for " | 1412 | ntfs_error(vol->sb, "Get size for mapping pairs failed for " |
| 1413 | "mft bitmap attribute extent."); | 1413 | "mft bitmap attribute extent."); |
| @@ -1441,7 +1441,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) | |||
| 1441 | /* Generate the mapping pairs array directly into the attr record. */ | 1441 | /* Generate the mapping pairs array directly into the attr record. */ |
| 1442 | ret = ntfs_mapping_pairs_build(vol, (u8*)a + | 1442 | ret = ntfs_mapping_pairs_build(vol, (u8*)a + |
| 1443 | le16_to_cpu(a->data.non_resident.mapping_pairs_offset), | 1443 | le16_to_cpu(a->data.non_resident.mapping_pairs_offset), |
| 1444 | mp_size, rl2, ll, NULL); | 1444 | mp_size, rl2, ll, -1, NULL); |
| 1445 | if (unlikely(ret)) { | 1445 | if (unlikely(ret)) { |
| 1446 | ntfs_error(vol->sb, "Failed to build mapping pairs array for " | 1446 | ntfs_error(vol->sb, "Failed to build mapping pairs array for " |
| 1447 | "mft bitmap attribute."); | 1447 | "mft bitmap attribute."); |
| @@ -1529,7 +1529,7 @@ undo_alloc: | |||
| 1529 | a->data.non_resident.mapping_pairs_offset), | 1529 | a->data.non_resident.mapping_pairs_offset), |
| 1530 | old_alen - le16_to_cpu( | 1530 | old_alen - le16_to_cpu( |
| 1531 | a->data.non_resident.mapping_pairs_offset), | 1531 | a->data.non_resident.mapping_pairs_offset), |
| 1532 | rl2, ll, NULL)) { | 1532 | rl2, ll, -1, NULL)) { |
| 1533 | ntfs_error(vol->sb, "Failed to restore mapping pairs " | 1533 | ntfs_error(vol->sb, "Failed to restore mapping pairs " |
| 1534 | "array.%s", es); | 1534 | "array.%s", es); |
| 1535 | NVolSetErrors(vol); | 1535 | NVolSetErrors(vol); |
| @@ -1838,7 +1838,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) | |||
| 1838 | BUG_ON(ll < rl2->vcn); | 1838 | BUG_ON(ll < rl2->vcn); |
| 1839 | BUG_ON(ll >= rl2->vcn + rl2->length); | 1839 | BUG_ON(ll >= rl2->vcn + rl2->length); |
| 1840 | /* Get the size for the new mapping pairs array for this extent. */ | 1840 | /* Get the size for the new mapping pairs array for this extent. */ |
| 1841 | mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll); | 1841 | mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1); |
| 1842 | if (unlikely(mp_size <= 0)) { | 1842 | if (unlikely(mp_size <= 0)) { |
| 1843 | ntfs_error(vol->sb, "Get size for mapping pairs failed for " | 1843 | ntfs_error(vol->sb, "Get size for mapping pairs failed for " |
| 1844 | "mft data attribute extent."); | 1844 | "mft data attribute extent."); |
| @@ -1877,7 +1877,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) | |||
| 1877 | /* Generate the mapping pairs array directly into the attr record. */ | 1877 | /* Generate the mapping pairs array directly into the attr record. */ |
| 1878 | ret = ntfs_mapping_pairs_build(vol, (u8*)a + | 1878 | ret = ntfs_mapping_pairs_build(vol, (u8*)a + |
| 1879 | le16_to_cpu(a->data.non_resident.mapping_pairs_offset), | 1879 | le16_to_cpu(a->data.non_resident.mapping_pairs_offset), |
| 1880 | mp_size, rl2, ll, NULL); | 1880 | mp_size, rl2, ll, -1, NULL); |
| 1881 | if (unlikely(ret)) { | 1881 | if (unlikely(ret)) { |
| 1882 | ntfs_error(vol->sb, "Failed to build mapping pairs array of " | 1882 | ntfs_error(vol->sb, "Failed to build mapping pairs array of " |
| 1883 | "mft data attribute."); | 1883 | "mft data attribute."); |
| @@ -1959,7 +1959,7 @@ undo_alloc: | |||
| 1959 | a->data.non_resident.mapping_pairs_offset), | 1959 | a->data.non_resident.mapping_pairs_offset), |
| 1960 | old_alen - le16_to_cpu( | 1960 | old_alen - le16_to_cpu( |
| 1961 | a->data.non_resident.mapping_pairs_offset), | 1961 | a->data.non_resident.mapping_pairs_offset), |
| 1962 | rl2, ll, NULL)) { | 1962 | rl2, ll, -1, NULL)) { |
| 1963 | ntfs_error(vol->sb, "Failed to restore mapping pairs " | 1963 | ntfs_error(vol->sb, "Failed to restore mapping pairs " |
| 1964 | "array.%s", es); | 1964 | "array.%s", es); |
| 1965 | NVolSetErrors(vol); | 1965 | NVolSetErrors(vol); |
diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c index 396d767c2cab..758855b0414e 100644 --- a/fs/ntfs/runlist.c +++ b/fs/ntfs/runlist.c | |||
| @@ -1048,10 +1048,17 @@ static inline int ntfs_get_nr_significant_bytes(const s64 n) | |||
| 1048 | * ntfs_get_size_for_mapping_pairs - get bytes needed for mapping pairs array | 1048 | * ntfs_get_size_for_mapping_pairs - get bytes needed for mapping pairs array |
| 1049 | * @vol: ntfs volume (needed for the ntfs version) | 1049 | * @vol: ntfs volume (needed for the ntfs version) |
| 1050 | * @rl: locked runlist to determine the size of the mapping pairs of | 1050 | * @rl: locked runlist to determine the size of the mapping pairs of |
| 1051 | * @start_vcn: vcn at which to start the mapping pairs array | 1051 | * @first_vcn: first vcn which to include in the mapping pairs array |
| 1052 | * @last_vcn: last vcn which to include in the mapping pairs array | ||
| 1052 | * | 1053 | * |
| 1053 | * Walk the locked runlist @rl and calculate the size in bytes of the mapping | 1054 | * Walk the locked runlist @rl and calculate the size in bytes of the mapping |
| 1054 | * pairs array corresponding to the runlist @rl, starting at vcn @start_vcn. | 1055 | * pairs array corresponding to the runlist @rl, starting at vcn @first_vcn and |
| 1056 | * finishing with vcn @last_vcn. | ||
| 1057 | * | ||
| 1058 | * A @last_vcn of -1 means end of runlist and in that case the size of the | ||
| 1059 | * mapping pairs array corresponding to the runlist starting at vcn @first_vcn | ||
| 1060 | * and finishing at the end of the runlist is determined. | ||
| 1061 | * | ||
| 1055 | * This for example allows us to allocate a buffer of the right size when | 1062 | * This for example allows us to allocate a buffer of the right size when |
| 1056 | * building the mapping pairs array. | 1063 | * building the mapping pairs array. |
| 1057 | * | 1064 | * |
| @@ -1067,34 +1074,50 @@ static inline int ntfs_get_nr_significant_bytes(const s64 n) | |||
| 1067 | * remains locked throughout, and is left locked upon return. | 1074 | * remains locked throughout, and is left locked upon return. |
| 1068 | */ | 1075 | */ |
| 1069 | int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol, | 1076 | int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol, |
| 1070 | const runlist_element *rl, const VCN start_vcn) | 1077 | const runlist_element *rl, const VCN first_vcn, |
| 1078 | const VCN last_vcn) | ||
| 1071 | { | 1079 | { |
| 1072 | LCN prev_lcn; | 1080 | LCN prev_lcn; |
| 1073 | int rls; | 1081 | int rls; |
| 1082 | BOOL the_end = FALSE; | ||
| 1074 | 1083 | ||
| 1075 | BUG_ON(start_vcn < 0); | 1084 | BUG_ON(first_vcn < 0); |
| 1085 | BUG_ON(last_vcn < -1); | ||
| 1086 | BUG_ON(last_vcn >= 0 && first_vcn > last_vcn); | ||
| 1076 | if (!rl) { | 1087 | if (!rl) { |
| 1077 | BUG_ON(start_vcn); | 1088 | BUG_ON(first_vcn); |
| 1089 | BUG_ON(last_vcn > 0); | ||
| 1078 | return 1; | 1090 | return 1; |
| 1079 | } | 1091 | } |
| 1080 | /* Skip to runlist element containing @start_vcn. */ | 1092 | /* Skip to runlist element containing @first_vcn. */ |
| 1081 | while (rl->length && start_vcn >= rl[1].vcn) | 1093 | while (rl->length && first_vcn >= rl[1].vcn) |
| 1082 | rl++; | 1094 | rl++; |
| 1083 | if ((!rl->length && start_vcn > rl->vcn) || start_vcn < rl->vcn) | 1095 | if (unlikely((!rl->length && first_vcn > rl->vcn) || |
| 1096 | first_vcn < rl->vcn)) | ||
| 1084 | return -EINVAL; | 1097 | return -EINVAL; |
| 1085 | prev_lcn = 0; | 1098 | prev_lcn = 0; |
| 1086 | /* Always need the termining zero byte. */ | 1099 | /* Always need the termining zero byte. */ |
| 1087 | rls = 1; | 1100 | rls = 1; |
| 1088 | /* Do the first partial run if present. */ | 1101 | /* Do the first partial run if present. */ |
| 1089 | if (start_vcn > rl->vcn) { | 1102 | if (first_vcn > rl->vcn) { |
| 1090 | s64 delta; | 1103 | s64 delta, length = rl->length; |
| 1091 | 1104 | ||
| 1092 | /* We know rl->length != 0 already. */ | ||
