BUG_ON() Conversion in fs/dquot.c
[safe/jmp/linux-2.6] / fs / ext3 / super.c
index 9e24ceb..f8a5266 100644 (file)
 #include <linux/namei.h>
 #include <linux/quotaops.h>
 #include <linux/seq_file.h>
+
 #include <asm/uaccess.h>
+
 #include "xattr.h"
 #include "acl.h"
+#include "namei.h"
 
-static int ext3_load_journal(struct super_block *, struct ext3_super_block *);
+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);
 static void ext3_commit_super (struct super_block * sb,
@@ -468,7 +472,7 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
 #ifdef CONFIG_EXT3_FS_XATTR
                init_rwsem(&ei->xattr_sem);
 #endif
-               init_MUTEX(&ei->truncate_sem);
+               mutex_init(&ei->truncate_mutex);
                inode_init_once(&ei->vfs_inode);
        }
 }
@@ -477,7 +481,8 @@ static int init_inodecache(void)
 {
        ext3_inode_cachep = kmem_cache_create("ext3_inode_cache",
                                             sizeof(struct ext3_inode_info),
-                                            0, SLAB_RECLAIM_ACCOUNT,
+                                            0, (SLAB_RECLAIM_ACCOUNT|
+                                               SLAB_MEM_SPREAD),
                                             init_once, NULL);
        if (ext3_inode_cachep == NULL)
                return -ENOMEM;
@@ -510,19 +515,11 @@ static void ext3_clear_inode(struct inode *inode)
        kfree(rsv);
 }
 
-static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
+static inline void ext3_show_quota_options(struct seq_file *seq, struct super_block *sb)
 {
-       struct super_block *sb = vfs->mnt_sb;
+#if defined(CONFIG_QUOTA)
        struct ext3_sb_info *sbi = EXT3_SB(sb);
 
-       if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA)
-               seq_puts(seq, ",data=journal");
-       else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA)
-               seq_puts(seq, ",data=ordered");
-       else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)
-               seq_puts(seq, ",data=writeback");
-
-#if defined(CONFIG_QUOTA)
        if (sbi->s_jquota_fmt)
                seq_printf(seq, ",jqfmt=%s",
                (sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold": "vfsv0");
@@ -539,6 +536,20 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
        if (sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA)
                seq_puts(seq, ",grpquota");
 #endif
+}
+
+static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
+{
+       struct super_block *sb = vfs->mnt_sb;
+
+       if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA)
+               seq_puts(seq, ",data=journal");
+       else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA)
+               seq_puts(seq, ",data=ordered");
+       else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)
+               seq_puts(seq, ",data=writeback");
+
+       ext3_show_quota_options(seq, sb);
 
        return 0;
 }
@@ -609,7 +620,6 @@ static struct super_operations ext3_sops = {
 #endif
 };
 
-struct dentry *ext3_get_parent(struct dentry *child);
 static struct export_operations ext3_export_ops = {
        .get_parent = ext3_get_parent,
 };
@@ -617,10 +627,10 @@ static struct export_operations ext3_export_ops = {
 enum {
        Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
        Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
-       Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
+       Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
        Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
        Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh,
-       Opt_commit, Opt_journal_update, Opt_journal_inum,
+       Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev,
        Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
        Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
        Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
@@ -644,7 +654,6 @@ static match_table_t tokens = {
        {Opt_nouid32, "nouid32"},
        {Opt_nocheck, "nocheck"},
        {Opt_nocheck, "check=none"},
-       {Opt_check, "check"},
        {Opt_debug, "debug"},
        {Opt_oldalloc, "oldalloc"},
        {Opt_orlov, "orlov"},
@@ -659,6 +668,7 @@ static match_table_t tokens = {
        {Opt_commit, "commit=%u"},
        {Opt_journal_update, "journal=update"},
        {Opt_journal_inum, "journal=%u"},
+       {Opt_journal_dev, "journal_dev=%u"},
        {Opt_abort, "abort"},
        {Opt_data_journal, "data=journal"},
        {Opt_data_ordered, "data=ordered"},
@@ -698,8 +708,9 @@ static unsigned long get_sb_block(void **data)
        return sb_block;
 }
 
-static int parse_options (char * options, struct super_block *sb,
-                         unsigned long * inum, unsigned long *n_blocks_count, int is_remount)
+static int parse_options (char *options, struct super_block *sb,
+                         unsigned long *inum, unsigned long *journal_devnum,
+                         unsigned long *n_blocks_count, int is_remount)
 {
        struct ext3_sb_info *sbi = EXT3_SB(sb);
        char * p;
@@ -765,14 +776,6 @@ static int parse_options (char * options, struct super_block *sb,
                case Opt_nouid32:
                        set_opt (sbi->s_mount_opt, NO_UID32);
                        break;
-               case Opt_check:
-#ifdef CONFIG_EXT3_CHECK
-                       set_opt (sbi->s_mount_opt, CHECK);
-#else
-                       printk(KERN_ERR
-                              "EXT3 Check option not supported\n");
-#endif
-                       break;
                case Opt_nocheck:
                        clear_opt (sbi->s_mount_opt, CHECK);
                        break;
@@ -840,6 +843,16 @@ static int parse_options (char * options, struct super_block *sb,
                                return 0;
                        *inum = option;
                        break;
+               case Opt_journal_dev:
+                       if (is_remount) {
+                               printk(KERN_ERR "EXT3-fs: cannot specify "
+                                      "journal on remount\n");
+                               return 0;
+                       }
+                       if (match_int(&args[0], &option))
+                               return 0;
+                       *journal_devnum = option;
+                       break;
                case Opt_noload:
                        set_opt (sbi->s_mount_opt, NOLOAD);
                        break;
@@ -1107,12 +1120,6 @@ static int ext3_setup_super(struct super_block *sb, struct ext3_super_block *es,
        } else {
                printk("internal journal\n");
        }
-#ifdef CONFIG_EXT3_CHECK
-       if (test_opt (sb, CHECK)) {
-               ext3_check_blocks_bitmap (sb);
-               ext3_check_inodes_bitmap (sb);
-       }
-#endif
        return res;
 }
 
@@ -1338,6 +1345,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
        unsigned long logic_sb_block;
        unsigned long offset = 0;
        unsigned long journal_inum = 0;
+       unsigned long journal_devnum = 0;
        unsigned long def_mount_opts;
        struct inode *root;
        int blocksize;
@@ -1418,7 +1426,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
 
        set_opt(sbi->s_mount_opt, RESERVATION);
 
-       if (!parse_options ((char *) data, sb, &journal_inum, NULL, 0))
+       if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum,
+                           NULL, 0))
                goto failed_mount;
 
        sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
@@ -1629,7 +1638,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
         */
        if (!test_opt(sb, NOLOAD) &&
            EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
-               if (ext3_load_journal(sb, es))
+               if (ext3_load_journal(sb, es, journal_devnum))
                        goto failed_mount2;
        } else if (journal_inum) {
                if (ext3_create_journal(sb, es, journal_inum))
@@ -1669,12 +1678,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
        }
 
        if (test_opt(sb, NOBH)) {
-               if (sb->s_blocksize_bits != PAGE_CACHE_SHIFT) {
-                       printk(KERN_WARNING "EXT3-fs: Ignoring nobh option "
-                               "since filesystem blocksize doesn't match "
-                               "pagesize\n");
-                       clear_opt(sbi->s_mount_opt, NOBH);
-               }
                if (!(test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)) {
                        printk(KERN_WARNING "EXT3-fs: Ignoring nobh option - "
                                "its supported only with writeback mode\n");
@@ -1909,15 +1912,24 @@ out_bdev:
        return NULL;
 }
 
-static int ext3_load_journal(struct super_block * sb,
-                            struct ext3_super_block * es)
+static int ext3_load_journal(struct super_block *sb,
+                            struct ext3_super_block *es,
+                            unsigned long journal_devnum)
 {
        journal_t *journal;
        int journal_inum = le32_to_cpu(es->s_journal_inum);
-       dev_t journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
+       dev_t journal_dev;
        int err = 0;
        int really_read_only;
 
+       if (journal_devnum &&
+           journal_devnum != le32_to_cpu(es->s_journal_dev)) {
+               printk(KERN_INFO "EXT3-fs: external journal device major/minor "
+                       "numbers have changed\n");
+               journal_dev = new_decode_dev(journal_devnum);
+       } else
+               journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
+
        really_read_only = bdev_read_only(sb->s_bdev);
 
        /*
@@ -1976,6 +1988,16 @@ static int ext3_load_journal(struct super_block * sb,
 
        EXT3_SB(sb)->s_journal = journal;
        ext3_clear_journal_err(sb, es);
+
+       if (journal_devnum &&
+           journal_devnum != le32_to_cpu(es->s_journal_dev)) {
+               es->s_journal_dev = cpu_to_le32(journal_devnum);
+               sb->s_dirt = 1;
+
+               /* Make sure we flush the recovery flag to disk. */
+               ext3_commit_super(sb, es, 1);
+       }
+
        return 0;
 }
 
@@ -2123,7 +2145,7 @@ int ext3_force_commit(struct super_block *sb)
 
 static void ext3_write_super (struct super_block * sb)
 {
-       if (down_trylock(&sb->s_lock) == 0)
+       if (mutex_trylock(&sb->s_lock) != 0)
                BUG();
        sb->s_dirt = 0;
 }
@@ -2204,7 +2226,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
        /*
         * Allow the "check" option to be passed as a remount option.
         */
-       if (!parse_options(data, sb, NULL, &n_blocks_count, 1)) {
+       if (!parse_options(data, sb, NULL, NULL, &n_blocks_count, 1)) {
                err = -EINVAL;
                goto restore_opts;
        }
@@ -2298,7 +2320,8 @@ restore_opts:
 
 static int ext3_statfs (struct super_block * sb, struct kstatfs * buf)
 {
-       struct ext3_super_block *es = EXT3_SB(sb)->s_es;
+       struct ext3_sb_info *sbi = EXT3_SB(sb);
+       struct ext3_super_block *es = sbi->s_es;
        unsigned long overhead;
        int i;
 
@@ -2340,12 +2363,12 @@ static int ext3_statfs (struct super_block * sb, struct kstatfs * buf)
        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 = ext3_count_free_blocks (sb);
+       buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter);
        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 = ext3_count_free_inodes (sb);
+       buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter);
        buf->f_namelen = EXT3_NAME_LEN;
        return 0;
 }
@@ -2355,8 +2378,8 @@ static int ext3_statfs (struct super_block * sb, struct kstatfs * buf)
  * Process 1                         Process 2
  * ext3_create()                     quota_sync()
  *   journal_start()                   write_dquot()
- *   DQUOT_INIT()                        down(dqio_sem)
- *     down(dqio_sem)                    journal_start()
+ *   DQUOT_INIT()                        down(dqio_mutex)
+ *     down(dqio_mutex)                    journal_start()
  *
  */
 
@@ -2574,7 +2597,7 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type,
        struct buffer_head *bh;
        handle_t *handle = journal_current_handle();
 
-       down(&inode->i_sem);
+       mutex_lock(&inode->i_mutex);
        while (towrite > 0) {
                tocopy = sb->s_blocksize - offset < towrite ?
                                sb->s_blocksize - offset : towrite;
@@ -2617,7 +2640,7 @@ out:
        inode->i_version++;
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
        ext3_mark_inode_dirty(handle, inode);
-       up(&inode->i_sem);
+       mutex_unlock(&inode->i_mutex);
        return len - towrite;
 }