aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2008-04-01 12:08:51 -0400
committerJan Kara <jack@suse.cz>2008-04-17 08:23:04 -0400
commit2e0838fd0c0b8f0753a4be9af9f9712c4be881e1 (patch)
treeeacb67341a7b352bd8c29e9b36179e61a8002291 /fs
parentc0eb31ed130ab18e1858179a644e39aee2355a13 (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')
-rw-r--r--fs/udf/super.c86
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
1154out_bh: 1158out_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
1685static 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
1680static int udf_fill_super(struct super_block *sb, void *options, int silent) 1702static 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)
1846error_out: 1868error_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);