diff options
author | Jan Kara <jack@suse.cz> | 2008-04-01 12:08:51 -0400 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2008-04-17 08:23:04 -0400 |
commit | 2e0838fd0c0b8f0753a4be9af9f9712c4be881e1 (patch) | |
tree | eacb67341a7b352bd8c29e9b36179e61a8002291 /fs/udf/super.c | |
parent | c0eb31ed130ab18e1858179a644e39aee2355a13 (diff) |
udf: Improve error recovery on mount
Report error when we fail to allocate memory for a bitmap and properly
release allocated memory and inodes for all the partitions in case of
mount failure and umount.
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/udf/super.c')
-rw-r--r-- | fs/udf/super.c | 86 |
1 files changed, 42 insertions, 44 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c index 500d1e4cc1c7..d50e3f5c46e8 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -1103,16 +1103,18 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block) | |||
1103 | 1103 | ||
1104 | if (phd->unallocSpaceBitmap.extLength) { | 1104 | if (phd->unallocSpaceBitmap.extLength) { |
1105 | struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, i); | 1105 | struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, i); |
1106 | if (!bitmap) { | ||
1107 | ret = 1; | ||
1108 | goto out_bh; | ||
1109 | } | ||
1106 | map->s_uspace.s_bitmap = bitmap; | 1110 | map->s_uspace.s_bitmap = bitmap; |
1107 | if (bitmap != NULL) { | 1111 | bitmap->s_extLength = le32_to_cpu( |
1108 | bitmap->s_extLength = le32_to_cpu( | ||
1109 | phd->unallocSpaceBitmap.extLength); | 1112 | phd->unallocSpaceBitmap.extLength); |
1110 | bitmap->s_extPosition = le32_to_cpu( | 1113 | bitmap->s_extPosition = le32_to_cpu( |
1111 | phd->unallocSpaceBitmap.extPosition); | 1114 | phd->unallocSpaceBitmap.extPosition); |
1112 | map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP; | 1115 | map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP; |
1113 | udf_debug("unallocSpaceBitmap (part %d) @ %d\n", | 1116 | udf_debug("unallocSpaceBitmap (part %d) @ %d\n", i, |
1114 | i, bitmap->s_extPosition); | 1117 | bitmap->s_extPosition); |
1115 | } | ||
1116 | } | 1118 | } |
1117 | 1119 | ||
1118 | if (phd->partitionIntegrityTable.extLength) | 1120 | if (phd->partitionIntegrityTable.extLength) |
@@ -1139,19 +1141,22 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block) | |||
1139 | 1141 | ||
1140 | if (phd->freedSpaceBitmap.extLength) { | 1142 | if (phd->freedSpaceBitmap.extLength) { |
1141 | struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, i); | 1143 | struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, i); |
1144 | if (!bitmap) { | ||
1145 | ret = 1; | ||
1146 | goto out_bh; | ||
1147 | } | ||
1142 | map->s_fspace.s_bitmap = bitmap; | 1148 | map->s_fspace.s_bitmap = bitmap; |
1143 | if (bitmap != NULL) { | 1149 | bitmap->s_extLength = le32_to_cpu( |
1144 | bitmap->s_extLength = le32_to_cpu( | ||
1145 | phd->freedSpaceBitmap.extLength); | 1150 | phd->freedSpaceBitmap.extLength); |
1146 | bitmap->s_extPosition = le32_to_cpu( | 1151 | bitmap->s_extPosition = le32_to_cpu( |
1147 | phd->freedSpaceBitmap.extPosition); | 1152 | phd->freedSpaceBitmap.extPosition); |
1148 | map->s_partition_flags |= UDF_PART_FLAG_FREED_BITMAP; | 1153 | map->s_partition_flags |= UDF_PART_FLAG_FREED_BITMAP; |
1149 | udf_debug("freedSpaceBitmap (part %d) @ %d\n", | 1154 | udf_debug("freedSpaceBitmap (part %d) @ %d\n", i, |
1150 | i, bitmap->s_extPosition); | 1155 | bitmap->s_extPosition); |
1151 | } | ||
1152 | } | 1156 | } |
1153 | 1157 | ||
1154 | out_bh: | 1158 | out_bh: |
1159 | /* In case loading failed, we handle cleanup in udf_fill_super */ | ||
1155 | brelse(bh); | 1160 | brelse(bh); |
1156 | return ret; | 1161 | return ret; |
1157 | } | 1162 | } |
@@ -1677,6 +1682,23 @@ static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) | |||
1677 | vfree(bitmap); | 1682 | vfree(bitmap); |
1678 | } | 1683 | } |
1679 | 1684 | ||
1685 | static void udf_free_partition(struct udf_part_map *map) | ||
1686 | { | ||
1687 | int i; | ||
1688 | |||
1689 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) | ||
1690 | iput(map->s_uspace.s_table); | ||
1691 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) | ||
1692 | iput(map->s_fspace.s_table); | ||
1693 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) | ||
1694 | udf_sb_free_bitmap(map->s_uspace.s_bitmap); | ||
1695 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) | ||
1696 | udf_sb_free_bitmap(map->s_fspace.s_bitmap); | ||
1697 | if (map->s_partition_type == UDF_SPARABLE_MAP15) | ||
1698 | for (i = 0; i < 4; i++) | ||
1699 | brelse(map->s_type_specific.s_sparing.s_spar_map[i]); | ||
1700 | } | ||
1701 | |||
1680 | static int udf_fill_super(struct super_block *sb, void *options, int silent) | 1702 | static int udf_fill_super(struct super_block *sb, void *options, int silent) |
1681 | { | 1703 | { |
1682 | int i; | 1704 | int i; |
@@ -1846,21 +1868,9 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1846 | error_out: | 1868 | error_out: |
1847 | if (sbi->s_vat_inode) | 1869 | if (sbi->s_vat_inode) |
1848 | iput(sbi->s_vat_inode); | 1870 | iput(sbi->s_vat_inode); |
1849 | if (sbi->s_partitions) { | 1871 | if (sbi->s_partitions) |
1850 | struct udf_part_map *map = &sbi->s_partmaps[sbi->s_partition]; | 1872 | for (i = 0; i < sbi->s_partitions; i++) |
1851 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) | 1873 | udf_free_partition(&sbi->s_partmaps[i]); |
1852 | iput(map->s_uspace.s_table); | ||
1853 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) | ||
1854 | iput(map->s_fspace.s_table); | ||
1855 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) | ||
1856 | udf_sb_free_bitmap(map->s_uspace.s_bitmap); | ||
1857 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) | ||
1858 | udf_sb_free_bitmap(map->s_fspace.s_bitmap); | ||
1859 | if (map->s_partition_type == UDF_SPARABLE_MAP15) | ||
1860 | for (i = 0; i < 4; i++) | ||
1861 | brelse(map->s_type_specific.s_sparing. | ||
1862 | s_spar_map[i]); | ||
1863 | } | ||
1864 | #ifdef CONFIG_UDF_NLS | 1874 | #ifdef CONFIG_UDF_NLS |
1865 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) | 1875 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) |
1866 | unload_nls(sbi->s_nls_map); | 1876 | unload_nls(sbi->s_nls_map); |
@@ -1912,21 +1922,9 @@ static void udf_put_super(struct super_block *sb) | |||
1912 | sbi = UDF_SB(sb); | 1922 | sbi = UDF_SB(sb); |
1913 | if (sbi->s_vat_inode) | 1923 | if (sbi->s_vat_inode) |
1914 | iput(sbi->s_vat_inode); | 1924 | iput(sbi->s_vat_inode); |
1915 | if (sbi->s_partitions) { | 1925 | if (sbi->s_partitions) |
1916 | struct udf_part_map *map = &sbi->s_partmaps[sbi->s_partition]; | 1926 | for (i = 0; i < sbi->s_partitions; i++) |
1917 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) | 1927 | udf_free_partition(&sbi->s_partmaps[i]); |
1918 | iput(map->s_uspace.s_table); | ||
1919 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) | ||
1920 | iput(map->s_fspace.s_table); | ||
1921 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) | ||
1922 | udf_sb_free_bitmap(map->s_uspace.s_bitmap); | ||
1923 | if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) | ||
1924 | udf_sb_free_bitmap(map->s_fspace.s_bitmap); | ||
1925 | if (map->s_partition_type == UDF_SPARABLE_MAP15) | ||
1926 | for (i = 0; i < 4; i++) | ||
1927 | brelse(map->s_type_specific.s_sparing. | ||
1928 | s_spar_map[i]); | ||
1929 | } | ||
1930 | #ifdef CONFIG_UDF_NLS | 1928 | #ifdef CONFIG_UDF_NLS |
1931 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) | 1929 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) |
1932 | unload_nls(sbi->s_nls_map); | 1930 | unload_nls(sbi->s_nls_map); |