diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/udf/partition.c | 8 | ||||
-rw-r--r-- | fs/udf/super.c | 68 | ||||
-rw-r--r-- | fs/udf/udf_sb.h | 1 | ||||
-rw-r--r-- | fs/udf/udfdecl.h | 2 |
4 files changed, 43 insertions, 36 deletions
diff --git a/fs/udf/partition.c b/fs/udf/partition.c index f3e472c67709..b526f25c04c9 100644 --- a/fs/udf/partition.c +++ b/fs/udf/partition.c | |||
@@ -321,8 +321,14 @@ uint32_t udf_get_pblock_meta25(struct super_block *sb, uint32_t block, | |||
321 | /* We shouldn't mount such media... */ | 321 | /* We shouldn't mount such media... */ |
322 | BUG_ON(!inode); | 322 | BUG_ON(!inode); |
323 | retblk = udf_try_read_meta(inode, block, partition, offset); | 323 | retblk = udf_try_read_meta(inode, block, partition, offset); |
324 | if (retblk == 0xFFFFFFFF) { | 324 | if (retblk == 0xFFFFFFFF && mdata->s_metadata_fe) { |
325 | udf_warn(sb, "error reading from METADATA, trying to read from MIRROR\n"); | 325 | udf_warn(sb, "error reading from METADATA, trying to read from MIRROR\n"); |
326 | if (!mdata->s_mirror_loaded_flag) { | ||
327 | mdata->s_mirror_fe = udf_find_metadata_inode_efe(sb, | ||
328 | mdata->s_mirror_file_loc, map->s_partition_num); | ||
329 | mdata->s_mirror_loaded_flag = 1; | ||
330 | } | ||
331 | |||
326 | inode = mdata->s_mirror_fe; | 332 | inode = mdata->s_mirror_fe; |
327 | if (!inode) | 333 | if (!inode) |
328 | return 0xFFFFFFFF; | 334 | return 0xFFFFFFFF; |
diff --git a/fs/udf/super.c b/fs/udf/super.c index e58123ad75ba..dfe043a36593 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -826,59 +826,57 @@ out1: | |||
826 | return ret; | 826 | return ret; |
827 | } | 827 | } |
828 | 828 | ||
829 | struct inode *udf_find_metadata_inode_efe(struct super_block *sb, | ||
830 | u32 meta_file_loc, u32 partition_num) | ||
831 | { | ||
832 | struct kernel_lb_addr addr; | ||
833 | struct inode *metadata_fe; | ||
834 | |||
835 | addr.logicalBlockNum = meta_file_loc; | ||
836 | addr.partitionReferenceNum = partition_num; | ||
837 | |||
838 | metadata_fe = udf_iget(sb, &addr); | ||
839 | |||
840 | if (metadata_fe == NULL) | ||
841 | udf_warn(sb, "metadata inode efe not found\n"); | ||
842 | else if (UDF_I(metadata_fe)->i_alloc_type != ICBTAG_FLAG_AD_SHORT) { | ||
843 | udf_warn(sb, "metadata inode efe does not have short allocation descriptors!\n"); | ||
844 | iput(metadata_fe); | ||
845 | metadata_fe = NULL; | ||
846 | } | ||
847 | |||
848 | return metadata_fe; | ||
849 | } | ||
850 | |||
829 | static int udf_load_metadata_files(struct super_block *sb, int partition) | 851 | static int udf_load_metadata_files(struct super_block *sb, int partition) |
830 | { | 852 | { |
831 | struct udf_sb_info *sbi = UDF_SB(sb); | 853 | struct udf_sb_info *sbi = UDF_SB(sb); |
832 | struct udf_part_map *map; | 854 | struct udf_part_map *map; |
833 | struct udf_meta_data *mdata; | 855 | struct udf_meta_data *mdata; |
834 | struct kernel_lb_addr addr; | 856 | struct kernel_lb_addr addr; |
835 | int fe_error = 0; | ||
836 | 857 | ||
837 | map = &sbi->s_partmaps[partition]; | 858 | map = &sbi->s_partmaps[partition]; |
838 | mdata = &map->s_type_specific.s_metadata; | 859 | mdata = &map->s_type_specific.s_metadata; |
839 | 860 | ||
840 | /* metadata address */ | 861 | /* metadata address */ |
841 | addr.logicalBlockNum = mdata->s_meta_file_loc; | ||
842 | addr.partitionReferenceNum = map->s_partition_num; | ||
843 | |||
844 | udf_debug("Metadata file location: block = %d part = %d\n", | 862 | udf_debug("Metadata file location: block = %d part = %d\n", |
845 | addr.logicalBlockNum, addr.partitionReferenceNum); | 863 | mdata->s_meta_file_loc, map->s_partition_num); |
846 | 864 | ||
847 | mdata->s_metadata_fe = udf_iget(sb, &addr); | 865 | mdata->s_metadata_fe = udf_find_metadata_inode_efe(sb, |
866 | mdata->s_meta_file_loc, map->s_partition_num); | ||
848 | 867 | ||
849 | if (mdata->s_metadata_fe == NULL) { | 868 | if (mdata->s_metadata_fe == NULL) { |
850 | udf_warn(sb, "metadata inode efe not found, will try mirror inode\n"); | 869 | /* mirror file entry */ |
851 | fe_error = 1; | 870 | udf_debug("Mirror metadata file location: block = %d part = %d\n", |
852 | } else if (UDF_I(mdata->s_metadata_fe)->i_alloc_type != | 871 | mdata->s_mirror_file_loc, map->s_partition_num); |
853 | ICBTAG_FLAG_AD_SHORT) { | ||
854 | udf_warn(sb, "metadata inode efe does not have short allocation descriptors!\n"); | ||
855 | fe_error = 1; | ||
856 | iput(mdata->s_metadata_fe); | ||
857 | mdata->s_metadata_fe = NULL; | ||
858 | } | ||
859 | |||
860 | /* mirror file entry */ | ||
861 | addr.logicalBlockNum = mdata->s_mirror_file_loc; | ||
862 | addr.partitionReferenceNum = map->s_partition_num; | ||
863 | 872 | ||
864 | udf_debug("Mirror metadata file location: block = %d part = %d\n", | 873 | mdata->s_mirror_fe = udf_find_metadata_inode_efe(sb, |
865 | addr.logicalBlockNum, addr.partitionReferenceNum); | 874 | mdata->s_mirror_file_loc, map->s_partition_num); |
866 | 875 | ||
867 | mdata->s_mirror_fe = udf_iget(sb, &addr); | 876 | if (mdata->s_mirror_fe == NULL) { |
868 | 877 | udf_err(sb, "Both metadata and mirror metadata inode efe can not found\n"); | |
869 | if (mdata->s_mirror_fe == NULL) { | ||
870 | if (fe_error) { | ||
871 | udf_err(sb, "mirror inode efe not found and metadata inode is missing too, exiting...\n"); | ||
872 | goto error_exit; | ||
873 | } else | ||
874 | udf_warn(sb, "mirror inode efe not found, but metadata inode is OK\n"); | ||
875 | } else if (UDF_I(mdata->s_mirror_fe)->i_alloc_type != | ||
876 | ICBTAG_FLAG_AD_SHORT) { | ||
877 | udf_warn(sb, "mirror inode efe does not have short allocation descriptors!\n"); | ||
878 | iput(mdata->s_mirror_fe); | ||
879 | mdata->s_mirror_fe = NULL; | ||
880 | if (fe_error) | ||
881 | goto error_exit; | 878 | goto error_exit; |
879 | } | ||
882 | } | 880 | } |
883 | 881 | ||
884 | /* | 882 | /* |
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index 4858c191242b..a3146b05feeb 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h | |||
@@ -61,6 +61,7 @@ struct udf_meta_data { | |||
61 | __u32 s_alloc_unit_size; | 61 | __u32 s_alloc_unit_size; |
62 | __u16 s_align_unit_size; | 62 | __u16 s_align_unit_size; |
63 | __u8 s_dup_md_flag; | 63 | __u8 s_dup_md_flag; |
64 | __u8 s_mirror_loaded_flag; | ||
64 | struct inode *s_metadata_fe; | 65 | struct inode *s_metadata_fe; |
65 | struct inode *s_mirror_fe; | 66 | struct inode *s_mirror_fe; |
66 | struct inode *s_bitmap_fe; | 67 | struct inode *s_bitmap_fe; |
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index f3d449867301..79aae3fe7b55 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -135,6 +135,8 @@ static inline void udf_updated_lvid(struct super_block *sb) | |||
135 | UDF_SB(sb)->s_lvid_dirty = 1; | 135 | UDF_SB(sb)->s_lvid_dirty = 1; |
136 | } | 136 | } |
137 | extern u64 lvid_get_unique_id(struct super_block *sb); | 137 | extern u64 lvid_get_unique_id(struct super_block *sb); |
138 | struct inode *udf_find_metadata_inode_efe(struct super_block *sb, | ||
139 | u32 meta_file_loc, u32 partition_num); | ||
138 | 140 | ||
139 | /* namei.c */ | 141 | /* namei.c */ |
140 | extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, | 142 | extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, |