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.c67
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 @@
31inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, 31inline 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
45uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, 48uint32_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
98uint32_t udf_get_pblock_spar15(struct super_block * sb, uint32_t block, 104uint32_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
128int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) 139int 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;