aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf')
-rw-r--r--fs/udf/inode.c9
-rw-r--r--fs/udf/partition.c55
-rw-r--r--fs/udf/super.c190
-rw-r--r--fs/udf/udf_sb.h16
-rw-r--r--fs/udf/udfdecl.h2
5 files changed, 258 insertions, 14 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index c150b6df6261..6e151f170c08 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1301,6 +1301,15 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
1301 inode->i_op = &page_symlink_inode_operations; 1301 inode->i_op = &page_symlink_inode_operations;
1302 inode->i_mode = S_IFLNK | S_IRWXUGO; 1302 inode->i_mode = S_IFLNK | S_IRWXUGO;
1303 break; 1303 break;
1304 case ICBTAG_FILE_TYPE_MAIN:
1305 udf_debug("METADATA FILE-----\n");
1306 break;
1307 case ICBTAG_FILE_TYPE_MIRROR:
1308 udf_debug("METADATA MIRROR FILE-----\n");
1309 break;
1310 case ICBTAG_FILE_TYPE_BITMAP:
1311 udf_debug("METADATA BITMAP FILE-----\n");
1312 break;
1304 default: 1313 default:
1305 printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown " 1314 printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown "
1306 "file type=%d\n", inode->i_ino, 1315 "file type=%d\n", inode->i_ino,
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}
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)
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
index 8308a12e1232..1c1c514a9725 100644
--- a/fs/udf/udf_sb.h
+++ b/fs/udf/udf_sb.h
@@ -6,7 +6,7 @@
6/* Since UDF 2.01 is ISO 13346 based... */ 6/* Since UDF 2.01 is ISO 13346 based... */
7#define UDF_SUPER_MAGIC 0x15013346 7#define UDF_SUPER_MAGIC 0x15013346
8 8
9#define UDF_MAX_READ_VERSION 0x0201 9#define UDF_MAX_READ_VERSION 0x0250
10#define UDF_MAX_WRITE_VERSION 0x0201 10#define UDF_MAX_WRITE_VERSION 0x0201
11 11
12#define UDF_FLAG_USE_EXTENDED_FE 0 12#define UDF_FLAG_USE_EXTENDED_FE 0
@@ -46,9 +46,22 @@
46#define UDF_VIRTUAL_MAP15 0x1512U 46#define UDF_VIRTUAL_MAP15 0x1512U
47#define UDF_VIRTUAL_MAP20 0x2012U 47#define UDF_VIRTUAL_MAP20 0x2012U
48#define UDF_SPARABLE_MAP15 0x1522U 48#define UDF_SPARABLE_MAP15 0x1522U
49#define UDF_METADATA_MAP25 0x2511U
49 50
50#pragma pack(1) /* XXX(hch): Why? This file just defines in-core structures */ 51#pragma pack(1) /* XXX(hch): Why? This file just defines in-core structures */
51 52
53struct udf_meta_data {
54 __u32 s_meta_file_loc;
55 __u32 s_mirror_file_loc;
56 __u32 s_bitmap_file_loc;
57 __u32 s_alloc_unit_size;
58 __u16 s_align_unit_size;
59 __u8 s_dup_md_flag;
60 struct inode *s_metadata_fe;
61 struct inode *s_mirror_fe;
62 struct inode *s_bitmap_fe;
63};
64
52struct udf_sparing_data { 65struct udf_sparing_data {
53 __u16 s_packet_len; 66 __u16 s_packet_len;
54 struct buffer_head *s_spar_map[4]; 67 struct buffer_head *s_spar_map[4];
@@ -82,6 +95,7 @@ struct udf_part_map {
82 union { 95 union {
83 struct udf_sparing_data s_sparing; 96 struct udf_sparing_data s_sparing;
84 struct udf_virtual_data s_virtual; 97 struct udf_virtual_data s_virtual;
98 struct udf_meta_data s_metadata;
85 } s_type_specific; 99 } s_type_specific;
86 __u32 (*s_partition_func)(struct super_block *, __u32, __u16, __u32); 100 __u32 (*s_partition_func)(struct super_block *, __u32, __u16, __u32);
87 __u16 s_volumeseqnum; 101 __u16 s_volumeseqnum;
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index 2cb2f5de4245..30f664ab0cd9 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -177,6 +177,8 @@ extern uint32_t udf_get_pblock_virt20(struct super_block *, uint32_t, uint16_t,
177 uint32_t); 177 uint32_t);
178extern uint32_t udf_get_pblock_spar15(struct super_block *, uint32_t, uint16_t, 178extern uint32_t udf_get_pblock_spar15(struct super_block *, uint32_t, uint16_t,
179 uint32_t); 179 uint32_t);
180extern uint32_t udf_get_pblock_meta25(struct super_block *, uint32_t, uint16_t,
181 uint32_t);
180extern int udf_relocate_blocks(struct super_block *, long, long *); 182extern int udf_relocate_blocks(struct super_block *, long, long *);
181 183
182/* unicode.c */ 184/* unicode.c */