diff options
Diffstat (limited to 'fs/udf/partition.c')
-rw-r--r-- | fs/udf/partition.c | 55 |
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 | |||
270 | static 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 | |||
295 | uint32_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 | } | ||