aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ntfs/runlist.c
diff options
context:
space:
mode:
authorDave Kleikamp <shaggy@austin.ibm.com>2005-07-19 14:46:53 -0400
committerDave Kleikamp <shaggy@austin.ibm.com>2005-07-19 14:46:53 -0400
commit21d1ee8b375bcd180f1d6b8ccbb8d8f938596310 (patch)
tree2e82b65c16a4aaa88eeb7dd9f47f2d1c418e77d0 /fs/ntfs/runlist.c
parent3d9b1cdd2455017c6aa25bc2442092b81438981f (diff)
parentf60f700876cd51de9de69f3a3c865d95e287a24d (diff)
Merge with /home/shaggy/git/linus-clean/
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
Diffstat (limited to 'fs/ntfs/runlist.c')
-rw-r--r--fs/ntfs/runlist.c278
1 files changed, 198 insertions, 80 deletions
diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c
index 8438fb1da219..758855b0414e 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 *
@@ -113,8 +113,11 @@ static inline BOOL ntfs_are_rl_mergeable(runlist_element *dst,
113 BUG_ON(!dst); 113 BUG_ON(!dst);
114 BUG_ON(!src); 114 BUG_ON(!src);
115 115
116 if ((dst->lcn < 0) || (src->lcn < 0)) /* Are we merging holes? */ 116 if ((dst->lcn < 0) || (src->lcn < 0)) { /* Are we merging holes? */
117 if (dst->lcn == LCN_HOLE && src->lcn == LCN_HOLE)
118 return TRUE;
117 return FALSE; 119 return FALSE;
120 }
118 if ((dst->lcn + dst->length) != src->lcn) /* Are the runs contiguous? */ 121 if ((dst->lcn + dst->length) != src->lcn) /* Are the runs contiguous? */
119 return FALSE; 122 return FALSE;
120 if ((dst->vcn + dst->length) != src->vcn) /* Are the runs misaligned? */ 123 if ((dst->vcn + dst->length) != src->vcn) /* Are the runs misaligned? */
@@ -855,30 +858,42 @@ mpa_err:
855 if (!attr->data.non_resident.lowest_vcn) { 858 if (!attr->data.non_resident.lowest_vcn) {
856 VCN max_cluster; 859 VCN max_cluster;
857 860
858 max_cluster = (sle64_to_cpu( 861 max_cluster = ((sle64_to_cpu(
859 attr->data.non_resident.allocated_size) + 862 attr->data.non_resident.allocated_size) +
860 vol->cluster_size - 1) >> 863 vol->cluster_size - 1) >>
861 vol->cluster_size_bits; 864 vol->cluster_size_bits) - 1;
862 /* 865 /*
863 * If there is a difference between the highest_vcn and the 866 * A highest_vcn of zero means this is a single extent
864 * highest cluster, the runlist is either corrupt or, more 867 * attribute so simply terminate the runlist with LCN_ENOENT).
865 * likely, there are more extents following this one.
866 */ 868 */
867 if (deltaxcn < --max_cluster) { 869 if (deltaxcn) {
868 ntfs_debug("More extents to follow; deltaxcn = 0x%llx, " 870 /*
869 "max_cluster = 0x%llx", 871 * If there is a difference between the highest_vcn and
870 (unsigned long long)deltaxcn, 872 * the highest cluster, the runlist is either corrupt
871 (unsigned long long)max_cluster); 873 * or, more likely, there are more extents following
872 rl[rlpos].vcn = vcn; 874 * this one.
873 vcn += rl[rlpos].length = max_cluster - deltaxcn; 875 */
874 rl[rlpos].lcn = LCN_RL_NOT_MAPPED; 876 if (deltaxcn < max_cluster) {
875 rlpos++; 877 ntfs_debug("More extents to follow; deltaxcn "
876 } else if (unlikely(deltaxcn > max_cluster)) { 878 "= 0x%llx, max_cluster = "
877 ntfs_error(vol->sb, "Corrupt attribute. deltaxcn = " 879 "0x%llx",
878 "0x%llx, max_cluster = 0x%llx", 880 (unsigned long long)deltaxcn,
879 (unsigned long long)deltaxcn, 881 (unsigned long long)
880 (unsigned long long)max_cluster); 882 max_cluster);
881 goto mpa_err; 883 rl[rlpos].vcn = vcn;
884 vcn += rl[rlpos].length = max_cluster -
885 deltaxcn;
886 rl[rlpos].lcn = LCN_RL_NOT_MAPPED;
887 rlpos++;
888 } else if (unlikely(deltaxcn > max_cluster)) {
889 ntfs_error(vol->sb, "Corrupt attribute. "
890 "deltaxcn = 0x%llx, "
891 "max_cluster = 0x%llx",
892 (unsigned long long)deltaxcn,
893 (unsigned long long)
894 max_cluster);
895 goto mpa_err;
896 }
882 } 897 }
883 rl[rlpos].lcn = LCN_ENOENT; 898 rl[rlpos].lcn = LCN_ENOENT;
884 } else /* Not the base extent. There may be more extents to follow. */ 899 } else /* Not the base extent. There may be more extents to follow. */
@@ -918,17 +933,18 @@ err_out:
918 * 933 *
919 * It is up to the caller to serialize access to the runlist @rl. 934 * It is up to the caller to serialize access to the runlist @rl.
920 * 935 *
921 * Since lcns must be >= 0, we use negative return values with special meaning: 936 * Since lcns must be >= 0, we use negative return codes with special meaning:
922 * 937 *
923 * Return value Meaning / Description 938 * Return code Meaning / Description
924 * ================================================== 939 * ==================================================
925 * -1 = LCN_HOLE Hole / not allocated on disk. 940 * LCN_HOLE Hole / not allocated on disk.
926 * -2 = LCN_RL_NOT_MAPPED This is part of the runlist which has not been 941 * LCN_RL_NOT_MAPPED This is part of the runlist which has not been
927 * inserted into the runlist yet. 942 * inserted into the runlist yet.
928 * -3 = LCN_ENOENT There is no such vcn in the attribute. 943 * LCN_ENOENT There is no such vcn in the attribute.
929 * 944 *
930 * Locking: - The caller must have locked the runlist (for reading or writing). 945 * Locking: - The caller must have locked the runlist (for reading or writing).
931 * - This function does not touch the lock. 946 * - This function does not touch the lock, nor does it modify the
947 * runlist.
932 */ 948 */
933LCN ntfs_rl_vcn_to_lcn(const runlist_element *rl, const VCN vcn) 949LCN ntfs_rl_vcn_to_lcn(const runlist_element *rl, const VCN vcn)
934{ 950{
@@ -964,6 +980,39 @@ LCN ntfs_rl_vcn_to_lcn(const runlist_element *rl, const VCN vcn)
964 return LCN_ENOENT; 980 return LCN_ENOENT;
965} 981}
966 982
983#ifdef NTFS_RW
984
985/**
986 * ntfs_rl_find_vcn_nolock - find a vcn in a runlist
987 * @rl: runlist to search
988 * @vcn: vcn to find
989 *
990 * Find the virtual cluster number @vcn in the runlist @rl and return the
991 * address of the runlist element containing the @vcn on success.
992 *
993 * Return NULL if @rl is NULL or @vcn is in an unmapped part/out of bounds of
994 * the runlist.
995 *
996 * Locking: The runlist must be locked on entry.
997 */
998runlist_element *ntfs_rl_find_vcn_nolock(runlist_element *rl, const VCN vcn)
999{
1000 BUG_ON(vcn < 0);
1001 if (unlikely(!rl || vcn < rl[0].vcn))
1002 return NULL;
1003 while (likely(rl->length)) {
1004 if (unlikely(vcn < rl[1].vcn)) {
1005 if (likely(rl->lcn >= LCN_HOLE))
1006 return rl;
1007 return NULL;
1008 }
1009 rl++;
1010 }
1011 if (likely(rl->lcn == LCN_ENOENT))
1012 return rl;
1013 return NULL;
1014}
1015
967/** 1016/**
968 * ntfs_get_nr_significant_bytes - get number of bytes needed to store a number 1017 * ntfs_get_nr_significant_bytes - get number of bytes needed to store a number
969 * @n: number for which to get the number of bytes for 1018 * @n: number for which to get the number of bytes for
@@ -999,10 +1048,17 @@ static inline int ntfs_get_nr_significant_bytes(const s64 n)
999 * 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
1000 * @vol: ntfs volume (needed for the ntfs version) 1049 * @vol: ntfs volume (needed for the ntfs version)
1001 * @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
1002 * @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
1003 * 1053 *
1004 * 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
1005 * 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 *
1006 * 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
1007 * building the mapping pairs array. 1063 * building the mapping pairs array.
1008 * 1064 *
@@ -1018,34 +1074,50 @@ static inline int ntfs_get_nr_significant_bytes(const s64 n)
1018 * remains locked throughout, and is left locked upon return. 1074 * remains locked throughout, and is left locked upon return.
1019 */ 1075 */
1020int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol, 1076int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
1021 const runlist_element *rl, const VCN start_vcn) 1077 const runlist_element *rl, const VCN first_vcn,
1078 const VCN last_vcn)
1022{ 1079{
1023 LCN prev_lcn; 1080 LCN prev_lcn;
1024 int rls; 1081 int rls;
1082 BOOL the_end = FALSE;
1025 1083
1026 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);
1027 if (!rl) { 1087 if (!rl) {
1028 BUG_ON(start_vcn); 1088 BUG_ON(first_vcn);
1089 BUG_ON(last_vcn > 0);
1029 return 1; 1090 return 1;
1030 } 1091 }
1031 /* Skip to runlist element containing @start_vcn. */ 1092 /* Skip to runlist element containing @first_vcn. */
1032 while (rl->length && start_vcn >= rl[1].vcn) 1093 while (rl->length && first_vcn >= rl[1].vcn)
1033 rl++; 1094 rl++;
1034 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))
1035 return -EINVAL; 1097 return -EINVAL;
1036 prev_lcn = 0; 1098 prev_lcn = 0;
1037 /* Always need the termining zero byte. */ 1099 /* Always need the termining zero byte. */
1038 rls = 1; 1100 rls = 1;
1039 /* Do the first partial run if present. */ 1101 /* Do the first partial run if present. */
1040 if (start_vcn > rl->vcn) { 1102 if (first_vcn > rl->vcn) {
1041 s64 delta; 1103 s64 delta, length = rl->length;
1042 1104
1043 /* We know rl->length != 0 already. */ 1105 /* We know rl->length != 0 already. */
1044 if (rl->length < 0 || rl->lcn < LCN_HOLE) 1106 if (unlikely(length < 0 || rl->lcn < LCN_HOLE))
1045 goto err_out; 1107 goto err_out;
1046 delta = start_vcn - rl->vcn; 1108 /*
1109 * If @stop_vcn is given and finishes inside this run, cap the
1110 * run length.
1111 */
1112 if (unlikely(last_vcn >= 0 && rl[1].vcn > last_vcn)) {
1113 s64 s1 = last_vcn + 1;
1114 if (unlikely(rl[1].vcn > s1))
1115 length = s1 - rl->vcn;
1116 the_end = TRUE;
1117 }
1118 delta = first_vcn - rl->vcn;
1047 /* Header byte + length. */ 1119 /* Header byte + length. */
1048 rls += 1 + ntfs_get_nr_significant_bytes(rl->length - delta); 1120 rls += 1 + ntfs_get_nr_significant_bytes(length - delta);
1049 /* 1121 /*
1050 * If the logical cluster number (lcn) denotes a hole and we 1122 * If the logical cluster number (lcn) denotes a hole and we
1051 * are on NTFS 3.0+, we don't store it at all, i.e. we need 1123 * are on NTFS 3.0+, we don't store it at all, i.e. we need
@@ -1053,9 +1125,9 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
1053 * Note: this assumes that on NTFS 1.2-, holes are stored with 1125 * Note: this assumes that on NTFS 1.2-, holes are stored with
1054 * an lcn of -1 and not a delta_lcn of -1 (unless both are -1). 1126 * an lcn of -1 and not a delta_lcn of -1 (unless both are -1).
1055 */ 1127 */
1056 if (rl->lcn >= 0 || vol->major_ver < 3) { 1128 if (likely(rl->lcn >= 0 || vol->major_ver < 3)) {
1057 prev_lcn = rl->lcn; 1129 prev_lcn = rl->lcn;
1058 if (rl->lcn >= 0) 1130 if (likely(rl->lcn >= 0))
1059 prev_lcn += delta; 1131 prev_lcn += delta;
1060 /* Change in lcn. */ 1132 /* Change in lcn. */
1061 rls += ntfs_get_nr_significant_bytes(prev_lcn); 1133 rls += ntfs_get_nr_significant_bytes(prev_lcn);
@@ -1064,11 +1136,23 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
1064 rl++; 1136 rl++;
1065 } 1137 }
1066 /* Do the full runs. */ 1138 /* Do the full runs. */
1067 for (; rl->length; rl++) { 1139 for (; rl->length && !the_end; rl++) {
1068 if (rl->length < 0 || rl->lcn < LCN_HOLE) 1140 s64 length = rl->length;
1141
1142 if (unlikely(length < 0 || rl->lcn < LCN_HOLE))
1069 goto err_out; 1143 goto err_out;
1144 /*
1145 * If @stop_vcn is given and finishes inside this run, cap the
1146 * run length.
1147 */
1148 if (unlikely(last_vcn >= 0 && rl[1].vcn > last_vcn)) {
1149 s64 s1 = last_vcn + 1;
1150 if (unlikely(rl[1].vcn > s1))
1151 length = s1 - rl->vcn;
1152 the_end = TRUE;
1153 }
1070 /* Header byte + length. */ 1154 /* Header byte + length. */
1071 rls += 1 + ntfs_get_nr_significant_bytes(rl->length); 1155 rls += 1 + ntfs_get_nr_significant_bytes(length);
1072 /* 1156 /*
1073 * If the logical cluster number (lcn) denotes a hole and we 1157 * If the logical cluster number (lcn) denotes a hole and we
1074 * are on NTFS 3.0+, we don't store it at all, i.e. we need 1158 * are on NTFS 3.0+, we don't store it at all, i.e. we need
@@ -1076,7 +1160,7 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
1076 * Note: this assumes that on NTFS 1.2-, holes are stored with 1160 * Note: this assumes that on NTFS 1.2-, holes are stored with
1077 * an lcn of -1 and not a delta_lcn of -1 (unless both are -1). 1161 * an lcn of -1 and not a delta_lcn of -1 (unless both are -1).
1078 */ 1162 */
1079 if (rl->lcn >= 0 || vol->major_ver < 3) { 1163 if (likely(rl->lcn >= 0 || vol->major_ver < 3)) {
1080 /* Change in lcn. */ 1164 /* Change in lcn. */
1081 rls += ntfs_get_nr_significant_bytes(rl->lcn - 1165 rls += ntfs_get_nr_significant_bytes(rl->lcn -
1082 prev_lcn); 1166 prev_lcn);
@@ -1119,7 +1203,7 @@ static inline int ntfs_write_significant_bytes(s8 *dst, const s8 *dst_max,
1119 1203
1120 i = 0; 1204 i = 0;
1121 do { 1205 do {
1122 if (dst > dst_max) 1206 if (unlikely(dst > dst_max))
1123 goto err_out; 1207 goto err_out;
1124 *dst++ = l & 0xffll; 1208 *dst++ = l & 0xffll;
1125 l >>= 8; 1209 l >>= 8;
@@ -1128,12 +1212,12 @@ static inline int ntfs_write_significant_bytes(s8 *dst, const s8 *dst_max,
1128 j = (n >> 8 * (i - 1)) & 0xff; 1212 j = (n >> 8 * (i - 1)) & 0xff;
1129 /* If the sign bit is wrong, we need an extra byte. */ 1213 /* If the sign bit is wrong, we need an extra byte. */
1130 if (n < 0 && j >= 0) { 1214 if (n < 0 && j >= 0) {
1131 if (dst > dst_max) 1215 if (unlikely(dst > dst_max))
1132 goto err_out; 1216 goto err_out;
1133 i++; 1217 i++;
1134 *dst = (s8)-1; 1218 *dst = (s8)-1;
1135 } else if (n > 0 && j < 0) { 1219 } else if (n > 0 && j < 0) {
1136 if (dst > dst_max) 1220 if (unlikely(dst > dst_max))
1137 goto err_out; 1221 goto err_out;
1138 i++; 1222 i++;
1139 *dst = (s8)0; 1223 *dst = (s8)0;
@@ -1149,13 +1233,18 @@ err_out:
1149 * @dst: destination buffer to which to write the mapping pairs array 1233 * @dst: destination buffer to which to write the mapping pairs array
1150 * @dst_len: size of destination buffer @dst in bytes 1234 * @dst_len: size of destination buffer @dst in bytes
1151 * @rl: locked runlist for which to build the mapping pairs array 1235 * @rl: locked runlist for which to build the mapping pairs array
1152 * @start_vcn: vcn at which to start the mapping pairs array 1236 * @first_vcn: first vcn which to include in the mapping pairs array
1237 * @last_vcn: last vcn which to include in the mapping pairs array
1153 * @stop_vcn: first vcn outside destination buffer on success or -ENOSPC 1238 * @stop_vcn: first vcn outside destination buffer on success or -ENOSPC
1154 * 1239 *
1155 * Create the mapping pairs array from the locked runlist @rl, starting at vcn 1240 * Create the mapping pairs array from the locked runlist @rl, starting at vcn
1156 * @start_vcn and save the array in @dst. @dst_len is the size of @dst in 1241 * @first_vcn and finishing with vcn @last_vcn and save the array in @dst.
1157 * bytes and it should be at least equal to the value obtained by calling 1242 * @dst_len is the size of @dst in bytes and it should be at least equal to the
1158 * ntfs_get_size_for_mapping_pairs(). 1243 * value obtained by calling ntfs_get_size_for_mapping_pairs().
1244 *
1245 * A @last_vcn of -1 means end of runlist and in that case the mapping pairs
1246 * array corresponding to the runlist starting at vcn @first_vcn and finishing
1247 * at the end of the runlist is created.
1159 * 1248 *
1160 * If @rl is NULL, just write a single terminator byte to @dst. 1249 * If @rl is NULL, just write a single terminator byte to @dst.
1161 * 1250 *
@@ -1164,7 +1253,7 @@ err_out:
1164 * been filled with all the mapping pairs that will fit, thus it can be treated 1253 * been filled with all the mapping pairs that will fit, thus it can be treated
1165 * as partial success, in that a new attribute extent needs to be created or 1254 * as partial success, in that a new attribute extent needs to be created or
1166 * the next extent has to be used and the mapping pairs build has to be 1255 * the next extent has to be used and the mapping pairs build has to be
1167 * continued with @start_vcn set to *@stop_vcn. 1256 * continued with @first_vcn set to *@stop_vcn.
1168 * 1257 *
1169 * Return 0 on success and -errno on error. The following error codes are 1258 * Return 0 on success and -errno on error. The following error codes are
1170 * defined: 1259 * defined:
@@ -1178,27 +1267,32 @@ err_out:
1178 */ 1267 */
1179int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst, 1268int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst,
1180 const int dst_len, const runlist_element *rl, 1269 const int dst_len, const runlist_element *rl,
1181 const VCN start_vcn, VCN *const stop_vcn) 1270 const VCN first_vcn, const VCN last_vcn, VCN *const stop_vcn)
1182{ 1271{
1183 LCN prev_lcn; 1272 LCN prev_lcn;
1184 s8 *dst_max, *dst_next; 1273 s8 *dst_max, *dst_next;
1185 int err = -ENOSPC; 1274 int err = -ENOSPC;
1275 BOOL the_end = FALSE;
1186 s8 len_len, lcn_len; 1276 s8 len_len, lcn_len;
1187 1277
1188 BUG_ON(start_vcn < 0); 1278 BUG_ON(first_vcn < 0);
1279 BUG_ON(last_vcn < -1);
1280 BUG_ON(last_vcn >= 0 && first_vcn > last_vcn);
1189 BUG_ON(dst_len < 1); 1281 BUG_ON(dst_len < 1);
1190 if (!rl) { 1282 if (!rl) {
1191 BUG_ON(start_vcn); 1283 BUG_ON(first_vcn);
1284 BUG_ON(last_vcn > 0);
1192 if (stop_vcn) 1285 if (stop_vcn)
1193 *stop_vcn = 0; 1286 *stop_vcn = 0;
1194 /* Terminator byte. */ 1287 /* Terminator byte. */
1195 *dst = 0; 1288 *dst = 0;
1196 return 0; 1289 return 0;
1197 } 1290 }
1198 /* Skip to runlist element containing @start_vcn. */ 1291 /* Skip to runlist element containing @first_vcn. */
1199 while (rl->length && start_vcn >= rl[1].vcn) 1292 while (rl->length && first_vcn >= rl[1].vcn)
1200 rl++; 1293 rl++;
1201 if ((!rl->length && start_vcn > rl->vcn) || start_vcn < rl->vcn) 1294 if (unlikely((!rl->length && first_vcn > rl->vcn) ||
1295 first_vcn < rl->vcn))
1202 return -EINVAL; 1296 return -EINVAL;
1203 /* 1297 /*
1204 * @dst_max is used for bounds checking in 1298 * @dst_max is used for bounds checking in
@@ -1207,17 +1301,27 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst,
1207 dst_max = dst + dst_len - 1; 1301 dst_max = dst + dst_len - 1;
1208 prev_lcn = 0; 1302 prev_lcn = 0;
1209 /* Do the first partial run if present. */ 1303 /* Do the first partial run if present. */
1210 if (start_vcn > rl->vcn) { 1304 if (first_vcn > rl->vcn) {
1211 s64 delta; 1305 s64 delta, length = rl->length;
1212 1306
1213 /* We know rl->length != 0 already. */ 1307 /* We know rl->length != 0 already. */
1214 if (rl->length < 0 || rl->lcn < LCN_HOLE) 1308 if (unlikely(length < 0 || rl->lcn < LCN_HOLE))
1215 goto err_out; 1309 goto err_out;
1216 delta = start_vcn - rl->vcn; 1310 /*
1311 * If @stop_vcn is given and finishes inside this run, cap the
1312 * run length.
1313 */
1314 if (unlikely(last_vcn >= 0 && rl[1].vcn > last_vcn)) {
1315 s64 s1 = last_vcn + 1;
1316 if (unlikely(rl[1].vcn > s1))
1317 length = s1 - rl->vcn;
1318 the_end = TRUE;
1319 }
1320 delta = first_vcn - rl->vcn;
1217 /* Write length. */ 1321 /* Write length. */
1218 len_len = ntfs_write_significant_bytes(dst + 1, dst_max, 1322 len_len = ntfs_write_significant_bytes(dst + 1, dst_max,
1219 rl->length - delta); 1323 length - delta);
1220 if (len_len < 0) 1324 if (unlikely(len_len < 0))
1221 goto size_err; 1325 goto size_err;
1222 /* 1326 /*
1223 * If the logical cluster number (lcn) denotes a hole and we 1327 * If the logical cluster number (lcn) denotes a hole and we
@@ -1228,19 +1332,19 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst,
1228 * case on NT4. - We assume that we just need to write the lcn 1332 * case on NT4. - We assume that we just need to write the lcn
1229 * change until someone tells us otherwise... (AIA) 1333 * change until someone tells us otherwise... (AIA)
1230 */ 1334 */
1231 if (rl->lcn >= 0 || vol->major_ver < 3) { 1335 if (likely(rl->lcn >= 0 || vol->major_ver < 3)) {
1232 prev_lcn = rl->lcn; 1336 prev_lcn = rl->lcn;
1233 if (rl->lcn >= 0) 1337 if (likely(rl->lcn >= 0))
1234 prev_lcn += delta; 1338 prev_lcn += delta;
1235 /* Write change in lcn. */ 1339 /* Write change in lcn. */
1236 lcn_len = ntfs_write_significant_bytes(dst + 1 + 1340 lcn_len = ntfs_write_significant_bytes(dst + 1 +
1237 len_len, dst_max, prev_lcn); 1341 len_len, dst_max, prev_lcn);
1238 if (lcn_len < 0) 1342 if (unlikely(lcn_len < 0))
1239 goto size_err; 1343 goto size_err;
1240 } else 1344 } else
1241 lcn_len = 0; 1345 lcn_len = 0;
1242 dst_next = dst + len_len + lcn_len + 1; 1346 dst_next = dst + len_len + lcn_len + 1;
1243 if (dst_next > dst_max) 1347 if (unlikely(dst_next > dst_max))
1244 goto size_err; 1348 goto size_err;
1245 /* Update header byte. */ 1349 /* Update header byte. */
1246 *dst = lcn_len << 4 | len_len; 1350 *dst = lcn_len << 4 | len_len;
@@ -1250,13 +1354,25 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst,
1250 rl++; 1354 rl++;
1251 } 1355 }
1252 /* Do the full runs. */ 1356 /* Do the full runs. */
1253 for (; rl->length; rl++) { 1357 for (; rl->length && !the_end; rl++) {
1254 if (rl->length < 0 || rl->lcn < LCN_HOLE) 1358 s64 length = rl->length;
1359
1360 if (unlikely(length < 0 || rl->lcn < LCN_HOLE))
1255 goto err_out; 1361 goto err_out;
1362 /*
1363 * If @stop_vcn is given and finishes inside this run, cap the
1364 * run length.
1365 */
1366 if (unlikely(last_vcn >= 0 && rl[1].vcn > last_vcn)) {
1367 s64 s1 = last_vcn + 1;
1368 if (unlikely(rl[1].vcn > s1))
1369 length = s1 - rl->vcn;
1370 the_end = TRUE;
1371 }
1256 /* Write length. */ 1372 /* Write length. */
1257 len_len = ntfs_write_significant_bytes(dst + 1, dst_max, 1373 len_len = ntfs_write_significant_bytes(dst + 1, dst_max,
1258 rl->length); 1374 length);
1259 if (len_len < 0) 1375 if (unlikely(len_len < 0))
1260 goto size_err; 1376 goto size_err;
1261 /* 1377 /*
1262 * If the logical cluster number (lcn) denotes a hole and we 1378 * If the logical cluster number (lcn) denotes a hole and we
@@ -1267,17 +1383,17 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst,
1267 * case on NT4. - We assume that we just need to write the lcn 1383 * case on NT4. - We assume that we just need to write the lcn
1268 * change until someone tells us otherwise... (AIA) 1384 * change until someone tells us otherwise... (AIA)
1269 */ 1385 */
1270 if (rl->lcn >= 0 || vol->major_ver < 3) { 1386 if (likely(rl->lcn >= 0 || vol->major_ver < 3)) {
1271 /* Write change in lcn. */ 1387 /* Write change in lcn. */
1272 lcn_len = ntfs_write_significant_bytes(dst + 1 + 1388 lcn_len = ntfs_write_significant_bytes(dst + 1 +
1273 len_len, dst_max, rl->lcn - prev_lcn); 1389 len_len, dst_max, rl->lcn - prev_lcn);
1274 if (lcn_len < 0) 1390 if (unlikely(lcn_len < 0))
1275 goto size_err; 1391 goto size_err;
1276 prev_lcn = rl->lcn; 1392 prev_lcn = rl->lcn;
1277 } else 1393 } else
1278 lcn_len = 0; 1394 lcn_len = 0;
1279 dst_next = dst + len_len + lcn_len + 1; 1395 dst_next = dst + len_len + lcn_len + 1;
1280 if (dst_next > dst_max) 1396 if (unlikely(dst_next > dst_max))
1281 goto size_err; 1397 goto size_err;
1282 /* Update header byte. */ 1398 /* Update header byte. */
1283 *dst = lcn_len << 4 | len_len; 1399 *dst = lcn_len << 4 | len_len;
@@ -1436,3 +1552,5 @@ int ntfs_rl_truncate_nolock(const ntfs_volume *vol, runlist *const runlist,
1436 ntfs_debug("Done."); 1552 ntfs_debug("Done.");
1437 return 0; 1553 return 0;
1438} 1554}
1555
1556#endif /* NTFS_RW */