fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / fs / ext3 / super.c
index 26425a5..8353d33 100644 (file)
@@ -62,13 +62,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 +90,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 +159,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,7 +370,7 @@ 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");
@@ -378,7 +379,7 @@ static void dump_orphan_list(struct super_block *sb, struct ext3_sb_info *sbi)
                printk(KERN_ERR "  "
                       "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));
        }
 }
@@ -435,7 +436,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 +445,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
@@ -461,7 +462,7 @@ static void ext3_destroy_inode(struct inode *inode)
        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(void * foo, struct kmem_cache * cachep, unsigned long flags)
 {
        struct ext3_inode_info *ei = (struct ext3_inode_info *) foo;
 
@@ -475,7 +476,7 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
                inode_init_once(&ei->vfs_inode);
        }
 }
+
 static int init_inodecache(void)
 {
        ext3_inode_cachep = kmem_cache_create("ext3_inode_cache",
@@ -490,8 +491,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)
@@ -677,7 +677,7 @@ enum {
        Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
        Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
        Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
-       Opt_grpquota, Opt_tagxid
+       Opt_grpquota, Opt_tag, Opt_notag, Opt_tagid
 };
 
 static match_table_t tokens = {
@@ -727,15 +727,18 @@ static match_table_t tokens = {
        {Opt_quota, "quota"},
        {Opt_usrquota, "usrquota"},
        {Opt_barrier, "barrier=%u"},
-       {Opt_tagxid, "tagxid"},
+       {Opt_tag, "tag"},
+       {Opt_notag, "notag"},
+       {Opt_tagid, "tagid=%u"},
+       {Opt_tag, "tagxid"},
        {Opt_err, NULL},
        {Opt_resize, "resize"},
 };
 
 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 */
@@ -821,9 +824,18 @@ static int parse_options (char *options, struct super_block *sb,
                case Opt_nouid32:
                        set_opt (sbi->s_mount_opt, NO_UID32);
                        break;
-#ifndef CONFIG_INOXID_NONE
-               case Opt_tagxid:
-                       set_opt (sbi->s_mount_opt, TAGXID);
+#ifndef CONFIG_TAGGING_NONE
+               case Opt_tag:
+                       set_opt (sbi->s_mount_opt, TAGGED);
+                       break;
+               case Opt_notag:
+                       clear_opt (sbi->s_mount_opt, TAGGED);
+                       break;
+#endif
+#ifdef CONFIG_PROPAGATE
+               case Opt_tagid:
+                       /* use args[0] */
+                       set_opt (sbi->s_mount_opt, TAGGED);
                        break;
 #endif
                case Opt_nocheck:
@@ -1270,6 +1282,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, "
@@ -1347,8 +1365,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.
@@ -1412,11 +1428,10 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
        int needs_recovery;
        __le32 features;
 
-       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;
@@ -1462,10 +1477,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)
@@ -1477,6 +1496,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);
@@ -1487,8 +1508,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
                            NULL, 0))
                goto failed_mount;
 
-       if (EXT3_SB(sb)->s_mount_opt & EXT3_MOUNT_TAGXID)
-               sb->s_flags |= MS_TAGXID;
+       if (EXT3_SB(sb)->s_mount_opt & EXT3_MOUNT_TAGGED)
+               sb->s_flags |= MS_TAGGED;
 
        sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
                ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
@@ -1497,7 +1518,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");
        /*
@@ -1523,7 +1544,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;
@@ -1547,14 +1568,14 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
                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;
                }
@@ -1599,8 +1620,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;
@@ -1833,7 +1854,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)
 {
@@ -2305,9 +2326,9 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
 
        if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
                ext3_abort(sb, __FUNCTION__, "Abort forced by user");
-       if ((sbi->s_mount_opt & EXT3_MOUNT_TAGXID) &&
-               !(sb->s_flags & MS_TAGXID)) {
-               printk("EXT3-fs: %s: tagxid not permitted on remount.\n",
+       if ((sbi->s_mount_opt & EXT3_MOUNT_TAGGED) &&
+               !(sb->s_flags & MS_TAGGED)) {
+               printk("EXT3-fs: %s: tagging not permitted on remount.\n",
                        sb->s_id);
                return -EINVAL;
        }
@@ -2362,10 +2383,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;
                }
@@ -2403,6 +2422,7 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf)
        struct ext3_super_block *es = sbi->s_es;
        ext3_fsblk_t overhead;
        int i;
+       u64 fsid;
 
        if (test_opt (sb, MINIX_DF))
                overhead = 0;
@@ -2449,6 +2469,10 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf)
        buf->f_files = le32_to_cpu(es->s_inodes_count);
        buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter);
        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;
 }
 
@@ -2754,7 +2778,7 @@ static int __init init_ext3_fs(void)
 out:
        destroy_inodecache();
 out1:
-       exit_ext3_xattr();
+       exit_ext3_xattr();
        return err;
 }