Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 25 Jul 2012 00:40:44 +0000 (17:40 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 25 Jul 2012 00:40:44 +0000 (17:40 -0700)
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>

12 files changed:
fs/ext2/super.c
fs/ext3/fsync.c
fs/ext3/super.c
fs/isofs/export.c
fs/jbd/recovery.c
fs/quota/dquot.c
fs/quota/quota.c
fs/udf/inode.c
fs/udf/namei.c
fs/udf/super.c
fs/udf/truncate.c
fs/udf/udfdecl.h

index 5df3d2d8169c25c1af4f45ce77a5f062517049de..9f311d27b16f5a804150e5cce66ce0b1724e7cb8 100644 (file)
@@ -771,13 +771,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
        err = -ENOMEM;
        sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
        if (!sbi)
-               goto failed_unlock;
+               goto failed;
 
        sbi->s_blockgroup_lock =
                kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL);
        if (!sbi->s_blockgroup_lock) {
                kfree(sbi);
-               goto failed_unlock;
+               goto failed;
        }
        sb->s_fs_info = sbi;
        sbi->s_sb_block = sb_block;
@@ -1130,7 +1130,7 @@ failed_sbi:
        sb->s_fs_info = NULL;
        kfree(sbi->s_blockgroup_lock);
        kfree(sbi);
-failed_unlock:
+failed:
        return ret;
 }
 
index d4dff278cbd824d5d732af355f1428be27a775ae..b31dbd4c46ad3f1ae9acd41dc274a9aa870656e9 100644 (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
         * storage
         */
-       if (needs_barrier)
-               blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
+       if (needs_barrier) {
+               int err;
+
+               err = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
+               if (!ret)
+                       ret = err;
+       }
 out:
        trace_ext3_sync_file_exit(inode, ret);
        return ret;
index 4ac304c55c5327703e19ed990c39a67460f1c4ad..ff9bcdc5b0d5a7b5f210723092716e9e0f32937c 100644 (file)
@@ -2058,7 +2058,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
                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_orphan_cleanup(sb, es);
index aa4356d09eeeb03167bcf506a7fe8ad98efaba39..1d3804492aa77d7ca4440d087fd415febc2e3681 100644 (file)
@@ -134,6 +134,7 @@ isofs_export_encode_fh(struct inode *inode,
        len = 3;
        fh32[0] = ei->i_iget5_block;
        fh16[2] = (__u16)ei->i_iget5_offset;  /* fh16 [sic] */
+       fh16[3] = 0;  /* avoid leaking uninitialized data */
        fh32[2] = inode->i_generation;
        if (parent) {
                struct iso_inode_info *eparent;
index 008bf062fd26e1bdfe0de195159c66aeb9fa1aab..a748fe21465abd1a6d8d478fc1fd93b4d9ce335a 100644 (file)
@@ -265,8 +265,11 @@ int journal_recover(journal_t *journal)
        if (!err)
                err = err2;
        /* Flush disk caches to get replayed data on the permanent storage */
-       if (journal->j_flags & JFS_BARRIER)
-               blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);
+       if (journal->j_flags & JFS_BARRIER) {
+               err2 = blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);
+               if (!err)
+                       err = err2;
+       }
 
        return err;
 }
index d679fc48ef27bcb6e62ac10fb9de1ba2677d7fdd..36a29b753c79c709175ebfd788196d1ecad948b5 100644 (file)
@@ -78,7 +78,7 @@
 #include <linux/quotaops.h>
 #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
index c659f92298d3623eed8da9eb9d53c064dd917141..6f155788cbc6ed498126cfca9edff974f19b4a93 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/namei.h>
 #include <linux/slab.h>
 #include <asm/current.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/kernel.h>
 #include <linux/security.h>
 #include <linux/syscalls.h>
index 873e1bab9c4c70cf45ed6bac6e46495decfbd55d..fafaad795cd6da4842a798e25446f6b426d65d65 100644 (file)
@@ -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) {
index 544b2799a9114c4620844bec32b9921881da97b9..95fee278ab9da660608226b478645878424bbf64 100644 (file)
@@ -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) {
index 8d86a8706c0e4d93bcace5ed039a71388cd966d5..dcbf98722afcd5df2a8940f4dbd5c1c8a02c7b40 100644 (file)
@@ -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);
index 4b98fee8e1613131815fa6155d3e7ac81a33c0f8..8a9657d7f7c680eed83bd007372796b5c2f2523c 100644 (file)
@@ -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);
index ebe10314e512cb1d214fc97e066b8b1bfecb549b..de038da6f6bde90588b95cd0bf70b2ac47930496 100644 (file)
@@ -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);