diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/udf/super.c | 118 |
1 files changed, 62 insertions, 56 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c index d50e3f5c46e8..c5fef85a9c15 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -1024,41 +1024,14 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) | |||
1024 | return bitmap; | 1024 | return bitmap; |
1025 | } | 1025 | } |
1026 | 1026 | ||
1027 | static int udf_load_partdesc(struct super_block *sb, sector_t block) | 1027 | static int udf_fill_partdesc_info(struct super_block *sb, |
1028 | struct partitionDesc *p, int p_index) | ||
1028 | { | 1029 | { |
1029 | struct buffer_head *bh; | ||
1030 | struct partitionHeaderDesc *phd; | ||
1031 | struct partitionDesc *p; | ||
1032 | struct udf_part_map *map; | 1030 | struct udf_part_map *map; |
1033 | struct udf_sb_info *sbi = UDF_SB(sb); | 1031 | struct udf_sb_info *sbi = UDF_SB(sb); |
1034 | bool found = false; | 1032 | struct partitionHeaderDesc *phd; |
1035 | int i; | ||
1036 | uint16_t partitionNumber; | ||
1037 | uint16_t ident; | ||
1038 | int ret = 0; | ||
1039 | |||
1040 | bh = udf_read_tagged(sb, block, block, &ident); | ||
1041 | if (!bh) | ||
1042 | return 1; | ||
1043 | if (ident != TAG_IDENT_PD) | ||
1044 | goto out_bh; | ||
1045 | |||
1046 | p = (struct partitionDesc *)bh->b_data; | ||
1047 | partitionNumber = le16_to_cpu(p->partitionNumber); | ||
1048 | for (i = 0; i < sbi->s_partitions; i++) { | ||
1049 | map = &sbi->s_partmaps[i]; | ||
1050 | udf_debug("Searching map: (%d == %d)\n", | ||
1051 | map->s_partition_num, partitionNumber); | ||
1052 | found = map->s_partition_num == partitionNumber; | ||
1053 | if (found) | ||
1054 | break; | ||
1055 | } | ||
1056 | 1033 | ||
1057 | if (!found) { | 1034 | map = &sbi->s_partmaps[p_index]; |
1058 | udf_debug("Partition (%d) not found in partition map\n", | ||
1059 | partitionNumber); | ||
1060 | goto out_bh; | ||
1061 | } | ||
1062 | 1035 | ||
1063 | map->s_partition_len = le32_to_cpu(p->partitionLength); /* blocks */ | 1036 | map->s_partition_len = le32_to_cpu(p->partitionLength); /* blocks */ |
1064 | map->s_partition_root = le32_to_cpu(p->partitionStartingLocation); | 1037 | map->s_partition_root = le32_to_cpu(p->partitionStartingLocation); |
@@ -1073,88 +1046,121 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block) | |||
1073 | map->s_partition_flags |= UDF_PART_FLAG_OVERWRITABLE; | 1046 | map->s_partition_flags |= UDF_PART_FLAG_OVERWRITABLE; |
1074 | 1047 | ||
1075 | udf_debug("Partition (%d:%d type %x) starts at physical %d, " | 1048 | udf_debug("Partition (%d:%d type %x) starts at physical %d, " |
1076 | "block length %d\n", partitionNumber, i, | 1049 | "block length %d\n", partitionNumber, p_index, |
1077 | map->s_partition_type, map->s_partition_root, | 1050 | map->s_partition_type, map->s_partition_root, |
1078 | map->s_partition_len); | 1051 | map->s_partition_len); |
1079 | 1052 | ||
1080 | if (strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) && | 1053 | if (strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) && |
1081 | strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03)) | 1054 | strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03)) |
1082 | goto out_bh; | 1055 | return 0; |
1083 | 1056 | ||
1084 | phd = (struct partitionHeaderDesc *)p->partitionContentsUse; | 1057 | phd = (struct partitionHeaderDesc *)p->partitionContentsUse; |
1085 | if (phd->unallocSpaceTable.extLength) { | 1058 | if (phd->unallocSpaceTable.extLength) { |
1086 | kernel_lb_addr loc = { | 1059 | kernel_lb_addr loc = { |
1087 | .logicalBlockNum = le32_to_cpu( | 1060 | .logicalBlockNum = le32_to_cpu( |
1088 | phd->unallocSpaceTable.extPosition), | 1061 | phd->unallocSpaceTable.extPosition), |
1089 | .partitionReferenceNum = i, | 1062 | .partitionReferenceNum = p_index, |
1090 | }; | 1063 | }; |
1091 | 1064 | ||
1092 | map->s_uspace.s_table = udf_iget(sb, loc); | 1065 | map->s_uspace.s_table = udf_iget(sb, loc); |
1093 | if (!map->s_uspace.s_table) { | 1066 | if (!map->s_uspace.s_table) { |
1094 | udf_debug("cannot load unallocSpaceTable (part %d)\n", | 1067 | udf_debug("cannot load unallocSpaceTable (part %d)\n", |
1095 | i); | 1068 | p_index); |
1096 | ret = 1; | 1069 | return 1; |
1097 | goto out_bh; | ||
1098 | } | 1070 | } |
1099 | map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_TABLE; | 1071 | map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_TABLE; |
1100 | udf_debug("unallocSpaceTable (part %d) @ %ld\n", | 1072 | udf_debug("unallocSpaceTable (part %d) @ %ld\n", |
1101 | i, map->s_uspace.s_table->i_ino); | 1073 | p_index, map->s_uspace.s_table->i_ino); |
1102 | } | 1074 | } |
1103 | 1075 | ||
1104 | if (phd->unallocSpaceBitmap.extLength) { | 1076 | if (phd->unallocSpaceBitmap.extLength) { |
1105 | struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, i); | 1077 | struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index); |
1106 | if (!bitmap) { | 1078 | if (!bitmap) |
1107 | ret = 1; | 1079 | return 1; |
1108 | goto out_bh; | ||
1109 | } | ||
1110 | map->s_uspace.s_bitmap = bitmap; | 1080 | map->s_uspace.s_bitmap = bitmap; |
1111 | bitmap->s_extLength = le32_to_cpu( | 1081 | bitmap->s_extLength = le32_to_cpu( |
1112 | phd->unallocSpaceBitmap.extLength); | 1082 | phd->unallocSpaceBitmap.extLength); |
1113 | bitmap->s_extPosition = le32_to_cpu( | 1083 | bitmap->s_extPosition = le32_to_cpu( |
1114 | phd->unallocSpaceBitmap.extPosition); | 1084 | phd->unallocSpaceBitmap.extPosition); |
1115 | map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP; | 1085 | map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP; |
1116 | udf_debug("unallocSpaceBitmap (part %d) @ %d\n", i, | 1086 | udf_debug("unallocSpaceBitmap (part %d) @ %d\n", p_index, |
1117 | bitmap->s_extPosition); | 1087 | bitmap->s_extPosition); |
1118 | } | 1088 | } |
1119 | 1089 | ||
1120 | if (phd->partitionIntegrityTable.extLength) | 1090 | if (phd->partitionIntegrityTable.extLength) |
1121 | udf_debug("partitionIntegrityTable (part %d)\n", i); | 1091 | udf_debug("partitionIntegrityTable (part %d)\n", p_index); |
1122 | 1092 | ||
1123 | if (phd->freedSpaceTable.extLength) { | 1093 | if (phd->freedSpaceTable.extLength) { |
1124 | kernel_lb_addr loc = { | 1094 | kernel_lb_addr loc = { |
1125 | .logicalBlockNum = le32_to_cpu( | 1095 | .logicalBlockNum = le32_to_cpu( |
1126 | phd->freedSpaceTable.extPosition), | 1096 | phd->freedSpaceTable.extPosition), |
1127 | .partitionReferenceNum = i, | 1097 | .partitionReferenceNum = p_index, |
1128 | }; | 1098 | }; |
1129 | 1099 | ||
1130 | map->s_fspace.s_table = udf_iget(sb, loc); | 1100 | map->s_fspace.s_table = udf_iget(sb, loc); |
1131 | if (!map->s_fspace.s_table) { | 1101 | if (!map->s_fspace.s_table) { |
1132 | udf_debug("cannot load freedSpaceTable (part %d)\n", i); | 1102 | udf_debug("cannot load freedSpaceTable (part %d)\n", |
1133 | ret = 1; | 1103 | p_index); |
1134 | goto out_bh; | 1104 | return 1; |
1135 | } | 1105 | } |
1136 | 1106 | ||
1137 | map->s_partition_flags |= UDF_PART_FLAG_FREED_TABLE; | 1107 | map->s_partition_flags |= UDF_PART_FLAG_FREED_TABLE; |
1138 | udf_debug("freedSpaceTable (part %d) @ %ld\n", | 1108 | udf_debug("freedSpaceTable (part %d) @ %ld\n", |
1139 | i, map->s_fspace.s_table->i_ino); | 1109 | p_index, map->s_fspace.s_table->i_ino); |
1140 | } | 1110 | } |
1141 | 1111 | ||
1142 | if (phd->freedSpaceBitmap.extLength) { | 1112 | if (phd->freedSpaceBitmap.extLength) { |
1143 | struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, i); | 1113 | struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index); |
1144 | if (!bitmap) { | 1114 | if (!bitmap) |
1145 | ret = 1; | 1115 | return 1; |
1146 | goto out_bh; | ||
1147 | } | ||
1148 | map->s_fspace.s_bitmap = bitmap; | 1116 | map->s_fspace.s_bitmap = bitmap; |
1149 | bitmap->s_extLength = le32_to_cpu( | 1117 | bitmap->s_extLength = le32_to_cpu( |
1150 | phd->freedSpaceBitmap.extLength); | 1118 | phd->freedSpaceBitmap.extLength); |
1151 | bitmap->s_extPosition = le32_to_cpu( | 1119 | bitmap->s_extPosition = le32_to_cpu( |
1152 | phd->freedSpaceBitmap.extPosition); | 1120 | phd->freedSpaceBitmap.extPosition); |
1153 | map->s_partition_flags |= UDF_PART_FLAG_FREED_BITMAP; | 1121 | map->s_partition_flags |= UDF_PART_FLAG_FREED_BITMAP; |
1154 | udf_debug("freedSpaceBitmap (part %d) @ %d\n", i, | 1122 | udf_debug("freedSpaceBitmap (part %d) @ %d\n", p_index, |
1155 | bitmap->s_extPosition); | 1123 | bitmap->s_extPosition); |
1156 | } | 1124 | } |
1125 | return 0; | ||
1126 | } | ||
1127 | |||
1128 | static int udf_load_partdesc(struct super_block *sb, sector_t block) | ||
1129 | { | ||
1130 | struct buffer_head *bh; | ||
1131 | struct partitionDesc *p; | ||
1132 | struct udf_part_map *map; | ||
1133 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
1134 | bool found = false; | ||
1135 | int i; | ||
1136 | uint16_t partitionNumber; | ||
1137 | uint16_t ident; | ||
1138 | int ret = 0; | ||
1139 | |||
1140 | bh = udf_read_tagged(sb, block, block, &ident); | ||
1141 | if (!bh) | ||
1142 | return 1; | ||
1143 | if (ident != TAG_IDENT_PD) | ||
1144 | goto out_bh; | ||
1145 | |||
1146 | p = (struct partitionDesc *)bh->b_data; | ||
1147 | partitionNumber = le16_to_cpu(p->partitionNumber); | ||
1148 | for (i = 0; i < sbi->s_partitions; i++) { | ||
1149 | map = &sbi->s_partmaps[i]; | ||
1150 | udf_debug("Searching map: (%d == %d)\n", | ||
1151 | map->s_partition_num, partitionNumber); | ||
1152 | found = map->s_partition_num == partitionNumber; | ||
1153 | if (found) | ||
1154 | break; | ||
1155 | } | ||
1156 | |||
1157 | if (!found) { | ||
1158 | udf_debug("Partition (%d) not found in partition map\n", | ||
1159 | partitionNumber); | ||
1160 | goto out_bh; | ||
1161 | } | ||
1157 | 1162 | ||
1163 | ret = udf_fill_partdesc_info(sb, p, i); | ||
1158 | out_bh: | 1164 | out_bh: |
1159 | /* In case loading failed, we handle cleanup in udf_fill_super */ | 1165 | /* In case loading failed, we handle cleanup in udf_fill_super */ |
1160 | brelse(bh); | 1166 | brelse(bh); |