aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/partition.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2008-04-08 14:37:21 -0400
committerJan Kara <jack@suse.cz>2008-04-17 08:29:36 -0400
commitbfb257a5981af805a9394f00f75d3d9f7b611cc0 (patch)
tree2f91577f4c2a706ece3553372c737daf05885375 /fs/udf/partition.c
parentf4bcbbd92ebda971f7c2cd1132b399808ed6cf9b (diff)
udf: Add read-only support for 2.50 UDF media
This patch implements parsing of metadata partitions and reading of Metadata File thus allowing to read UDF 2.50 media. Error resilience is implemented through accessing the Metadata Mirror File in case the data the Metadata File cannot be read. The patch is based on the original patch by Sebastian Manciulea <manciuleas@yahoo.com> and Mircea Fedoreanu <mirceaf_spl@yahoo.com>. Signed-off-by: Sebastian Manciulea <manciuleas@yahoo.com> Signed-off-by: Mircea Fedoreanu <mirceaf_spl@yahoo.com> Signed-off-by: Jan Kara <jack@suse.cz>
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}