|
@@ -252,6 +252,63 @@ static int udf_sb_alloc_partition_maps(struct super_block *sb, u32 count)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ int nr_groups = bitmap->s_nr_groups;
|
|
|
+ int size = sizeof(struct udf_bitmap) + (sizeof(struct buffer_head *) *
|
|
|
+ nr_groups);
|
|
|
+
|
|
|
+ for (i = 0; i < nr_groups; i++)
|
|
|
+ if (bitmap->s_block_bitmap[i])
|
|
|
+ brelse(bitmap->s_block_bitmap[i]);
|
|
|
+
|
|
|
+ if (size <= PAGE_SIZE)
|
|
|
+ kfree(bitmap);
|
|
|
+ else
|
|
|
+ vfree(bitmap);
|
|
|
+}
|
|
|
+
|
|
|
+static void udf_free_partition(struct udf_part_map *map)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ struct udf_meta_data *mdata;
|
|
|
+
|
|
|
+ if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE)
|
|
|
+ iput(map->s_uspace.s_table);
|
|
|
+ if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE)
|
|
|
+ iput(map->s_fspace.s_table);
|
|
|
+ if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP)
|
|
|
+ udf_sb_free_bitmap(map->s_uspace.s_bitmap);
|
|
|
+ if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP)
|
|
|
+ udf_sb_free_bitmap(map->s_fspace.s_bitmap);
|
|
|
+ if (map->s_partition_type == UDF_SPARABLE_MAP15)
|
|
|
+ for (i = 0; i < 4; i++)
|
|
|
+ brelse(map->s_type_specific.s_sparing.s_spar_map[i]);
|
|
|
+ else if (map->s_partition_type == UDF_METADATA_MAP25) {
|
|
|
+ mdata = &map->s_type_specific.s_metadata;
|
|
|
+ iput(mdata->s_metadata_fe);
|
|
|
+ mdata->s_metadata_fe = NULL;
|
|
|
+
|
|
|
+ iput(mdata->s_mirror_fe);
|
|
|
+ mdata->s_mirror_fe = NULL;
|
|
|
+
|
|
|
+ iput(mdata->s_bitmap_fe);
|
|
|
+ mdata->s_bitmap_fe = NULL;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void udf_sb_free_partitions(struct super_block *sb)
|
|
|
+{
|
|
|
+ struct udf_sb_info *sbi = UDF_SB(sb);
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 0; i < sbi->s_partitions; i++)
|
|
|
+ udf_free_partition(&sbi->s_partmaps[i]);
|
|
|
+ kfree(sbi->s_partmaps);
|
|
|
+ sbi->s_partmaps = NULL;
|
|
|
+}
|
|
|
+
|
|
|
static int udf_show_options(struct seq_file *seq, struct dentry *root)
|
|
|
{
|
|
|
struct super_block *sb = root->d_sb;
|
|
@@ -1283,7 +1340,7 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block,
|
|
|
BUG_ON(ident != TAG_IDENT_LVD);
|
|
|
lvd = (struct logicalVolDesc *)bh->b_data;
|
|
|
table_len = le32_to_cpu(lvd->mapTableLength);
|
|
|
- if (sizeof(*lvd) + table_len > sb->s_blocksize) {
|
|
|
+ if (table_len > sb->s_blocksize - sizeof(*lvd)) {
|
|
|
udf_err(sb, "error loading logical volume descriptor: "
|
|
|
"Partition table too long (%u > %lu)\n", table_len,
|
|
|
sb->s_blocksize - sizeof(*lvd));
|
|
@@ -1596,7 +1653,11 @@ static int udf_load_sequence(struct super_block *sb, struct buffer_head *bh,
|
|
|
/* responsible for finding the PartitionDesc(s) */
|
|
|
if (!udf_process_sequence(sb, main_s, main_e, fileset))
|
|
|
return 1;
|
|
|
- return !udf_process_sequence(sb, reserve_s, reserve_e, fileset);
|
|
|
+ udf_sb_free_partitions(sb);
|
|
|
+ if (!udf_process_sequence(sb, reserve_s, reserve_e, fileset))
|
|
|
+ return 1;
|
|
|
+ udf_sb_free_partitions(sb);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1861,55 +1922,8 @@ u64 lvid_get_unique_id(struct super_block *sb)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
|
|
|
-{
|
|
|
- int i;
|
|
|
- int nr_groups = bitmap->s_nr_groups;
|
|
|
- int size = sizeof(struct udf_bitmap) + (sizeof(struct buffer_head *) *
|
|
|
- nr_groups);
|
|
|
-
|
|
|
- for (i = 0; i < nr_groups; i++)
|
|
|
- if (bitmap->s_block_bitmap[i])
|
|
|
- brelse(bitmap->s_block_bitmap[i]);
|
|
|
-
|
|
|
- if (size <= PAGE_SIZE)
|
|
|
- kfree(bitmap);
|
|
|
- else
|
|
|
- vfree(bitmap);
|
|
|
-}
|
|
|
-
|
|
|
-static void udf_free_partition(struct udf_part_map *map)
|
|
|
-{
|
|
|
- int i;
|
|
|
- struct udf_meta_data *mdata;
|
|
|
-
|
|
|
- if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE)
|
|
|
- iput(map->s_uspace.s_table);
|
|
|
- if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE)
|
|
|
- iput(map->s_fspace.s_table);
|
|
|
- if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP)
|
|
|
- udf_sb_free_bitmap(map->s_uspace.s_bitmap);
|
|
|
- if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP)
|
|
|
- udf_sb_free_bitmap(map->s_fspace.s_bitmap);
|
|
|
- if (map->s_partition_type == UDF_SPARABLE_MAP15)
|
|
|
- for (i = 0; i < 4; i++)
|
|
|
- brelse(map->s_type_specific.s_sparing.s_spar_map[i]);
|
|
|
- else if (map->s_partition_type == UDF_METADATA_MAP25) {
|
|
|
- mdata = &map->s_type_specific.s_metadata;
|
|
|
- iput(mdata->s_metadata_fe);
|
|
|
- mdata->s_metadata_fe = NULL;
|
|
|
-
|
|
|
- iput(mdata->s_mirror_fe);
|
|
|
- mdata->s_mirror_fe = NULL;
|
|
|
-
|
|
|
- iput(mdata->s_bitmap_fe);
|
|
|
- mdata->s_bitmap_fe = NULL;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
static int udf_fill_super(struct super_block *sb, void *options, int silent)
|
|
|
{
|
|
|
- int i;
|
|
|
int ret;
|
|
|
struct inode *inode = NULL;
|
|
|
struct udf_options uopt;
|
|
@@ -1974,7 +1988,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
|
|
|
sb->s_op = &udf_sb_ops;
|
|
|
sb->s_export_op = &udf_export_ops;
|
|
|
|
|
|
- sb->s_dirt = 0;
|
|
|
sb->s_magic = UDF_SUPER_MAGIC;
|
|
|
sb->s_time_gran = 1000;
|
|
|
|
|
@@ -2072,9 +2085,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
|
|
|
error_out:
|
|
|
if (sbi->s_vat_inode)
|
|
|
iput(sbi->s_vat_inode);
|
|
|
- if (sbi->s_partitions)
|
|
|
- for (i = 0; i < sbi->s_partitions; i++)
|
|
|
- udf_free_partition(&sbi->s_partmaps[i]);
|
|
|
#ifdef CONFIG_UDF_NLS
|
|
|
if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
|
|
|
unload_nls(sbi->s_nls_map);
|
|
@@ -2082,8 +2092,7 @@ error_out:
|
|
|
if (!(sb->s_flags & MS_RDONLY))
|
|
|
udf_close_lvid(sb);
|
|
|
brelse(sbi->s_lvid_bh);
|
|
|
-
|
|
|
- kfree(sbi->s_partmaps);
|
|
|
+ udf_sb_free_partitions(sb);
|
|
|
kfree(sbi);
|
|
|
sb->s_fs_info = NULL;
|
|
|
|
|
@@ -2096,10 +2105,6 @@ void _udf_err(struct super_block *sb, const char *function,
|
|
|
struct va_format vaf;
|
|
|
va_list args;
|
|
|
|
|
|
- /* mark sb error */
|
|
|
- if (!(sb->s_flags & MS_RDONLY))
|
|
|
- sb->s_dirt = 1;
|
|
|
-
|
|
|
va_start(args, fmt);
|
|
|
|
|
|
vaf.fmt = fmt;
|
|
@@ -2128,16 +2133,12 @@ void _udf_warn(struct super_block *sb, const char *function,
|
|
|
|
|
|
static void udf_put_super(struct super_block *sb)
|
|
|
{
|
|
|
- int i;
|
|
|
struct udf_sb_info *sbi;
|
|
|
|
|
|
sbi = UDF_SB(sb);
|
|
|
|
|
|
if (sbi->s_vat_inode)
|
|
|
iput(sbi->s_vat_inode);
|
|
|
- if (sbi->s_partitions)
|
|
|
- for (i = 0; i < sbi->s_partitions; i++)
|
|
|
- udf_free_partition(&sbi->s_partmaps[i]);
|
|
|
#ifdef CONFIG_UDF_NLS
|
|
|
if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
|
|
|
unload_nls(sbi->s_nls_map);
|
|
@@ -2145,7 +2146,7 @@ static void udf_put_super(struct super_block *sb)
|
|
|
if (!(sb->s_flags & MS_RDONLY))
|
|
|
udf_close_lvid(sb);
|
|
|
brelse(sbi->s_lvid_bh);
|
|
|
- kfree(sbi->s_partmaps);
|
|
|
+ udf_sb_free_partitions(sb);
|
|
|
kfree(sb->s_fs_info);
|
|
|
sb->s_fs_info = NULL;
|
|
|
}
|
|
@@ -2161,7 +2162,6 @@ static int udf_sync_fs(struct super_block *sb, int wait)
|
|
|
* the buffer for IO
|
|
|
*/
|
|
|
mark_buffer_dirty(sbi->s_lvid_bh);
|
|
|
- sb->s_dirt = 0;
|
|
|
sbi->s_lvid_dirty = 0;
|
|
|
}
|
|
|
mutex_unlock(&sbi->s_alloc_mutex);
|