aboutsummaryrefslogtreecommitdiff
path: root/fs/udf
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-24 17:40:44 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-24 17:40:44 -0700
commit08d9329c29ec98477e8ac2f7a513f2bfa3e9f3c5 (patch)
tree464917dd750d7417cc62831c7a119b7ca64d0ec8 /fs/udf
parent2c05b2c838e7adaabb7265ad5d5b632315c20821 (diff)
parent0143fc5e9f6f5aad4764801015bc8d4b4a278200 (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull misc udf, ext2, ext3, and isofs fixes from Jan Kara: "Assorted, mostly trivial, fixes for udf, ext2, ext3, and isofs. I'm on vacation and scarcely checking email since we are expecting baby any day now but these fixes should be safe to go in and I don't want to delay them unnecessarily." * 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: udf: avoid info leak on export isofs: avoid info leak on export udf: Improve table length check to avoid possible overflow ext3: Check return value of blkdev_issue_flush() jbd: Check return value of blkdev_issue_flush() udf: Do not decrement i_blocks when freeing indirect extent block udf: Fix memory leak when mounting ext2: cleanup the confused goto label UDF: Remove unnecessary variable "offset" from udf_fill_inode udf: stop using s_dirt ext3: force ro mount if ext3_setup_super() fails quota: fix checkpatch.pl warning by replacing <asm/uaccess.h> with <linux/uaccess.h>
Diffstat (limited to 'fs/udf')
-rw-r--r--fs/udf/inode.c4
-rw-r--r--fs/udf/namei.c1
-rw-r--r--fs/udf/super.c130
-rw-r--r--fs/udf/truncate.c4
-rw-r--r--fs/udf/udfdecl.h1
5 files changed, 68 insertions, 72 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 873e1bab9c4..fafaad795cd 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1247,7 +1247,6 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
{
struct fileEntry *fe;
struct extendedFileEntry *efe;
- int offset;
struct udf_sb_info *sbi = UDF_SB(inode->i_sb);
struct udf_inode_info *iinfo = UDF_I(inode);
unsigned int link_count;
@@ -1359,7 +1358,6 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr);
iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs);
iinfo->i_checkpoint = le32_to_cpu(fe->checkpoint);
- offset = sizeof(struct fileEntry) + iinfo->i_lenEAttr;
} else {
inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
(inode->i_sb->s_blocksize_bits - 9);
@@ -1381,8 +1379,6 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr);
iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs);
iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint);
- offset = sizeof(struct extendedFileEntry) +
- iinfo->i_lenEAttr;
}
switch (fe->icbTag.fileType) {
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 544b2799a91..95fee278ab9 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -1279,6 +1279,7 @@ static int udf_encode_fh(struct inode *inode, __u32 *fh, int *lenp,
*lenp = 3;
fid->udf.block = location.logicalBlockNum;
fid->udf.partref = location.partitionReferenceNum;
+ fid->udf.parent_partref = 0;
fid->udf.generation = inode->i_generation;
if (parent) {
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 8d86a8706c0..dcbf98722af 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -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);
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c
index 4b98fee8e16..8a9657d7f7c 100644
--- a/fs/udf/truncate.c
+++ b/fs/udf/truncate.c
@@ -248,7 +248,7 @@ void udf_truncate_extents(struct inode *inode)
/* We managed to free all extents in the
* indirect extent - free it too */
BUG_ON(!epos.bh);
- udf_free_blocks(sb, inode, &epos.block,
+ udf_free_blocks(sb, NULL, &epos.block,
0, indirect_ext_len);
} else if (!epos.bh) {
iinfo->i_lenAlloc = lenalloc;
@@ -275,7 +275,7 @@ void udf_truncate_extents(struct inode *inode)
if (indirect_ext_len) {
BUG_ON(!epos.bh);
- udf_free_blocks(sb, inode, &epos.block, 0, indirect_ext_len);
+ udf_free_blocks(sb, NULL, &epos.block, 0, indirect_ext_len);
} else if (!epos.bh) {
iinfo->i_lenAlloc = lenalloc;
mark_inode_dirty(inode);
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index ebe10314e51..de038da6f6b 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -129,7 +129,6 @@ static inline void udf_updated_lvid(struct super_block *sb)
WARN_ON_ONCE(((struct logicalVolIntegrityDesc *)
bh->b_data)->integrityType !=
cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN));
- sb->s_dirt = 1;
UDF_SB(sb)->s_lvid_dirty = 1;
}
extern u64 lvid_get_unique_id(struct super_block *sb);