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