aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/super.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/super.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/super.c')
-rw-r--r--fs/udf/super.c190
1 files changed, 177 insertions, 13 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 787cedf6cc07..29b19678327a 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -950,6 +950,101 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
950 return 0; 950 return 0;
951} 951}
952 952
953static int udf_load_metadata_files(struct super_block *sb, int partition)
954{
955 struct udf_sb_info *sbi = UDF_SB(sb);
956 struct udf_part_map *map;
957 struct udf_meta_data *mdata;
958 kernel_lb_addr addr;
959 int fe_error = 0;
960
961 map = &sbi->s_partmaps[partition];
962 mdata = &map->s_type_specific.s_metadata;
963
964 /* metadata address */
965 addr.logicalBlockNum = mdata->s_meta_file_loc;
966 addr.partitionReferenceNum = map->s_partition_num;
967
968 udf_debug("Metadata file location: block = %d part = %d\n",
969 addr.logicalBlockNum, addr.partitionReferenceNum);
970
971 mdata->s_metadata_fe = udf_iget(sb, addr);
972
973 if (mdata->s_metadata_fe == NULL) {
974 udf_warning(sb, __func__, "metadata inode efe not found, "
975 "will try mirror inode.");
976 fe_error = 1;
977 } else if (UDF_I(mdata->s_metadata_fe)->i_alloc_type !=
978 ICBTAG_FLAG_AD_SHORT) {
979 udf_warning(sb, __func__, "metadata inode efe does not have "
980 "short allocation descriptors!");
981 fe_error = 1;
982 iput(mdata->s_metadata_fe);
983 mdata->s_metadata_fe = NULL;
984 }
985
986 /* mirror file entry */
987 addr.logicalBlockNum = mdata->s_mirror_file_loc;
988 addr.partitionReferenceNum = map->s_partition_num;
989
990 udf_debug("Mirror metadata file location: block = %d part = %d\n",
991 addr.logicalBlockNum, addr.partitionReferenceNum);
992
993 mdata->s_mirror_fe = udf_iget(sb, addr);
994
995 if (mdata->s_mirror_fe == NULL) {
996 if (fe_error) {
997 udf_error(sb, __func__, "mirror inode efe not found "
998 "and metadata inode is missing too, exiting...");
999 goto error_exit;
1000 } else
1001 udf_warning(sb, __func__, "mirror inode efe not found,"
1002 " but metadata inode is OK");
1003 } else if (UDF_I(mdata->s_mirror_fe)->i_alloc_type !=
1004 ICBTAG_FLAG_AD_SHORT) {
1005 udf_warning(sb, __func__, "mirror inode efe does not have "
1006 "short allocation descriptors!");
1007 iput(mdata->s_mirror_fe);
1008 mdata->s_mirror_fe = NULL;
1009 if (fe_error)
1010 goto error_exit;
1011 }
1012
1013 /*
1014 * bitmap file entry
1015 * Note:
1016 * Load only if bitmap file location differs from 0xFFFFFFFF (DCN-5102)
1017 */
1018 if (mdata->s_bitmap_file_loc != 0xFFFFFFFF) {
1019 addr.logicalBlockNum = mdata->s_bitmap_file_loc;
1020 addr.partitionReferenceNum = map->s_partition_num;
1021
1022 udf_debug("Bitmap file location: block = %d part = %d\n",
1023 addr.logicalBlockNum, addr.partitionReferenceNum);
1024
1025 mdata->s_bitmap_fe = udf_iget(sb, addr);
1026
1027 if (mdata->s_bitmap_fe == NULL) {
1028 if (sb->s_flags & MS_RDONLY)
1029 udf_warning(sb, __func__, "bitmap inode efe "
1030 "not found but it's ok since the disc"
1031 " is mounted read-only");
1032 else {
1033 udf_error(sb, __func__, "bitmap inode efe not "
1034 "found and attempted read-write mount");
1035 goto error_exit;
1036 }
1037 }
1038 }
1039
1040 udf_debug("udf_load_metadata_files Ok\n");
1041
1042 return 0;
1043
1044error_exit:
1045 return 1;
1046}
1047
953static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, 1048static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh,
954 kernel_lb_addr *root) 1049 kernel_lb_addr *root)
955{ 1050{
@@ -1169,7 +1264,7 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block)
1169 p = (struct partitionDesc *)bh->b_data; 1264 p = (struct partitionDesc *)bh->b_data;
1170 partitionNumber = le16_to_cpu(p->partitionNumber); 1265 partitionNumber = le16_to_cpu(p->partitionNumber);
1171 1266
1172 /* First scan for TYPE1 and SPARABLE partitions */ 1267 /* First scan for TYPE1, SPARABLE and METADATA partitions */
1173 for (i = 0; i < sbi->s_partitions; i++) { 1268 for (i = 0; i < sbi->s_partitions; i++) {
1174 map = &sbi->s_partmaps[i]; 1269 map = &sbi->s_partmaps[i];
1175 udf_debug("Searching map: (%d == %d)\n", 1270 udf_debug("Searching map: (%d == %d)\n",
@@ -1189,8 +1284,8 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block)
1189 ret = udf_fill_partdesc_info(sb, p, i); 1284 ret = udf_fill_partdesc_info(sb, p, i);
1190 1285
1191 /* 1286 /*
1192 * Now rescan for VIRTUAL partitions when TYPE1 partitions are 1287 * Now rescan for VIRTUAL or METADATA partitions when SPARABLE and
1193 * already set up 1288 * PHYSICAL partitions are already set up
1194 */ 1289 */
1195 type1_idx = i; 1290 type1_idx = i;
1196 for (i = 0; i < sbi->s_partitions; i++) { 1291 for (i = 0; i < sbi->s_partitions; i++) {
@@ -1198,7 +1293,8 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block)
1198 1293
1199 if (map->s_partition_num == partitionNumber && 1294 if (map->s_partition_num == partitionNumber &&
1200 (map->s_partition_type == UDF_VIRTUAL_MAP15 || 1295 (map->s_partition_type == UDF_VIRTUAL_MAP15 ||
1201 map->s_partition_type == UDF_VIRTUAL_MAP20)) 1296 map->s_partition_type == UDF_VIRTUAL_MAP20 ||
1297 map->s_partition_type == UDF_METADATA_MAP25))
1202 break; 1298 break;
1203 } 1299 }
1204 1300
@@ -1208,16 +1304,28 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block)
1208 ret = udf_fill_partdesc_info(sb, p, i); 1304 ret = udf_fill_partdesc_info(sb, p, i);
1209 if (ret) 1305 if (ret)
1210 goto out_bh; 1306 goto out_bh;
1211 /*
1212 * Mark filesystem read-only if we have a partition with virtual map
1213 * since we don't handle writing to it (we overwrite blocks instead of
1214 * relocating them).
1215 */
1216 sb->s_flags |= MS_RDONLY;
1217 printk(KERN_NOTICE "UDF-fs: Filesystem marked read-only because "
1218 "writing to pseudooverwrite partition is not implemented.\n");
1219 1307
1220 ret = udf_load_vat(sb, i, type1_idx); 1308 if (map->s_partition_type == UDF_METADATA_MAP25) {
1309 ret = udf_load_metadata_files(sb, i);
1310 if (ret) {
1311 printk(KERN_ERR "UDF-fs: error loading MetaData "
1312 "partition map %d\n", i);
1313 goto out_bh;
1314 }
1315 } else {
1316 ret = udf_load_vat(sb, i, type1_idx);
1317 if (ret)
1318 goto out_bh;
1319 /*
1320 * Mark filesystem read-only if we have a partition with
1321 * virtual map since we don't handle writing to it (we
1322 * overwrite blocks instead of relocating them).
1323 */
1324 sb->s_flags |= MS_RDONLY;
1325 printk(KERN_NOTICE "UDF-fs: Filesystem marked read-only "
1326 "because writing to pseudooverwrite partition is "
1327 "not implemented.\n");
1328 }
1221out_bh: 1329out_bh:
1222 /* In case loading failed, we handle cleanup in udf_fill_super */ 1330 /* In case loading failed, we handle cleanup in udf_fill_super */
1223 brelse(bh); 1331 brelse(bh);
@@ -1316,6 +1424,50 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block,
1316 } 1424 }
1317 } 1425 }
1318 map->s_partition_func = udf_get_pblock_spar15; 1426 map->s_partition_func = udf_get_pblock_spar15;
1427 } else if (!strncmp(upm2->partIdent.ident,
1428 UDF_ID_METADATA,
1429 strlen(UDF_ID_METADATA))) {
1430 struct udf_meta_data *mdata =
1431 &map->s_type_specific.s_metadata;
1432 struct metadataPartitionMap *mdm =
1433 (struct metadataPartitionMap *)
1434 &(lvd->partitionMaps[offset]);
1435 udf_debug("Parsing Logical vol part %d "
1436 "type %d id=%s\n", i, type,
1437 UDF_ID_METADATA);
1438
1439 map->s_partition_type = UDF_METADATA_MAP25;
1440 map->s_partition_func = udf_get_pblock_meta25;
1441
1442 mdata->s_meta_file_loc =
1443 le32_to_cpu(mdm->metadataFileLoc);
1444 mdata->s_mirror_file_loc =
1445 le32_to_cpu(mdm->metadataMirrorFileLoc);
1446 mdata->s_bitmap_file_loc =
1447 le32_to_cpu(mdm->metadataBitmapFileLoc);
1448 mdata->s_alloc_unit_size =
1449 le32_to_cpu(mdm->allocUnitSize);
1450 mdata->s_align_unit_size =
1451 le16_to_cpu(mdm->alignUnitSize);
1452 mdata->s_dup_md_flag =
1453 mdm->flags & 0x01;
1454
1455 udf_debug("Metadata Ident suffix=0x%x\n",
1456 (le16_to_cpu(
1457 ((__le16 *)
1458 mdm->partIdent.identSuffix)[0])));
1459 udf_debug("Metadata part num=%d\n",
1460 le16_to_cpu(mdm->partitionNum));
1461 udf_debug("Metadata part alloc unit size=%d\n",
1462 le32_to_cpu(mdm->allocUnitSize));
1463 udf_debug("Metadata file loc=%d\n",
1464 le32_to_cpu(mdm->metadataFileLoc));
1465 udf_debug("Mirror file loc=%d\n",
1466 le32_to_cpu(mdm->metadataMirrorFileLoc));
1467 udf_debug("Bitmap file loc=%d\n",
1468 le32_to_cpu(mdm->metadataBitmapFileLoc));
1469 udf_debug("Duplicate Flag: %d %d\n",
1470 mdata->s_dup_md_flag, mdm->flags);
1319 } else { 1471 } else {
1320 udf_debug("Unknown ident: %s\n", 1472 udf_debug("Unknown ident: %s\n",
1321 upm2->partIdent.ident); 1473 upm2->partIdent.ident);
@@ -1677,6 +1829,7 @@ static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
1677static void udf_free_partition(struct udf_part_map *map) 1829static void udf_free_partition(struct udf_part_map *map)
1678{ 1830{
1679 int i; 1831 int i;
1832 struct udf_meta_data *mdata;
1680 1833
1681 if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) 1834 if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE)
1682 iput(map->s_uspace.s_table); 1835 iput(map->s_uspace.s_table);
@@ -1689,6 +1842,17 @@ static void udf_free_partition(struct udf_part_map *map)
1689 if (map->s_partition_type == UDF_SPARABLE_MAP15) 1842 if (map->s_partition_type == UDF_SPARABLE_MAP15)
1690 for (i = 0; i < 4; i++) 1843 for (i = 0; i < 4; i++)
1691 brelse(map->s_type_specific.s_sparing.s_spar_map[i]); 1844 brelse(map->s_type_specific.s_sparing.s_spar_map[i]);
1845 else if (map->s_partition_type == UDF_METADATA_MAP25) {
1846 mdata = &map->s_type_specific.s_metadata;
1847 iput(mdata->s_metadata_fe);
1848 mdata->s_metadata_fe = NULL;
1849
1850 iput(mdata->s_mirror_fe);
1851 mdata->s_mirror_fe = NULL;
1852
1853 iput(mdata->s_bitmap_fe);
1854 mdata->s_bitmap_fe = NULL;
1855 }
1692} 1856}
1693 1857
1694static int udf_fill_super(struct super_block *sb, void *options, int silent) 1858static int udf_fill_super(struct super_block *sb, void *options, int silent)