diff options
Diffstat (limited to 'fs/udf/partition.c')
-rw-r--r-- | fs/udf/partition.c | 119 |
1 files changed, 51 insertions, 68 deletions
diff --git a/fs/udf/partition.c b/fs/udf/partition.c index 467a26171cd9..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 | ||
@@ -28,12 +28,12 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/buffer_head.h> | 29 | #include <linux/buffer_head.h> |
30 | 30 | ||
31 | inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset) | 31 | inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, |
32 | uint16_t partition, uint32_t offset) | ||
32 | { | 33 | { |
33 | if (partition >= UDF_SB_NUMPARTS(sb)) | 34 | if (partition >= UDF_SB_NUMPARTS(sb)) { |
34 | { | ||
35 | udf_debug("block=%d, partition=%d, offset=%d: invalid partition\n", | 35 | udf_debug("block=%d, partition=%d, offset=%d: invalid partition\n", |
36 | block, partition, offset); | 36 | block, partition, offset); |
37 | return 0xFFFFFFFF; | 37 | return 0xFFFFFFFF; |
38 | } | 38 | } |
39 | if (UDF_SB_PARTFUNC(sb, partition)) | 39 | if (UDF_SB_PARTFUNC(sb, partition)) |
@@ -42,7 +42,8 @@ inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, uint16_t | |||
42 | return UDF_SB_PARTROOT(sb, partition) + block + offset; | 42 | return UDF_SB_PARTROOT(sb, partition) + block + offset; |
43 | } | 43 | } |
44 | 44 | ||
45 | uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset) | 45 | uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, |
46 | uint16_t partition, uint32_t offset) | ||
46 | { | 47 | { |
47 | struct buffer_head *bh = NULL; | 48 | struct buffer_head *bh = NULL; |
48 | uint32_t newblock; | 49 | uint32_t newblock; |
@@ -51,31 +52,26 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, uint16_t | |||
51 | 52 | ||
52 | index = (sb->s_blocksize - UDF_SB_TYPEVIRT(sb,partition).s_start_offset) / sizeof(uint32_t); | 53 | index = (sb->s_blocksize - UDF_SB_TYPEVIRT(sb,partition).s_start_offset) / sizeof(uint32_t); |
53 | 54 | ||
54 | if (block > UDF_SB_TYPEVIRT(sb,partition).s_num_entries) | 55 | if (block > UDF_SB_TYPEVIRT(sb,partition).s_num_entries) { |
55 | { | ||
56 | udf_debug("Trying to access block beyond end of VAT (%d max %d)\n", | 56 | udf_debug("Trying to access block beyond end of VAT (%d max %d)\n", |
57 | block, UDF_SB_TYPEVIRT(sb,partition).s_num_entries); | 57 | block, UDF_SB_TYPEVIRT(sb,partition).s_num_entries); |
58 | return 0xFFFFFFFF; | 58 | return 0xFFFFFFFF; |
59 | } | 59 | } |
60 | 60 | ||
61 | if (block >= index) | 61 | if (block >= index) { |
62 | { | ||
63 | block -= index; | 62 | block -= index; |
64 | newblock = 1 + (block / (sb->s_blocksize / sizeof(uint32_t))); | 63 | newblock = 1 + (block / (sb->s_blocksize / sizeof(uint32_t))); |
65 | index = block % (sb->s_blocksize / sizeof(uint32_t)); | 64 | index = block % (sb->s_blocksize / sizeof(uint32_t)); |
66 | } | 65 | } else { |
67 | else | ||
68 | { | ||
69 | newblock = 0; | 66 | newblock = 0; |
70 | index = UDF_SB_TYPEVIRT(sb,partition).s_start_offset / sizeof(uint32_t) + block; | 67 | index = UDF_SB_TYPEVIRT(sb,partition).s_start_offset / sizeof(uint32_t) + block; |
71 | } | 68 | } |
72 | 69 | ||
73 | loc = udf_block_map(UDF_SB_VAT(sb), newblock); | 70 | loc = udf_block_map(UDF_SB_VAT(sb), newblock); |
74 | 71 | ||
75 | if (!(bh = sb_bread(sb, loc))) | 72 | if (!(bh = sb_bread(sb, loc))) { |
76 | { | ||
77 | udf_debug("get_pblock(UDF_VIRTUAL_MAP:%p,%d,%d) VAT: %d[%d]\n", | 73 | udf_debug("get_pblock(UDF_VIRTUAL_MAP:%p,%d,%d) VAT: %d[%d]\n", |
78 | sb, block, partition, loc, index); | 74 | sb, block, partition, loc, index); |
79 | return 0xFFFFFFFF; | 75 | return 0xFFFFFFFF; |
80 | } | 76 | } |
81 | 77 | ||
@@ -83,50 +79,49 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, uint16_t | |||
83 | 79 | ||
84 | brelse(bh); | 80 | brelse(bh); |
85 | 81 | ||
86 | if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition) | 82 | if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition) { |
87 | { | ||
88 | udf_debug("recursive call to udf_get_pblock!\n"); | 83 | udf_debug("recursive call to udf_get_pblock!\n"); |
89 | return 0xFFFFFFFF; | 84 | return 0xFFFFFFFF; |
90 | } | 85 | } |
91 | 86 | ||
92 | return udf_get_pblock(sb, loc, UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum, offset); | 87 | return udf_get_pblock(sb, loc, |
88 | UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum, | ||
89 | offset); | ||
93 | } | 90 | } |
94 | 91 | ||
95 | inline uint32_t udf_get_pblock_virt20(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset) | 92 | inline uint32_t udf_get_pblock_virt20(struct super_block * sb, uint32_t block, |
93 | uint16_t partition, uint32_t offset) | ||
96 | { | 94 | { |
97 | return udf_get_pblock_virt15(sb, block, partition, offset); | 95 | return udf_get_pblock_virt15(sb, block, partition, offset); |
98 | } | 96 | } |
99 | 97 | ||
100 | uint32_t udf_get_pblock_spar15(struct super_block *sb, uint32_t block, uint16_t partition, uint32_t offset) | 98 | uint32_t udf_get_pblock_spar15(struct super_block * sb, uint32_t block, |
99 | uint16_t partition, uint32_t offset) | ||
101 | { | 100 | { |
102 | int i; | 101 | int i; |
103 | struct sparingTable *st = NULL; | 102 | struct sparingTable *st = NULL; |
104 | uint32_t packet = (block + offset) & ~(UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1); | 103 | uint32_t packet = (block + offset) & ~(UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1); |
105 | 104 | ||
106 | for (i=0; i<4; i++) | 105 | for (i = 0; i < 4; i++) { |
107 | { | 106 | if (UDF_SB_TYPESPAR(sb,partition).s_spar_map[i] != NULL) { |
108 | if (UDF_SB_TYPESPAR(sb,partition).s_spar_map[i] != NULL) | ||
109 | { | ||
110 | st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,partition).s_spar_map[i]->b_data; | 107 | st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,partition).s_spar_map[i]->b_data; |
111 | break; | 108 | break; |
112 | } | 109 | } |
113 | } | 110 | } |
114 | 111 | ||
115 | if (st) | 112 | if (st) { |
116 | { | 113 | for (i = 0; i < le16_to_cpu(st->reallocationTableLen); i++) { |
117 | for (i=0; i<le16_to_cpu(st->reallocationTableLen); i++) | 114 | if (le32_to_cpu(st->mapEntry[i].origLocation) >= 0xFFFFFFF0) { |
118 | { | ||
119 | if (le32_to_cpu(st->mapEntry[i].origLocation) >= 0xFFFFFFF0) | ||
120 | break; | 115 | break; |
121 | else if (le32_to_cpu(st->mapEntry[i].origLocation) == packet) | 116 | } else if (le32_to_cpu(st->mapEntry[i].origLocation) == packet) { |
122 | { | ||
123 | return le32_to_cpu(st->mapEntry[i].mappedLocation) + | 117 | return le32_to_cpu(st->mapEntry[i].mappedLocation) + |
124 | ((block + offset) & (UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1)); | 118 | ((block + offset) & (UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1)); |
125 | } | 119 | } else if (le32_to_cpu(st->mapEntry[i].origLocation) > packet) { |
126 | else if (le32_to_cpu(st->mapEntry[i].origLocation) > packet) | ||
127 | break; | 120 | break; |
121 | } | ||
128 | } | 122 | } |
129 | } | 123 | } |
124 | |||
130 | return UDF_SB_PARTROOT(sb,partition) + block + offset; | 125 | return UDF_SB_PARTROOT(sb,partition) + block + offset; |
131 | } | 126 | } |
132 | 127 | ||
@@ -138,18 +133,14 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) | |||
138 | uint32_t packet; | 133 | uint32_t packet; |
139 | int i, j, k, l; | 134 | int i, j, k, l; |
140 | 135 | ||
141 | for (i=0; i<UDF_SB_NUMPARTS(sb); i++) | 136 | for (i = 0; i < UDF_SB_NUMPARTS(sb); i++) { |
142 | { | ||
143 | if (old_block > UDF_SB_PARTROOT(sb,i) && | 137 | if (old_block > UDF_SB_PARTROOT(sb,i) && |
144 | 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)) { |
145 | { | ||
146 | sdata = &UDF_SB_TYPESPAR(sb,i); | 139 | sdata = &UDF_SB_TYPESPAR(sb,i); |
147 | packet = (old_block - UDF_SB_PARTROOT(sb,i)) & ~(sdata->s_packet_len - 1); | 140 | packet = (old_block - UDF_SB_PARTROOT(sb,i)) & ~(sdata->s_packet_len - 1); |
148 | 141 | ||
149 | for (j=0; j<4; j++) | 142 | for (j = 0; j < 4; j++) { |
150 | { | 143 | if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL) { |
151 | if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL) | ||
152 | { | ||
153 | st = (struct sparingTable *)sdata->s_spar_map[j]->b_data; | 144 | st = (struct sparingTable *)sdata->s_spar_map[j]->b_data; |
154 | break; | 145 | break; |
155 | } | 146 | } |
@@ -158,14 +149,10 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) | |||
158 | if (!st) | 149 | if (!st) |
159 | return 1; | 150 | return 1; |
160 | 151 | ||
161 | for (k=0; k<le16_to_cpu(st->reallocationTableLen); k++) | 152 | for (k = 0; k < le16_to_cpu(st->reallocationTableLen); k++) { |
162 | { | 153 | if (le32_to_cpu(st->mapEntry[k].origLocation) == 0xFFFFFFFF) { |
163 | if (le32_to_cpu(st->mapEntry[k].origLocation) == 0xFFFFFFFF) | 154 | for (; j < 4; j++) { |
164 | { | 155 | if (sdata->s_spar_map[j]) { |
165 | for (; j<4; j++) | ||
166 | { | ||
167 | if (sdata->s_spar_map[j]) | ||
168 | { | ||
169 | st = (struct sparingTable *)sdata->s_spar_map[j]->b_data; | 156 | st = (struct sparingTable *)sdata->s_spar_map[j]->b_data; |
170 | st->mapEntry[k].origLocation = cpu_to_le32(packet); | 157 | st->mapEntry[k].origLocation = cpu_to_le32(packet); |
171 | udf_update_tag((char *)st, sizeof(struct sparingTable) + le16_to_cpu(st->reallocationTableLen) * sizeof(struct sparingEntry)); | 158 | udf_update_tag((char *)st, sizeof(struct sparingTable) + le16_to_cpu(st->reallocationTableLen) * sizeof(struct sparingEntry)); |
@@ -175,28 +162,23 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) | |||
175 | *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) + | 162 | *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) + |
176 | ((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1)); | 163 | ((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1)); |
177 | return 0; | 164 | return 0; |
178 | } | 165 | } else if (le32_to_cpu(st->mapEntry[k].origLocation) == packet) { |
179 | else if (le32_to_cpu(st->mapEntry[k].origLocation) == packet) | ||
180 | { | ||
181 | *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) + | 166 | *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) + |
182 | ((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1)); | 167 | ((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1)); |
183 | return 0; | 168 | return 0; |
184 | } | 169 | } else if (le32_to_cpu(st->mapEntry[k].origLocation) > packet) { |
185 | else if (le32_to_cpu(st->mapEntry[k].origLocation) > packet) | ||
186 | break; | 170 | break; |
171 | } | ||
187 | } | 172 | } |
188 | for (l=k; l<le16_to_cpu(st->reallocationTableLen); l++) | 173 | |
189 | { | 174 | for (l = k; l < le16_to_cpu(st->reallocationTableLen); l++) { |
190 | if (le32_to_cpu(st->mapEntry[l].origLocation) == 0xFFFFFFFF) | 175 | if (le32_to_cpu(st->mapEntry[l].origLocation) == 0xFFFFFFFF) { |
191 | { | 176 | for (; j < 4; j++) { |
192 | for (; j<4; j++) | 177 | if (sdata->s_spar_map[j]) { |
193 | { | ||
194 | if (sdata->s_spar_map[j]) | ||
195 | { | ||
196 | st = (struct sparingTable *)sdata->s_spar_map[j]->b_data; | 178 | st = (struct sparingTable *)sdata->s_spar_map[j]->b_data; |
197 | mapEntry = st->mapEntry[l]; | 179 | mapEntry = st->mapEntry[l]; |
198 | mapEntry.origLocation = cpu_to_le32(packet); | 180 | mapEntry.origLocation = cpu_to_le32(packet); |
199 | memmove(&st->mapEntry[k+1], &st->mapEntry[k], (l-k)*sizeof(struct sparingEntry)); | 181 | memmove(&st->mapEntry[k + 1], &st->mapEntry[k], (l - k) * sizeof(struct sparingEntry)); |
200 | st->mapEntry[k] = mapEntry; | 182 | st->mapEntry[k] = mapEntry; |
201 | udf_update_tag((char *)st, sizeof(struct sparingTable) + le16_to_cpu(st->reallocationTableLen) * sizeof(struct sparingEntry)); | 183 | udf_update_tag((char *)st, sizeof(struct sparingTable) + le16_to_cpu(st->reallocationTableLen) * sizeof(struct sparingEntry)); |
202 | mark_buffer_dirty(sdata->s_spar_map[j]); | 184 | mark_buffer_dirty(sdata->s_spar_map[j]); |
@@ -207,11 +189,12 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) | |||
207 | return 0; | 189 | return 0; |
208 | } | 190 | } |
209 | } | 191 | } |
192 | |||
210 | return 1; | 193 | return 1; |
211 | } | 194 | } /* if old_block */ |
212 | } | 195 | } |
213 | if (i == UDF_SB_NUMPARTS(sb)) | 196 | |
214 | { | 197 | if (i == UDF_SB_NUMPARTS(sb)) { |
215 | /* outside of partitions */ | 198 | /* outside of partitions */ |
216 | /* for now, fail =) */ | 199 | /* for now, fail =) */ |
217 | return 1; | 200 | return 1; |