aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Altaparmakov <aia21@cantab.net>2005-06-25 12:15:36 -0400
committerAnton Altaparmakov <aia21@cantab.net>2005-06-25 12:15:36 -0400
commitfa3be92317c4ae34edcf5274e8bbeff181e20b7a (patch)
tree84ae4ace6c891aa95b804950283e1f8f3e46c730
parent1d58b27b8d77ecb816cfa8f846b78c845675eb89 (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/ChangeLog4
-rw-r--r--fs/ntfs/attrib.c4
-rw-r--r--fs/ntfs/mft.c12
-rw-r--r--fs/ntfs/runlist.c167
-rw-r--r--fs/ntfs/runlist.h5
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
1392.1.22 - Many bug and race fixes and error handling improvements. 1432.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 */
1069int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol, 1076int 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. */