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.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/fs/udf/partition.c b/fs/udf/partition.c
index b2e6e1eddb90..2dfe4be2eeb2 100644
--- a/fs/udf/partition.c
+++ b/fs/udf/partition.c
@@ -266,3 +266,58 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
266 266
267 return 0; 267 return 0;
268} 268}
269
270static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block,
271 uint16_t partition, uint32_t offset)
272{
273 struct super_block *sb = inode->i_sb;
274 struct udf_part_map *map;
275 kernel_lb_addr eloc;
276 uint32_t elen;
277 sector_t ext_offset;
278 struct extent_position epos = {};
279 uint32_t phyblock;
280
281 if (inode_bmap(inode, block, &epos, &eloc, &elen, &ext_offset) !=
282 (EXT_RECORDED_ALLOCATED >> 30))
283 phyblock = 0xFFFFFFFF;
284 else {
285 map = &UDF_SB(sb)->s_partmaps[partition];
286 /* map to sparable/physical partition desc */
287 phyblock = udf_get_pblock(sb, eloc.logicalBlockNum,
288 map->s_partition_num, ext_offset + offset);
289 }
290
291 brelse(epos.bh);
292 return phyblock;
293}
294
295uint32_t udf_get_pblock_meta25(struct super_block *sb, uint32_t block,
296 uint16_t partition, uint32_t offset)
297{
298 struct udf_sb_info *sbi = UDF_SB(sb);
299 struct udf_part_map *map;
300 struct udf_meta_data *mdata;
301 uint32_t retblk;
302 struct inode *inode;
303
304 udf_debug("READING from METADATA\n");
305
306 map = &sbi->s_partmaps[partition];
307 mdata = &map->s_type_specific.s_metadata;
308 inode = mdata->s_metadata_fe ? : mdata->s_mirror_fe;
309
310 /* We shouldn't mount such media... */
311 BUG_ON(!inode);
312 retblk = udf_try_read_meta(inode, block, partition, offset);
313 if (retblk == 0xFFFFFFFF) {
314 udf_warning(sb, __func__, "error reading from METADATA, "
315 "trying to read from MIRROR");
316 inode = mdata->s_mirror_fe;
317 if (!inode)
318 return 0xFFFFFFFF;
319 retblk = udf_try_read_meta(inode, block, partition, offset);
320 }
321
322 return retblk;
323}