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>
This commit is contained in:
Linus Torvalds 2012-07-24 17:40:44 -07:00
commit 08d9329c29
12 changed files with 88 additions and 82 deletions

View file

@ -771,13 +771,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
err = -ENOMEM; err = -ENOMEM;
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi) if (!sbi)
goto failed_unlock; goto failed;
sbi->s_blockgroup_lock = sbi->s_blockgroup_lock =
kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL); kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL);
if (!sbi->s_blockgroup_lock) { if (!sbi->s_blockgroup_lock) {
kfree(sbi); kfree(sbi);
goto failed_unlock; goto failed;
} }
sb->s_fs_info = sbi; sb->s_fs_info = sbi;
sbi->s_sb_block = sb_block; sbi->s_sb_block = sb_block;
@ -1130,7 +1130,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
kfree(sbi->s_blockgroup_lock); kfree(sbi->s_blockgroup_lock);
kfree(sbi); kfree(sbi);
failed_unlock: failed:
return ret; return ret;
} }

View file

@ -92,8 +92,13 @@ int ext3_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
* disk caches manually so that data really is on persistent * disk caches manually so that data really is on persistent
* storage * storage
*/ */
if (needs_barrier) if (needs_barrier) {
blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); int err;
err = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
if (!ret)
ret = err;
}
out: out:
trace_ext3_sync_file_exit(inode, ret); trace_ext3_sync_file_exit(inode, ret);
return ret; return ret;

View file

@ -2058,7 +2058,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
goto failed_mount3; goto failed_mount3;
} }
ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY); if (ext3_setup_super(sb, es, sb->s_flags & MS_RDONLY))
sb->s_flags |= MS_RDONLY;
EXT3_SB(sb)->s_mount_state |= EXT3_ORPHAN_FS; EXT3_SB(sb)->s_mount_state |= EXT3_ORPHAN_FS;
ext3_orphan_cleanup(sb, es); ext3_orphan_cleanup(sb, es);

View file

@ -134,6 +134,7 @@ isofs_export_encode_fh(struct inode *inode,
len = 3; len = 3;
fh32[0] = ei->i_iget5_block; fh32[0] = ei->i_iget5_block;
fh16[2] = (__u16)ei->i_iget5_offset; /* fh16 [sic] */ fh16[2] = (__u16)ei->i_iget5_offset; /* fh16 [sic] */
fh16[3] = 0; /* avoid leaking uninitialized data */
fh32[2] = inode->i_generation; fh32[2] = inode->i_generation;
if (parent) { if (parent) {
struct iso_inode_info *eparent; struct iso_inode_info *eparent;

View file

@ -265,8 +265,11 @@ int journal_recover(journal_t *journal)
if (!err) if (!err)
err = err2; err = err2;
/* Flush disk caches to get replayed data on the permanent storage */ /* Flush disk caches to get replayed data on the permanent storage */
if (journal->j_flags & JFS_BARRIER) if (journal->j_flags & JFS_BARRIER) {
blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); err2 = blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);
if (!err)
err = err2;
}
return err; return err;
} }

View file

@ -78,7 +78,7 @@
#include <linux/quotaops.h> #include <linux/quotaops.h>
#include "../internal.h" /* ugh */ #include "../internal.h" /* ugh */
#include <asm/uaccess.h> #include <linux/uaccess.h>
/* /*
* There are three quota SMP locks. dq_list_lock protects all lists with quotas * There are three quota SMP locks. dq_list_lock protects all lists with quotas

View file

@ -9,7 +9,7 @@
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/current.h> #include <asm/current.h>
#include <asm/uaccess.h> #include <linux/uaccess.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/security.h> #include <linux/security.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>

View file

@ -1247,7 +1247,6 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
{ {
struct fileEntry *fe; struct fileEntry *fe;
struct extendedFileEntry *efe; struct extendedFileEntry *efe;
int offset;
struct udf_sb_info *sbi = UDF_SB(inode->i_sb); struct udf_sb_info *sbi = UDF_SB(inode->i_sb);
struct udf_inode_info *iinfo = UDF_I(inode); struct udf_inode_info *iinfo = UDF_I(inode);
unsigned int link_count; 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_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr);
iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs); iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs);
iinfo->i_checkpoint = le32_to_cpu(fe->checkpoint); iinfo->i_checkpoint = le32_to_cpu(fe->checkpoint);
offset = sizeof(struct fileEntry) + iinfo->i_lenEAttr;
} else { } else {
inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
(inode->i_sb->s_blocksize_bits - 9); (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_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr);
iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs); iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs);
iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint); iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint);
offset = sizeof(struct extendedFileEntry) +
iinfo->i_lenEAttr;
} }
switch (fe->icbTag.fileType) { switch (fe->icbTag.fileType) {

View file

@ -1279,6 +1279,7 @@ static int udf_encode_fh(struct inode *inode, __u32 *fh, int *lenp,
*lenp = 3; *lenp = 3;
fid->udf.block = location.logicalBlockNum; fid->udf.block = location.logicalBlockNum;
fid->udf.partref = location.partitionReferenceNum; fid->udf.partref = location.partitionReferenceNum;
fid->udf.parent_partref = 0;
fid->udf.generation = inode->i_generation; fid->udf.generation = inode->i_generation;
if (parent) { if (parent) {

View file

@ -252,6 +252,63 @@ static int udf_sb_alloc_partition_maps(struct super_block *sb, u32 count)
return 0; 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) static int udf_show_options(struct seq_file *seq, struct dentry *root)
{ {
struct super_block *sb = root->d_sb; 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); BUG_ON(ident != TAG_IDENT_LVD);
lvd = (struct logicalVolDesc *)bh->b_data; lvd = (struct logicalVolDesc *)bh->b_data;
table_len = le32_to_cpu(lvd->mapTableLength); 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: " udf_err(sb, "error loading logical volume descriptor: "
"Partition table too long (%u > %lu)\n", table_len, "Partition table too long (%u > %lu)\n", table_len,
sb->s_blocksize - sizeof(*lvd)); 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) */ /* responsible for finding the PartitionDesc(s) */
if (!udf_process_sequence(sb, main_s, main_e, fileset)) if (!udf_process_sequence(sb, main_s, main_e, fileset))
return 1; 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; 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) static int udf_fill_super(struct super_block *sb, void *options, int silent)
{ {
int i;
int ret; int ret;
struct inode *inode = NULL; struct inode *inode = NULL;
struct udf_options uopt; 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_op = &udf_sb_ops;
sb->s_export_op = &udf_export_ops; sb->s_export_op = &udf_export_ops;
sb->s_dirt = 0;
sb->s_magic = UDF_SUPER_MAGIC; sb->s_magic = UDF_SUPER_MAGIC;
sb->s_time_gran = 1000; sb->s_time_gran = 1000;
@ -2072,9 +2085,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
error_out: error_out:
if (sbi->s_vat_inode) if (sbi->s_vat_inode)
iput(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 #ifdef CONFIG_UDF_NLS
if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
unload_nls(sbi->s_nls_map); unload_nls(sbi->s_nls_map);
@ -2082,8 +2092,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
if (!(sb->s_flags & MS_RDONLY)) if (!(sb->s_flags & MS_RDONLY))
udf_close_lvid(sb); udf_close_lvid(sb);
brelse(sbi->s_lvid_bh); brelse(sbi->s_lvid_bh);
udf_sb_free_partitions(sb);
kfree(sbi->s_partmaps);
kfree(sbi); kfree(sbi);
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
@ -2096,10 +2105,6 @@ void _udf_err(struct super_block *sb, const char *function,
struct va_format vaf; struct va_format vaf;
va_list args; va_list args;
/* mark sb error */
if (!(sb->s_flags & MS_RDONLY))
sb->s_dirt = 1;
va_start(args, fmt); va_start(args, fmt);
vaf.fmt = 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) static void udf_put_super(struct super_block *sb)
{ {
int i;
struct udf_sb_info *sbi; struct udf_sb_info *sbi;
sbi = UDF_SB(sb); sbi = UDF_SB(sb);
if (sbi->s_vat_inode) if (sbi->s_vat_inode)
iput(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 #ifdef CONFIG_UDF_NLS
if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
unload_nls(sbi->s_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)) if (!(sb->s_flags & MS_RDONLY))
udf_close_lvid(sb); udf_close_lvid(sb);
brelse(sbi->s_lvid_bh); brelse(sbi->s_lvid_bh);
kfree(sbi->s_partmaps); udf_sb_free_partitions(sb);
kfree(sb->s_fs_info); kfree(sb->s_fs_info);
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
} }
@ -2161,7 +2162,6 @@ static int udf_sync_fs(struct super_block *sb, int wait)
* the buffer for IO * the buffer for IO
*/ */
mark_buffer_dirty(sbi->s_lvid_bh); mark_buffer_dirty(sbi->s_lvid_bh);
sb->s_dirt = 0;
sbi->s_lvid_dirty = 0; sbi->s_lvid_dirty = 0;
} }
mutex_unlock(&sbi->s_alloc_mutex); mutex_unlock(&sbi->s_alloc_mutex);

View file

@ -248,7 +248,7 @@ void udf_truncate_extents(struct inode *inode)
/* We managed to free all extents in the /* We managed to free all extents in the
* indirect extent - free it too */ * indirect extent - free it too */
BUG_ON(!epos.bh); BUG_ON(!epos.bh);
udf_free_blocks(sb, inode, &epos.block, udf_free_blocks(sb, NULL, &epos.block,
0, indirect_ext_len); 0, indirect_ext_len);
} else if (!epos.bh) { } else if (!epos.bh) {
iinfo->i_lenAlloc = lenalloc; iinfo->i_lenAlloc = lenalloc;
@ -275,7 +275,7 @@ void udf_truncate_extents(struct inode *inode)
if (indirect_ext_len) { if (indirect_ext_len) {
BUG_ON(!epos.bh); 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) { } else if (!epos.bh) {
iinfo->i_lenAlloc = lenalloc; iinfo->i_lenAlloc = lenalloc;
mark_inode_dirty(inode); mark_inode_dirty(inode);

View file

@ -129,7 +129,6 @@ static inline void udf_updated_lvid(struct super_block *sb)
WARN_ON_ONCE(((struct logicalVolIntegrityDesc *) WARN_ON_ONCE(((struct logicalVolIntegrityDesc *)
bh->b_data)->integrityType != bh->b_data)->integrityType !=
cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN)); cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN));
sb->s_dirt = 1;
UDF_SB(sb)->s_lvid_dirty = 1; UDF_SB(sb)->s_lvid_dirty = 1;
} }
extern u64 lvid_get_unique_id(struct super_block *sb); extern u64 lvid_get_unique_id(struct super_block *sb);