ext3, ext4: avoid divide by zero
[safe/jmp/linux-2.6] / fs / ext3 / super.c
index f2dd713..cb14de1 100644 (file)
 #include <linux/parser.h>
 #include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
+#include <linux/exportfs.h>
 #include <linux/vfs.h>
 #include <linux/random.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/quotaops.h>
 #include <linux/seq_file.h>
+#include <linux/log2.h>
 
 #include <asm/uaccess.h>
 
@@ -45,7 +47,7 @@
 static int ext3_load_journal(struct super_block *, struct ext3_super_block *,
                             unsigned long journal_devnum);
 static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
-                              int);
+                              unsigned int);
 static void ext3_commit_super (struct super_block * sb,
                               struct ext3_super_block * es,
                               int sync);
@@ -62,13 +64,13 @@ static void ext3_unlockfs(struct super_block *sb);
 static void ext3_write_super (struct super_block * sb);
 static void ext3_write_super_lockfs(struct super_block *sb);
 
-/* 
+/*
  * Wrappers for journal_start/end.
  *
  * The only special thing we need to do here is to make sure that all
  * journal_end calls result in the superblock being marked dirty, so
  * that sync() will call the filesystem's write_super callback if
- * appropriate. 
+ * appropriate.
  */
 handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks)
 {
@@ -90,11 +92,11 @@ handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks)
        return journal_start(journal, nblocks);
 }
 
-/* 
+/*
  * The only special thing we need to do here is to make sure that all
  * journal_stop calls result in the superblock being marked dirty, so
  * that sync() will call the filesystem's write_super callback if
- * appropriate. 
+ * appropriate.
  */
 int __ext3_journal_stop(const char *where, handle_t *handle)
 {
@@ -159,20 +161,21 @@ static void ext3_handle_error(struct super_block *sb)
        if (sb->s_flags & MS_RDONLY)
                return;
 
-       if (test_opt (sb, ERRORS_RO)) {
-               printk (KERN_CRIT "Remounting filesystem read-only\n");
-               sb->s_flags |= MS_RDONLY;
-       } else {
+       if (!test_opt (sb, ERRORS_CONT)) {
                journal_t *journal = EXT3_SB(sb)->s_journal;
 
                EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT;
                if (journal)
                        journal_abort(journal, -EIO);
        }
+       if (test_opt (sb, ERRORS_RO)) {
+               printk (KERN_CRIT "Remounting filesystem read-only\n");
+               sb->s_flags |= MS_RDONLY;
+       }
+       ext3_commit_super(sb, es, 1);
        if (test_opt(sb, ERRORS_PANIC))
                panic("EXT3-fs (device %s): panic forced after error\n",
                        sb->s_id);
-       ext3_commit_super(sb, es, 1);
 }
 
 void ext3_error (struct super_block * sb, const char * function,
@@ -369,16 +372,16 @@ static void dump_orphan_list(struct super_block *sb, struct ext3_sb_info *sbi)
 {
        struct list_head *l;
 
-       printk(KERN_ERR "sb orphan head is %d\n", 
+       printk(KERN_ERR "sb orphan head is %d\n",
               le32_to_cpu(sbi->s_es->s_last_orphan));
 
        printk(KERN_ERR "sb_info orphan list:\n");
        list_for_each(l, &sbi->s_orphan) {
                struct inode *inode = orphan_list_entry(l);
                printk(KERN_ERR "  "
-                      "inode %s:%ld at %p: mode %o, nlink %d, next %d\n",
+                      "inode %s:%lu at %p: mode %o, nlink %d, next %d\n",
                       inode->i_sb->s_id, inode->i_ino, inode,
-                      inode->i_mode, inode->i_nlink, 
+                      inode->i_mode, inode->i_nlink,
                       NEXT_ORPHAN(inode));
        }
 }
@@ -419,7 +422,7 @@ static void ext3_put_super (struct super_block * sb)
                dump_orphan_list(sb, sbi);
        J_ASSERT(list_empty(&sbi->s_orphan));
 
-       invalidate_bdev(sb->s_bdev, 0);
+       invalidate_bdev(sb->s_bdev);
        if (sbi->journal_bdev && sbi->journal_bdev != sb->s_bdev) {
                /*
                 * Invalidate the journal device's buffers.  We don't want them
@@ -427,7 +430,7 @@ static void ext3_put_super (struct super_block * sb)
                 * hotswapped, and it breaks the `ro-after' testing code.
                 */
                sync_blockdev(sbi->journal_bdev);
-               invalidate_bdev(sbi->journal_bdev, 0);
+               invalidate_bdev(sbi->journal_bdev);
                ext3_blkdev_remove(sbi);
        }
        sb->s_fs_info = NULL;
@@ -435,7 +438,7 @@ static void ext3_put_super (struct super_block * sb)
        return;
 }
 
-static kmem_cache_t *ext3_inode_cachep;
+static struct kmem_cache *ext3_inode_cachep;
 
 /*
  * Called inside transaction, so use GFP_NOFS
@@ -444,7 +447,7 @@ static struct inode *ext3_alloc_inode(struct super_block *sb)
 {
        struct ext3_inode_info *ei;
 
-       ei = kmem_cache_alloc(ext3_inode_cachep, SLAB_NOFS);
+       ei = kmem_cache_alloc(ext3_inode_cachep, GFP_NOFS);
        if (!ei)
                return NULL;
 #ifdef CONFIG_EXT3_FS_POSIX_ACL
@@ -458,31 +461,36 @@ static struct inode *ext3_alloc_inode(struct super_block *sb)
 
 static void ext3_destroy_inode(struct inode *inode)
 {
+       if (!list_empty(&(EXT3_I(inode)->i_orphan))) {
+               printk("EXT3 Inode %p: orphan list check failed!\n",
+                       EXT3_I(inode));
+               print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 4,
+                               EXT3_I(inode), sizeof(struct ext3_inode_info),
+                               false);
+               dump_stack();
+       }
        kmem_cache_free(ext3_inode_cachep, EXT3_I(inode));
 }
 
-static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+static void init_once(struct kmem_cache * cachep, void *foo)
 {
        struct ext3_inode_info *ei = (struct ext3_inode_info *) foo;
 
-       if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
-           SLAB_CTOR_CONSTRUCTOR) {
-               INIT_LIST_HEAD(&ei->i_orphan);
+       INIT_LIST_HEAD(&ei->i_orphan);
 #ifdef CONFIG_EXT3_FS_XATTR
-               init_rwsem(&ei->xattr_sem);
+       init_rwsem(&ei->xattr_sem);
 #endif
-               mutex_init(&ei->truncate_mutex);
-               inode_init_once(&ei->vfs_inode);
-       }
+       mutex_init(&ei->truncate_mutex);
+       inode_init_once(&ei->vfs_inode);
 }
+
 static int init_inodecache(void)
 {
        ext3_inode_cachep = kmem_cache_create("ext3_inode_cache",
                                             sizeof(struct ext3_inode_info),
                                             0, (SLAB_RECLAIM_ACCOUNT|
                                                SLAB_MEM_SPREAD),
-                                            init_once, NULL);
+                                            init_once);
        if (ext3_inode_cachep == NULL)
                return -ENOMEM;
        return 0;
@@ -490,8 +498,7 @@ static int init_inodecache(void)
 
 static void destroy_inodecache(void)
 {
-       if (kmem_cache_destroy(ext3_inode_cachep))
-               printk(KERN_INFO "ext3_inode_cache: not all structures were freed\n");
+       kmem_cache_destroy(ext3_inode_cachep);
 }
 
 static void ext3_clear_inode(struct inode *inode)
@@ -538,9 +545,78 @@ static inline void ext3_show_quota_options(struct seq_file *seq, struct super_bl
 #endif
 }
 
+/*
+ * Show an option if
+ *  - it's set to a non-default value OR
+ *  - if the per-sb default is different from the global default
+ */
 static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
 {
        struct super_block *sb = vfs->mnt_sb;
+       struct ext3_sb_info *sbi = EXT3_SB(sb);
+       struct ext3_super_block *es = sbi->s_es;
+       unsigned long def_mount_opts;
+
+       def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
+
+       if (sbi->s_sb_block != 1)
+               seq_printf(seq, ",sb=%lu", sbi->s_sb_block);
+       if (test_opt(sb, MINIX_DF))
+               seq_puts(seq, ",minixdf");
+       if (test_opt(sb, GRPID))
+               seq_puts(seq, ",grpid");
+       if (!test_opt(sb, GRPID) && (def_mount_opts & EXT3_DEFM_BSDGROUPS))
+               seq_puts(seq, ",nogrpid");
+       if (sbi->s_resuid != EXT3_DEF_RESUID ||
+           le16_to_cpu(es->s_def_resuid) != EXT3_DEF_RESUID) {
+               seq_printf(seq, ",resuid=%u", sbi->s_resuid);
+       }
+       if (sbi->s_resgid != EXT3_DEF_RESGID ||
+           le16_to_cpu(es->s_def_resgid) != EXT3_DEF_RESGID) {
+               seq_printf(seq, ",resgid=%u", sbi->s_resgid);
+       }
+       if (test_opt(sb, ERRORS_CONT)) {
+               int def_errors = le16_to_cpu(es->s_errors);
+
+               if (def_errors == EXT3_ERRORS_PANIC ||
+                   def_errors == EXT3_ERRORS_RO) {
+                       seq_puts(seq, ",errors=continue");
+               }
+       }
+       if (test_opt(sb, ERRORS_RO))
+               seq_puts(seq, ",errors=remount-ro");
+       if (test_opt(sb, ERRORS_PANIC))
+               seq_puts(seq, ",errors=panic");
+       if (test_opt(sb, NO_UID32))
+               seq_puts(seq, ",nouid32");
+       if (test_opt(sb, DEBUG))
+               seq_puts(seq, ",debug");
+       if (test_opt(sb, OLDALLOC))
+               seq_puts(seq, ",oldalloc");
+#ifdef CONFIG_EXT3_FS_XATTR
+       if (test_opt(sb, XATTR_USER))
+               seq_puts(seq, ",user_xattr");
+       if (!test_opt(sb, XATTR_USER) &&
+           (def_mount_opts & EXT3_DEFM_XATTR_USER)) {
+               seq_puts(seq, ",nouser_xattr");
+       }
+#endif
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+       if (test_opt(sb, POSIX_ACL))
+               seq_puts(seq, ",acl");
+       if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT3_DEFM_ACL))
+               seq_puts(seq, ",noacl");
+#endif
+       if (!test_opt(sb, RESERVATION))
+               seq_puts(seq, ",noreservation");
+       if (sbi->s_commit_interval) {
+               seq_printf(seq, ",commit=%u",
+                          (unsigned) (sbi->s_commit_interval / HZ));
+       }
+       if (test_opt(sb, BARRIER))
+               seq_puts(seq, ",barrier=1");
+       if (test_opt(sb, NOBH))
+               seq_puts(seq, ",nobh");
 
        if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA)
                seq_puts(seq, ",data=journal");
@@ -554,6 +630,51 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
        return 0;
 }
 
+
+static struct inode *ext3_nfs_get_inode(struct super_block *sb,
+               u64 ino, u32 generation)
+{
+       struct inode *inode;
+
+       if (ino < EXT3_FIRST_INO(sb) && ino != EXT3_ROOT_INO)
+               return ERR_PTR(-ESTALE);
+       if (ino > le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count))
+               return ERR_PTR(-ESTALE);
+
+       /* iget isn't really right if the inode is currently unallocated!!
+        *
+        * ext3_read_inode will return a bad_inode if the inode had been
+        * deleted, so we should be safe.
+        *
+        * Currently we don't know the generation for parent directory, so
+        * a generation of 0 means "accept any"
+        */
+       inode = iget(sb, ino);
+       if (inode == NULL)
+               return ERR_PTR(-ENOMEM);
+       if (is_bad_inode(inode) ||
+           (generation && inode->i_generation != generation)) {
+               iput(inode);
+               return ERR_PTR(-ESTALE);
+       }
+
+       return inode;
+}
+
+static struct dentry *ext3_fh_to_dentry(struct super_block *sb, struct fid *fid,
+               int fh_len, int fh_type)
+{
+       return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+                                   ext3_nfs_get_inode);
+}
+
+static struct dentry *ext3_fh_to_parent(struct super_block *sb, struct fid *fid,
+               int fh_len, int fh_type)
+{
+       return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+                                   ext3_nfs_get_inode);
+}
+
 #ifdef CONFIG_QUOTA
 #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group")
 #define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))
@@ -598,7 +719,7 @@ static struct quotactl_ops ext3_qctl_operations = {
 };
 #endif
 
-static struct super_operations ext3_sops = {
+static const struct super_operations ext3_sops = {
        .alloc_inode    = ext3_alloc_inode,
        .destroy_inode  = ext3_destroy_inode,
        .read_inode     = ext3_read_inode,
@@ -620,7 +741,9 @@ static struct super_operations ext3_sops = {
 #endif
 };
 
-static struct export_operations ext3_export_ops = {
+static const struct export_operations ext3_export_ops = {
+       .fh_to_dentry = ext3_fh_to_dentry,
+       .fh_to_parent = ext3_fh_to_parent,
        .get_parent = ext3_get_parent,
 };
 
@@ -691,8 +814,8 @@ static match_table_t tokens = {
 
 static ext3_fsblk_t get_sb_block(void **data)
 {
-       ext3_fsblk_t    sb_block;
-       char            *options = (char *) *data;
+       ext3_fsblk_t    sb_block;
+       char            *options = (char *) *data;
 
        if (!options || strncmp(options, "sb=", 3) != 0)
                return 1;       /* Default location */
@@ -711,7 +834,7 @@ static ext3_fsblk_t get_sb_block(void **data)
 }
 
 static int parse_options (char *options, struct super_block *sb,
-                         unsigned long *inum, unsigned long *journal_devnum,
+                         unsigned int *inum, unsigned long *journal_devnum,
                          ext3_fsblk_t *n_blocks_count, int is_remount)
 {
        struct ext3_sb_info *sbi = EXT3_SB(sb);
@@ -1132,7 +1255,8 @@ static int ext3_setup_super(struct super_block *sb, struct ext3_super_block *es,
 static int ext3_check_descriptors (struct super_block * sb)
 {
        struct ext3_sb_info *sbi = EXT3_SB(sb);
-       ext3_fsblk_t block = le32_to_cpu(sbi->s_es->s_first_data_block);
+       ext3_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block);
+       ext3_fsblk_t last_block;
        struct ext3_group_desc * gdp = NULL;
        int desc_block = 0;
        int i;
@@ -1141,12 +1265,17 @@ static int ext3_check_descriptors (struct super_block * sb)
 
        for (i = 0; i < sbi->s_groups_count; i++)
        {
+               if (i == sbi->s_groups_count - 1)
+                       last_block = le32_to_cpu(sbi->s_es->s_blocks_count) - 1;
+               else
+                       last_block = first_block +
+                               (EXT3_BLOCKS_PER_GROUP(sb) - 1);
+
                if ((i % EXT3_DESC_PER_BLOCK(sb)) == 0)
                        gdp = (struct ext3_group_desc *)
                                        sbi->s_group_desc[desc_block++]->b_data;
-               if (le32_to_cpu(gdp->bg_block_bitmap) < block ||
-                   le32_to_cpu(gdp->bg_block_bitmap) >=
-                               block + EXT3_BLOCKS_PER_GROUP(sb))
+               if (le32_to_cpu(gdp->bg_block_bitmap) < first_block ||
+                   le32_to_cpu(gdp->bg_block_bitmap) > last_block)
                {
                        ext3_error (sb, "ext3_check_descriptors",
                                    "Block bitmap for group %d"
@@ -1155,9 +1284,8 @@ static int ext3_check_descriptors (struct super_block * sb)
                                        le32_to_cpu(gdp->bg_block_bitmap));
                        return 0;
                }
-               if (le32_to_cpu(gdp->bg_inode_bitmap) < block ||
-                   le32_to_cpu(gdp->bg_inode_bitmap) >=
-                               block + EXT3_BLOCKS_PER_GROUP(sb))
+               if (le32_to_cpu(gdp->bg_inode_bitmap) < first_block ||
+                   le32_to_cpu(gdp->bg_inode_bitmap) > last_block)
                {
                        ext3_error (sb, "ext3_check_descriptors",
                                    "Inode bitmap for group %d"
@@ -1166,9 +1294,9 @@ static int ext3_check_descriptors (struct super_block * sb)
                                        le32_to_cpu(gdp->bg_inode_bitmap));
                        return 0;
                }
-               if (le32_to_cpu(gdp->bg_inode_table) < block ||
-                   le32_to_cpu(gdp->bg_inode_table) + sbi->s_itb_per_group >=
-                   block + EXT3_BLOCKS_PER_GROUP(sb))
+               if (le32_to_cpu(gdp->bg_inode_table) < first_block ||
+                   le32_to_cpu(gdp->bg_inode_table) + sbi->s_itb_per_group - 1 >
+                   last_block)
                {
                        ext3_error (sb, "ext3_check_descriptors",
                                    "Inode table for group %d"
@@ -1177,7 +1305,7 @@ static int ext3_check_descriptors (struct super_block * sb)
                                        le32_to_cpu(gdp->bg_inode_table));
                        return 0;
                }
-               block += EXT3_BLOCKS_PER_GROUP(sb);
+               first_block += EXT3_BLOCKS_PER_GROUP(sb);
                gdp++;
        }
 
@@ -1217,6 +1345,12 @@ static void ext3_orphan_cleanup (struct super_block * sb,
                return;
        }
 
+       if (bdev_read_only(sb->s_bdev)) {
+               printk(KERN_ERR "EXT3-fs: write access "
+                       "unavailable, skipping orphan cleanup.\n");
+               return;
+       }
+
        if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) {
                if (es->s_last_orphan)
                        jbd_debug(1, "Errors on filesystem, "
@@ -1259,17 +1393,17 @@ static void ext3_orphan_cleanup (struct super_block * sb,
                DQUOT_INIT(inode);
                if (inode->i_nlink) {
                        printk(KERN_DEBUG
-                               "%s: truncating inode %ld to %Ld bytes\n",
+                               "%s: truncating inode %lu to %Ld bytes\n",
                                __FUNCTION__, inode->i_ino, inode->i_size);
-                       jbd_debug(2, "truncating inode %ld to %Ld bytes\n",
+                       jbd_debug(2, "truncating inode %lu to %Ld bytes\n",
                                  inode->i_ino, inode->i_size);
                        ext3_truncate(inode);
                        nr_truncates++;
                } else {
                        printk(KERN_DEBUG
-                               "%s: deleting unreferenced inode %ld\n",
+                               "%s: deleting unreferenced inode %lu\n",
                                __FUNCTION__, inode->i_ino);
-                       jbd_debug(2, "deleting unreferenced inode %ld\n",
+                       jbd_debug(2, "deleting unreferenced inode %lu\n",
                                  inode->i_ino);
                        nr_orphans++;
                }
@@ -1294,8 +1428,6 @@ static void ext3_orphan_cleanup (struct super_block * sb,
        sb->s_flags = s_flags; /* Restore MS_RDONLY status */
 }
 
-#define log2(n) ffz(~(n))
-
 /*
  * Maximal file size.  There is a direct, and {,double-,triple-}indirect
  * block limit, and also a limit of (2^32 - 1) 512-byte sectors in i_blocks.
@@ -1348,7 +1480,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
        ext3_fsblk_t sb_block = get_sb_block(&data);
        ext3_fsblk_t logic_sb_block;
        unsigned long offset = 0;
-       unsigned long journal_inum = 0;
+       unsigned int journal_inum = 0;
        unsigned long journal_devnum = 0;
        unsigned long def_mount_opts;
        struct inode *root;
@@ -1358,15 +1490,16 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
        int i;
        int needs_recovery;
        __le32 features;
+       int err;
 
-       sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
+       sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
        if (!sbi)
                return -ENOMEM;
        sb->s_fs_info = sbi;
-       memset(sbi, 0, sizeof(*sbi));
        sbi->s_mount_opt = 0;
        sbi->s_resuid = EXT3_DEF_RESUID;
        sbi->s_resgid = EXT3_DEF_RESGID;
+       sbi->s_sb_block = sb_block;
 
        unlock_kernel();
 
@@ -1409,10 +1542,14 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
                set_opt(sbi->s_mount_opt, GRPID);
        if (def_mount_opts & EXT3_DEFM_UID16)
                set_opt(sbi->s_mount_opt, NO_UID32);
+#ifdef CONFIG_EXT3_FS_XATTR
        if (def_mount_opts & EXT3_DEFM_XATTR_USER)
                set_opt(sbi->s_mount_opt, XATTR_USER);
+#endif
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
        if (def_mount_opts & EXT3_DEFM_ACL)
                set_opt(sbi->s_mount_opt, POSIX_ACL);
+#endif
        if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_DATA)
                sbi->s_mount_opt |= EXT3_MOUNT_JOURNAL_DATA;
        else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_ORDERED)
@@ -1424,6 +1561,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
                set_opt(sbi->s_mount_opt, ERRORS_PANIC);
        else if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_RO)
                set_opt(sbi->s_mount_opt, ERRORS_RO);
+       else
+               set_opt(sbi->s_mount_opt, ERRORS_CONT);
 
        sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
        sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
@@ -1441,7 +1580,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
            (EXT3_HAS_COMPAT_FEATURE(sb, ~0U) ||
             EXT3_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
             EXT3_HAS_INCOMPAT_FEATURE(sb, ~0U)))
-               printk(KERN_WARNING 
+               printk(KERN_WARNING
                       "EXT3-fs warning: feature flags set on rev 0 fs, "
                       "running e2fsck is recommended\n");
        /*
@@ -1467,7 +1606,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
 
        if (blocksize < EXT3_MIN_BLOCK_SIZE ||
            blocksize > EXT3_MAX_BLOCK_SIZE) {
-               printk(KERN_ERR 
+               printk(KERN_ERR
                       "EXT3-fs: Unsupported filesystem blocksize %d on %s.\n",
                       blocksize, sb->s_id);
                goto failed_mount;
@@ -1486,19 +1625,23 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
                }
 
                brelse (bh);
-               sb_set_blocksize(sb, blocksize);
+               if (!sb_set_blocksize(sb, blocksize)) {
+                       printk(KERN_ERR "EXT3-fs: bad blocksize %d.\n",
+                               blocksize);
+                       goto out_fail;
+               }
                logic_sb_block = (sb_block * EXT3_MIN_BLOCK_SIZE) / blocksize;
                offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize;
                bh = sb_bread(sb, logic_sb_block);
                if (!bh) {
-                       printk(KERN_ERR 
+                       printk(KERN_ERR
                               "EXT3-fs: Can't read superblock on 2nd try.\n");
                        goto failed_mount;
                }
                es = (struct ext3_super_block *)(((char *)bh->b_data) + offset);
                sbi->s_es = es;
                if (es->s_magic != cpu_to_le16(EXT3_SUPER_MAGIC)) {
-                       printk (KERN_ERR 
+                       printk (KERN_ERR
                                "EXT3-fs: Magic mismatch, very weird !\n");
                        goto failed_mount;
                }
@@ -1513,7 +1656,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
                sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
                sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
                if ((sbi->s_inode_size < EXT3_GOOD_OLD_INODE_SIZE) ||
-                   (sbi->s_inode_size & (sbi->s_inode_size - 1)) ||
+                   (!is_power_of_2(sbi->s_inode_size)) ||
                    (sbi->s_inode_size > blocksize)) {
                        printk (KERN_ERR
                                "EXT3-fs: unsupported inode size: %d\n",
@@ -1533,7 +1676,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
        sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
        sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
        sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
-       if (EXT3_INODE_SIZE(sb) == 0)
+       if (EXT3_INODE_SIZE(sb) == 0 || EXT3_INODES_PER_GROUP(sb) == 0)
                goto cantfind_ext3;
        sbi->s_inodes_per_block = blocksize / EXT3_INODE_SIZE(sb);
        if (sbi->s_inodes_per_block == 0)
@@ -1543,8 +1686,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
        sbi->s_desc_per_block = blocksize / sizeof(struct ext3_group_desc);
        sbi->s_sbh = bh;
        sbi->s_mount_state = le16_to_cpu(es->s_state);
-       sbi->s_addr_per_block_bits = log2(EXT3_ADDR_PER_BLOCK(sb));
-       sbi->s_desc_per_block_bits = log2(EXT3_DESC_PER_BLOCK(sb));
+       sbi->s_addr_per_block_bits = ilog2(EXT3_ADDR_PER_BLOCK(sb));
+       sbi->s_desc_per_block_bits = ilog2(EXT3_DESC_PER_BLOCK(sb));
        for (i=0; i < 4; i++)
                sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
        sbi->s_def_hash_version = es->s_def_hash_version;
@@ -1580,10 +1723,9 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
 
        if (EXT3_BLOCKS_PER_GROUP(sb) == 0)
                goto cantfind_ext3;
-       sbi->s_groups_count = (le32_to_cpu(es->s_blocks_count) -
-                              le32_to_cpu(es->s_first_data_block) +
-                              EXT3_BLOCKS_PER_GROUP(sb) - 1) /
-                             EXT3_BLOCKS_PER_GROUP(sb);
+       sbi->s_groups_count = ((le32_to_cpu(es->s_blocks_count) -
+                              le32_to_cpu(es->s_first_data_block) - 1)
+                                      / EXT3_BLOCKS_PER_GROUP(sb)) + 1;
        db_count = (sbi->s_groups_count + EXT3_DESC_PER_BLOCK(sb) - 1) /
                   EXT3_DESC_PER_BLOCK(sb);
        sbi->s_group_desc = kmalloc(db_count * sizeof (struct buffer_head *),
@@ -1613,12 +1755,20 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
        get_random_bytes(&sbi->s_next_generation, sizeof(u32));
        spin_lock_init(&sbi->s_next_gen_lock);
 
-       percpu_counter_init(&sbi->s_freeblocks_counter,
-               ext3_count_free_blocks(sb));
-       percpu_counter_init(&sbi->s_freeinodes_counter,
-               ext3_count_free_inodes(sb));
-       percpu_counter_init(&sbi->s_dirs_counter,
-               ext3_count_dirs(sb));
+       err = percpu_counter_init(&sbi->s_freeblocks_counter,
+                       ext3_count_free_blocks(sb));
+       if (!err) {
+               err = percpu_counter_init(&sbi->s_freeinodes_counter,
+                               ext3_count_free_inodes(sb));
+       }
+       if (!err) {
+               err = percpu_counter_init(&sbi->s_dirs_counter,
+                               ext3_count_dirs(sb));
+       }
+       if (err) {
+               printk(KERN_ERR "EXT3-fs: insufficient memory\n");
+               goto failed_mount3;
+       }
 
        /* per fileystem reservation list head & lock */
        spin_lock_init(&sbi->s_rsv_window_lock);
@@ -1778,7 +1928,7 @@ out_fail:
 /*
  * Setup any per-fs journal parameters now.  We'll do this both on
  * initial mount, once the journal has been initialised but before we've
- * done any recovery; and again on any subsequent remount. 
+ * done any recovery; and again on any subsequent remount.
  */
 static void ext3_init_journal_params(struct super_block *sb, journal_t *journal)
 {
@@ -1798,7 +1948,8 @@ static void ext3_init_journal_params(struct super_block *sb, journal_t *journal)
        spin_unlock(&journal->j_state_lock);
 }
 
-static journal_t *ext3_get_journal(struct super_block *sb, int journal_inum)
+static journal_t *ext3_get_journal(struct super_block *sb,
+                                  unsigned int journal_inum)
 {
        struct inode *journal_inode;
        journal_t *journal;
@@ -1933,7 +2084,7 @@ static int ext3_load_journal(struct super_block *sb,
                             unsigned long journal_devnum)
 {
        journal_t *journal;
-       int journal_inum = le32_to_cpu(es->s_journal_inum);
+       unsigned int journal_inum = le32_to_cpu(es->s_journal_inum);
        dev_t journal_dev;
        int err = 0;
        int really_read_only;
@@ -2019,9 +2170,10 @@ static int ext3_load_journal(struct super_block *sb,
 
 static int ext3_create_journal(struct super_block * sb,
                               struct ext3_super_block * es,
-                              int journal_inum)
+                              unsigned int journal_inum)
 {
        journal_t *journal;
+       int err;
 
        if (sb->s_flags & MS_RDONLY) {
                printk(KERN_ERR "EXT3-fs: readonly filesystem when trying to "
@@ -2029,13 +2181,15 @@ static int ext3_create_journal(struct super_block * sb,
                return -EROFS;
        }
 
-       if (!(journal = ext3_get_journal(sb, journal_inum)))
+       journal = ext3_get_journal(sb, journal_inum);
+       if (!journal)
                return -EINVAL;
 
-       printk(KERN_INFO "EXT3-fs: creating new journal on inode %d\n",
+       printk(KERN_INFO "EXT3-fs: creating new journal on inode %u\n",
               journal_inum);
 
-       if (journal_create(journal)) {
+       err = journal_create(journal);
+       if (err) {
                printk(KERN_ERR "EXT3-fs: error creating journal.\n");
                journal_destroy(journal);
                return -EIO;
@@ -2086,12 +2240,14 @@ static void ext3_mark_recovery_complete(struct super_block * sb,
 
        journal_lock_updates(journal);
        journal_flush(journal);
+       lock_super(sb);
        if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) &&
            sb->s_flags & MS_RDONLY) {
                EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
                sb->s_dirt = 0;
                ext3_commit_super(sb, es, 1);
        }
+       unlock_super(sb);
        journal_unlock_updates(journal);
 }
 
@@ -2280,7 +2436,13 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
                            (sbi->s_mount_state & EXT3_VALID_FS))
                                es->s_state = cpu_to_le16(sbi->s_mount_state);
 
+                       /*
+                        * We have to unlock super so that we can wait for
+                        * transactions.
+                        */
+                       unlock_super(sb);
                        ext3_mark_recovery_complete(sb, es);
+                       lock_super(sb);
                } else {
                        __le32 ret;
                        if ((ret = EXT3_HAS_RO_COMPAT_FEATURE(sb,
@@ -2292,6 +2454,22 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
                                err = -EROFS;
                                goto restore_opts;
                        }
+
+                       /*
+                        * If we have an unprocessed orphan list hanging
+                        * around from a previously readonly bdev mount,
+                        * require a full umount/remount for now.
+                        */
+                       if (es->s_last_orphan) {
+                               printk(KERN_WARNING "EXT3-fs: %s: couldn't "
+                                      "remount RDWR because of unprocessed "
+                                      "orphan inode list.  Please "
+                                      "umount/remount instead.\n",
+                                      sb->s_id);
+                               err = -EINVAL;
+                               goto restore_opts;
+                       }
+
                        /*
                         * Mounting a RDONLY partition read-write, so reread
                         * and store the current valid flag.  (It may have
@@ -2300,10 +2478,8 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
                         */
                        ext3_clear_journal_err(sb, es);
                        sbi->s_mount_state = le16_to_cpu(es->s_state);
-                       if ((ret = ext3_group_extend(sb, es, n_blocks_count))) {
-                               err = ret;
+                       if ((err = ext3_group_extend(sb, es, n_blocks_count)))
                                goto restore_opts;
-                       }
                        if (!ext3_setup_super (sb, es, 0))
                                sb->s_flags &= ~MS_RDONLY;
                }
@@ -2339,18 +2515,19 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf)
        struct super_block *sb = dentry->d_sb;
        struct ext3_sb_info *sbi = EXT3_SB(sb);
        struct ext3_super_block *es = sbi->s_es;
-       ext3_fsblk_t overhead;
-       int i;
+       u64 fsid;
 
-       if (test_opt (sb, MINIX_DF))
-               overhead = 0;
-       else {
-               unsigned long ngroups;
-               ngroups = EXT3_SB(sb)->s_groups_count;
+       if (test_opt(sb, MINIX_DF)) {
+               sbi->s_overhead_last = 0;
+       } else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) {
+               unsigned long ngroups = sbi->s_groups_count, i;
+               ext3_fsblk_t overhead = 0;
                smp_rmb();
 
                /*
-                * Compute the overhead (FS structures)
+                * Compute the overhead (FS structures).  This is constant
+                * for a given filesystem unless the number of block groups
+                * changes so we cache the previous value until it does.
                 */
 
                /*
@@ -2374,19 +2551,28 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf)
                 * Every block group has an inode bitmap, a block
                 * bitmap, and an inode table.
                 */
-               overhead += (ngroups * (2 + EXT3_SB(sb)->s_itb_per_group));
+               overhead += ngroups * (2 + sbi->s_itb_per_group);
+               sbi->s_overhead_last = overhead;
+               smp_wmb();
+               sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count);
        }
 
        buf->f_type = EXT3_SUPER_MAGIC;
        buf->f_bsize = sb->s_blocksize;
-       buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead;
-       buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter);
+       buf->f_blocks = le32_to_cpu(es->s_blocks_count) - sbi->s_overhead_last;
+       buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter);
+       es->s_free_blocks_count = cpu_to_le32(buf->f_bfree);
        buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count);
        if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count))
                buf->f_bavail = 0;
        buf->f_files = le32_to_cpu(es->s_inodes_count);
-       buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter);
+       buf->f_ffree = percpu_counter_sum_positive(&sbi->s_freeinodes_counter);
+       es->s_free_inodes_count = cpu_to_le32(buf->f_ffree);
        buf->f_namelen = EXT3_NAME_LEN;
+       fsid = le64_to_cpup((void *)es->s_uuid) ^
+              le64_to_cpup((void *)es->s_uuid + sizeof(u64));
+       buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL;
+       buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL;
        return 0;
 }
 
@@ -2480,8 +2666,11 @@ static int ext3_release_dquot(struct dquot *dquot)
 
        handle = ext3_journal_start(dquot_to_inode(dquot),
                                        EXT3_QUOTA_DEL_BLOCKS(dquot->dq_sb));
-       if (IS_ERR(handle))
+       if (IS_ERR(handle)) {
+               /* Release dquot anyway to avoid endless cycle in dqput() */
+               dquot_release(dquot);
                return PTR_ERR(handle);
+       }
        ret = dquot_release(dquot);
        err = ext3_journal_stop(handle);
        if (!ret)
@@ -2614,7 +2803,13 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type,
        struct buffer_head *bh;
        handle_t *handle = journal_current_handle();
 
-       mutex_lock(&inode->i_mutex);
+       if (!handle) {
+               printk(KERN_WARNING "EXT3-fs: Quota write (off=%Lu, len=%Lu)"
+                       " cancelled because transaction is not started.\n",
+                       (unsigned long long)off, (unsigned long long)len);
+               return -EIO;
+       }
+       mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
        while (towrite > 0) {
                tocopy = sb->s_blocksize - offset < towrite ?
                                sb->s_blocksize - offset : towrite;
@@ -2692,7 +2887,7 @@ static int __init init_ext3_fs(void)
 out:
        destroy_inodecache();
 out1:
-       exit_ext3_xattr();
+       exit_ext3_xattr();
        return err;
 }