diff options
Diffstat (limited to 'fs/udf/partition.c')
-rw-r--r-- | fs/udf/partition.c | 212 |
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 | ||
47 | uint32_t udf_get_pblock_virt15(struct super_block * sb, uint32_t block, | 45 | uint32_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 | ||
100 | inline uint32_t udf_get_pblock_virt20(struct super_block * sb, uint32_t block, | 92 | inline 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 | ||
147 | int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) | 128 | int 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 =) */ |