aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/partition.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf/partition.c')
-rw-r--r--fs/udf/partition.c212
1 files changed, 58 insertions, 154 deletions
diff --git a/fs/udf/partition.c b/fs/udf/partition.c
index a95d830a674d..aaab24c8c498 100644
--- a/fs/udf/partition.c
+++ b/fs/udf/partition.c
@@ -14,7 +14,7 @@
14 * 14 *
15 * HISTORY 15 * HISTORY
16 * 16 *
17 * 12/06/98 blf Created file. 17 * 12/06/98 blf Created file.
18 * 18 *
19 */ 19 */
20 20
@@ -32,19 +32,17 @@ inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block,
32 uint16_t partition, uint32_t offset) 32 uint16_t partition, uint32_t offset)
33{ 33{
34 if (partition >= UDF_SB_NUMPARTS(sb)) { 34 if (partition >= UDF_SB_NUMPARTS(sb)) {
35 udf_debug 35 udf_debug("block=%d, partition=%d, offset=%d: invalid partition\n",
36 ("block=%d, partition=%d, offset=%d: invalid partition\n", 36 block, partition, offset);
37 block, partition, offset);
38 return 0xFFFFFFFF; 37 return 0xFFFFFFFF;
39 } 38 }
40 if (UDF_SB_PARTFUNC(sb, partition)) 39 if (UDF_SB_PARTFUNC(sb, partition))
41 return UDF_SB_PARTFUNC(sb, partition) (sb, block, partition, 40 return UDF_SB_PARTFUNC(sb, partition)(sb, block, partition, offset);
42 offset);
43 else 41 else
44 return UDF_SB_PARTROOT(sb, partition) + block + offset; 42 return UDF_SB_PARTROOT(sb, partition) + block + offset;
45} 43}
46 44
47uint32_t udf_get_pblock_virt15(struct super_block * sb, uint32_t block, 45uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block,
48 uint16_t partition, uint32_t offset) 46 uint16_t partition, uint32_t offset)
49{ 47{
50 struct buffer_head *bh = NULL; 48 struct buffer_head *bh = NULL;
@@ -52,14 +50,11 @@ uint32_t udf_get_pblock_virt15(struct super_block * sb, uint32_t block,
52 uint32_t index; 50 uint32_t index;
53 uint32_t loc; 51 uint32_t loc;
54 52
55 index = 53 index = (sb->s_blocksize - UDF_SB_TYPEVIRT(sb,partition).s_start_offset) / sizeof(uint32_t);
56 (sb->s_blocksize -
57 UDF_SB_TYPEVIRT(sb, partition).s_start_offset) / sizeof(uint32_t);
58 54
59 if (block > UDF_SB_TYPEVIRT(sb, partition).s_num_entries) { 55 if (block > UDF_SB_TYPEVIRT(sb,partition).s_num_entries) {
60 udf_debug 56 udf_debug("Trying to access block beyond end of VAT (%d max %d)\n",
61 ("Trying to access block beyond end of VAT (%d max %d)\n", 57 block, UDF_SB_TYPEVIRT(sb,partition).s_num_entries);
62 block, UDF_SB_TYPEVIRT(sb, partition).s_num_entries);
63 return 0xFFFFFFFF; 58 return 0xFFFFFFFF;
64 } 59 }
65 60
@@ -69,10 +64,7 @@ uint32_t udf_get_pblock_virt15(struct super_block * sb, uint32_t block,
69 index = block % (sb->s_blocksize / sizeof(uint32_t)); 64 index = block % (sb->s_blocksize / sizeof(uint32_t));
70 } else { 65 } else {
71 newblock = 0; 66 newblock = 0;
72 index = 67 index = UDF_SB_TYPEVIRT(sb,partition).s_start_offset / sizeof(uint32_t) + block;
73 UDF_SB_TYPEVIRT(sb,
74 partition).s_start_offset /
75 sizeof(uint32_t) + block;
76 } 68 }
77 69
78 loc = udf_block_map(UDF_SB_VAT(sb), newblock); 70 loc = udf_block_map(UDF_SB_VAT(sb), newblock);
@@ -83,7 +75,7 @@ uint32_t udf_get_pblock_virt15(struct super_block * sb, uint32_t block,
83 return 0xFFFFFFFF; 75 return 0xFFFFFFFF;
84 } 76 }
85 77
86 loc = le32_to_cpu(((__le32 *) bh->b_data)[index]); 78 loc = le32_to_cpu(((__le32 *)bh->b_data)[index]);
87 79
88 brelse(bh); 80 brelse(bh);
89 81
@@ -93,8 +85,8 @@ uint32_t udf_get_pblock_virt15(struct super_block * sb, uint32_t block,
93 } 85 }
94 86
95 return udf_get_pblock(sb, loc, 87 return udf_get_pblock(sb, loc,
96 UDF_I_LOCATION(UDF_SB_VAT(sb)). 88 UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum,
97 partitionReferenceNum, offset); 89 offset);
98} 90}
99 91
100inline uint32_t udf_get_pblock_virt20(struct super_block * sb, uint32_t block, 92inline uint32_t udf_get_pblock_virt20(struct super_block * sb, uint32_t block,
@@ -108,40 +100,29 @@ uint32_t udf_get_pblock_spar15(struct super_block * sb, uint32_t block,
108{ 100{
109 int i; 101 int i;
110 struct sparingTable *st = NULL; 102 struct sparingTable *st = NULL;
111 uint32_t packet = 103 uint32_t packet = (block + offset) & ~(UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1);
112 (block + offset) & ~(UDF_SB_TYPESPAR(sb, partition).s_packet_len -
113 1);
114 104
115 for (i = 0; i < 4; i++) { 105 for (i = 0; i < 4; i++) {
116 if (UDF_SB_TYPESPAR(sb, partition).s_spar_map[i] != NULL) { 106 if (UDF_SB_TYPESPAR(sb,partition).s_spar_map[i] != NULL) {
117 st = (struct sparingTable *)UDF_SB_TYPESPAR(sb, 107 st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,partition).s_spar_map[i]->b_data;
118 partition).
119 s_spar_map[i]->b_data;
120 break; 108 break;
121 } 109 }
122 } 110 }
123 111
124 if (st) { 112 if (st) {
125 for (i = 0; i < le16_to_cpu(st->reallocationTableLen); i++) { 113 for (i = 0; i < le16_to_cpu(st->reallocationTableLen); i++) {
126 if (le32_to_cpu(st->mapEntry[i].origLocation) >= 114 if (le32_to_cpu(st->mapEntry[i].origLocation) >= 0xFFFFFFF0) {
127 0xFFFFFFF0)
128 break; 115 break;
129 else if (le32_to_cpu(st->mapEntry[i].origLocation) == 116 } else if (le32_to_cpu(st->mapEntry[i].origLocation) == packet) {
130 packet) { 117 return le32_to_cpu(st->mapEntry[i].mappedLocation) +
131 return le32_to_cpu(st->mapEntry[i]. 118 ((block + offset) & (UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1));
132 mappedLocation) + ((block + 119 } else if (le32_to_cpu(st->mapEntry[i].origLocation) > packet) {
133 offset) &
134 (UDF_SB_TYPESPAR
135 (sb,
136 partition).
137 s_packet_len
138 - 1));
139 } else if (le32_to_cpu(st->mapEntry[i].origLocation) >
140 packet)
141 break; 120 break;
121 }
142 } 122 }
143 } 123 }
144 return UDF_SB_PARTROOT(sb, partition) + block + offset; 124
125 return UDF_SB_PARTROOT(sb,partition) + block + offset;
145} 126}
146 127
147int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) 128int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
@@ -153,20 +134,14 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
153 int i, j, k, l; 134 int i, j, k, l;
154 135
155 for (i = 0; i < UDF_SB_NUMPARTS(sb); i++) { 136 for (i = 0; i < UDF_SB_NUMPARTS(sb); i++) {
156 if (old_block > UDF_SB_PARTROOT(sb, i) && 137 if (old_block > UDF_SB_PARTROOT(sb,i) &&
157 old_block < UDF_SB_PARTROOT(sb, i) + UDF_SB_PARTLEN(sb, i)) 138 old_block < UDF_SB_PARTROOT(sb,i) + UDF_SB_PARTLEN(sb,i)) {
158 { 139 sdata = &UDF_SB_TYPESPAR(sb,i);
159 sdata = &UDF_SB_TYPESPAR(sb, i); 140 packet = (old_block - UDF_SB_PARTROOT(sb,i)) & ~(sdata->s_packet_len - 1);
160 packet =
161 (old_block -
162 UDF_SB_PARTROOT(sb,
163 i)) & ~(sdata->s_packet_len - 1);
164 141
165 for (j = 0; j < 4; j++) { 142 for (j = 0; j < 4; j++) {
166 if (UDF_SB_TYPESPAR(sb, i).s_spar_map[j] != 143 if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL) {
167 NULL) { 144 st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
168 st = (struct sparingTable *)sdata->
169 s_spar_map[j]->b_data;
170 break; 145 break;
171 } 146 }
172 } 147 }
@@ -174,122 +149,51 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
174 if (!st) 149 if (!st)
175 return 1; 150 return 1;
176 151
177 for (k = 0; k < le16_to_cpu(st->reallocationTableLen); 152 for (k = 0; k < le16_to_cpu(st->reallocationTableLen); k++) {
178 k++) { 153 if (le32_to_cpu(st->mapEntry[k].origLocation) == 0xFFFFFFFF) {
179 if (le32_to_cpu(st->mapEntry[k].origLocation) ==
180 0xFFFFFFFF) {
181 for (; j < 4; j++) { 154 for (; j < 4; j++) {
182 if (sdata->s_spar_map[j]) { 155 if (sdata->s_spar_map[j]) {
183 st = (struct 156 st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
184 sparingTable *) 157 st->mapEntry[k].origLocation = cpu_to_le32(packet);
185 sdata-> 158 udf_update_tag((char *)st, sizeof(struct sparingTable) + le16_to_cpu(st->reallocationTableLen) * sizeof(struct sparingEntry));
186 s_spar_map[j]-> 159 mark_buffer_dirty(sdata->s_spar_map[j]);
187 b_data;
188 st->mapEntry[k].
189 origLocation =
190 cpu_to_le32(packet);
191 udf_update_tag((char *)
192 st,
193 sizeof
194 (struct
195 sparingTable)
196 +
197 le16_to_cpu
198 (st->
199 reallocationTableLen)
200 *
201 sizeof
202 (struct
203 sparingEntry));
204 mark_buffer_dirty
205 (sdata->
206 s_spar_map[j]);
207 } 160 }
208 } 161 }
209 *new_block = 162 *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
210 le32_to_cpu(st->mapEntry[k]. 163 ((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
211 mappedLocation) +
212 ((old_block -
213 UDF_SB_PARTROOT(sb,
214 i)) & (sdata->
215 s_packet_len
216 - 1));
217 return 0; 164 return 0;
218 } else 165 } else if (le32_to_cpu(st->mapEntry[k].origLocation) == packet) {
219 if (le32_to_cpu 166 *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
220 (st->mapEntry[k].origLocation) == 167 ((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
221 packet) {
222 *new_block =
223 le32_to_cpu(st->mapEntry[k].
224 mappedLocation) +
225 ((old_block -
226 UDF_SB_PARTROOT(sb,
227 i)) & (sdata->
228 s_packet_len
229 - 1));
230 return 0; 168 return 0;
231 } else 169 } else if (le32_to_cpu(st->mapEntry[k].origLocation) > packet) {
232 if (le32_to_cpu
233 (st->mapEntry[k].origLocation) > packet)
234 break; 170 break;
171 }
235 } 172 }
236 for (l = k; l < le16_to_cpu(st->reallocationTableLen); 173
237 l++) { 174 for (l = k; l < le16_to_cpu(st->reallocationTableLen); l++) {
238 if (le32_to_cpu(st->mapEntry[l].origLocation) == 175 if (le32_to_cpu(st->mapEntry[l].origLocation) == 0xFFFFFFFF) {
239 0xFFFFFFFF) {
240 for (; j < 4; j++) { 176 for (; j < 4; j++) {
241 if (sdata->s_spar_map[j]) { 177 if (sdata->s_spar_map[j]) {
242 st = (struct 178 st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
243 sparingTable *) 179 mapEntry = st->mapEntry[l];
244 sdata-> 180 mapEntry.origLocation = cpu_to_le32(packet);
245 s_spar_map[j]-> 181 memmove(&st->mapEntry[k + 1], &st->mapEntry[k], (l - k) * sizeof(struct sparingEntry));
246 b_data; 182 st->mapEntry[k] = mapEntry;
247 mapEntry = 183 udf_update_tag((char *)st, sizeof(struct sparingTable) + le16_to_cpu(st->reallocationTableLen) * sizeof(struct sparingEntry));
248 st->mapEntry[l]; 184 mark_buffer_dirty(sdata->s_spar_map[j]);
249 mapEntry.origLocation =
250 cpu_to_le32(packet);
251 memmove(&st->
252 mapEntry[k + 1],
253 &st->
254 mapEntry[k],
255 (l -
256 k) *
257 sizeof(struct
258 sparingEntry));
259 st->mapEntry[k] =
260 mapEntry;
261 udf_update_tag((char *)
262 st,
263 sizeof
264 (struct
265 sparingTable)
266 +
267 le16_to_cpu
268 (st->
269 reallocationTableLen)
270 *
271 sizeof
272 (struct
273 sparingEntry));
274 mark_buffer_dirty
275 (sdata->
276 s_spar_map[j]);
277 } 185 }
278 } 186 }
279 *new_block = 187 *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
280 le32_to_cpu(st->mapEntry[k]. 188 ((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
281 mappedLocation) +
282 ((old_block -
283 UDF_SB_PARTROOT(sb,
284 i)) & (sdata->
285 s_packet_len
286 - 1));
287 return 0; 189 return 0;
288 } 190 }
289 } 191 }
192
290 return 1; 193 return 1;
291 } 194 } /* if old_block */
292 } 195 }
196
293 if (i == UDF_SB_NUMPARTS(sb)) { 197 if (i == UDF_SB_NUMPARTS(sb)) {
294 /* outside of partitions */ 198 /* outside of partitions */
295 /* for now, fail =) */ 199 /* for now, fail =) */