Move all the superblock flag & geometry testing & fiddling
into its own function.

This does coalesce some far-flung tests, but it ... looks
ok to me.

Signed-off-by: Eric Sandeen <sand...@redhat.com>
---
 fs/btrfs/disk-io.c |  207 ++++++++++++++++++++++++++++------------------------
 1 files changed, 112 insertions(+), 95 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 47fcacf..31e9791 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2209,6 +2209,104 @@ static void btrfs_qgroup_init(struct btrfs_fs_info 
*fs_info)
        mutex_init(&fs_info->qgroup_rescan_lock);
 }
 
+/*
+ * Test geometry and feature flags at mount time
+ */
+static int btrfs_setup_super(struct super_block *sb,
+                            struct btrfs_fs_info *fs_info)
+{
+       struct btrfs_super_block *disk_super = fs_info->super_copy;
+       u32 nodesize = btrfs_super_nodesize(disk_super);
+       u32 leafsize = btrfs_super_leafsize(disk_super);
+       u32 sectorsize = btrfs_super_sectorsize(disk_super);
+       u64 features;
+
+
+       /* First sanity check magic &  sizes */
+       if (btrfs_super_magic(disk_super) != BTRFS_MAGIC) {
+               printk(KERN_INFO "BTRFS: valid FS not found on %s\n", sb->s_id);
+               return -EINVAL;
+       }
+
+       if (leafsize != nodesize) {
+               printk(KERN_ERR "BTRFS: couldn't mount because metadata "
+                      "blocksizes don't match.  node %d leaf %d\n",
+                      nodesize, leafsize);
+               return -EINVAL;
+       }
+
+       if (leafsize > BTRFS_MAX_METADATA_BLOCKSIZE) {
+               printk(KERN_ERR "BTRFS: couldn't mount because metadata "
+                      "blocksize (%d) was too large\n", leafsize);
+               return -EINVAL;
+       }
+       
+       if (sectorsize != PAGE_SIZE) {
+               printk(KERN_WARNING "BTRFS: Incompatible sector size(%lu) "
+                      "found on %s\n", (unsigned long)sectorsize, sb->s_id);
+               return -EINVAL;
+       }
+
+       /* check FS state, whether FS is broken. */
+       if (btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_ERROR)
+               set_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state);
+
+       features = btrfs_super_incompat_flags(disk_super);
+       if (features & ~BTRFS_FEATURE_INCOMPAT_SUPP) {
+               printk(KERN_ERR "BTRFS: couldn't mount because of "
+                      "unsupported optional features (%Lx).\n",
+                      features & ~BTRFS_FEATURE_INCOMPAT_SUPP);
+               return -EINVAL;
+       }
+
+       features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF;
+       /* Original LZO commit didn't set incompat flag when mounted :( */
+       if (fs_info->compress_type == BTRFS_COMPRESS_LZO)
+               features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO;
+
+       if (features & BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA)
+               printk(KERN_ERR "BTRFS: has skinny extents\n");
+
+       /*
+        * flag our filesystem as having big metadata blocks if
+        * they are bigger than the page size
+        */
+       if (leafsize > PAGE_CACHE_SIZE) {
+               if (!(features & BTRFS_FEATURE_INCOMPAT_BIG_METADATA))
+                       printk(KERN_INFO "BTRFS: flagging fs with big metadata 
feature\n");
+               features |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA;
+       }
+
+       /*
+        * mixed block groups end up with duplicate but slightly offset
+        * extent buffers for the same range.  It leads to corruptions
+        */
+       if ((features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) &&
+           (sectorsize != leafsize)) {
+               printk(KERN_WARNING "BTRFS: unequal leaf/node/sector sizes "
+                               "are not allowed for mixed block groups on 
%s\n",
+                               sb->s_id);
+               return -EINVAL;
+       }
+
+       /*
+        * Needn't use the lock because there is no other task which will
+        * update the flag.
+        */
+       btrfs_set_super_incompat_flags(disk_super, features);
+
+       features = btrfs_super_compat_ro_flags(disk_super) &
+               ~BTRFS_FEATURE_COMPAT_RO_SUPP;
+       if (!(sb->s_flags & MS_RDONLY) && features) {
+               printk(KERN_ERR "BTRFS: couldn't mount RDWR because of "
+                      "unsupported option features (%Lx).\n",
+                      features);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 int open_ctree(struct super_block *sb,
               struct btrfs_fs_devices *fs_devices,
               char *options)
@@ -2219,7 +2317,6 @@ int open_ctree(struct super_block *sb,
        u32 blocksize;
        u32 stripesize;
        u64 generation;
-       u64 features;
        struct btrfs_key location;
        struct buffer_head *bh;
        struct btrfs_super_block *disk_super;
@@ -2458,10 +2555,6 @@ int open_ctree(struct super_block *sb,
        if (!btrfs_super_root(disk_super))
                goto fail_alloc;
 
-       /* check FS state, whether FS is broken. */
-       if (btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_ERROR)
-               set_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state);
-
        /*
         * run through our array of backup supers and setup
         * our ring pointer to the oldest one
@@ -2469,6 +2562,12 @@ int open_ctree(struct super_block *sb,
        generation = btrfs_super_generation(disk_super);
        find_oldest_super_backup(fs_info, generation);
 
+       ret = btrfs_setup_super(sb, fs_info);
+       if (ret) {
+               err = ret;
+               goto fail_alloc;
+       }
+
        /*
         * In the long term, we'll store the compression type in the super
         * block, and it'll be used for per file compression control.
@@ -2481,86 +2580,6 @@ int open_ctree(struct super_block *sb,
                goto fail_alloc;
        }
 
-       features = btrfs_super_incompat_flags(disk_super) &
-               ~BTRFS_FEATURE_INCOMPAT_SUPP;
-       if (features) {
-               printk(KERN_ERR "BTRFS: couldn't mount because of "
-                      "unsupported optional features (%Lx).\n",
-                      features);
-               err = -EINVAL;
-               goto fail_alloc;
-       }
-
-       if (btrfs_super_leafsize(disk_super) !=
-           btrfs_super_nodesize(disk_super)) {
-               printk(KERN_ERR "BTRFS: couldn't mount because metadata "
-                      "blocksizes don't match.  node %d leaf %d\n",
-                      btrfs_super_nodesize(disk_super),
-                      btrfs_super_leafsize(disk_super));
-               err = -EINVAL;
-               goto fail_alloc;
-       }
-       if (btrfs_super_leafsize(disk_super) > BTRFS_MAX_METADATA_BLOCKSIZE) {
-               printk(KERN_ERR "BTRFS: couldn't mount because metadata "
-                      "blocksize (%d) was too large\n",
-                      btrfs_super_leafsize(disk_super));
-               err = -EINVAL;
-               goto fail_alloc;
-       }
-
-       features = btrfs_super_incompat_flags(disk_super);
-       features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF;
-       if (tree_root->fs_info->compress_type == BTRFS_COMPRESS_LZO)
-               features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO;
-
-       if (features & BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA)
-               printk(KERN_ERR "BTRFS: has skinny extents\n");
-
-       /*
-        * flag our filesystem as having big metadata blocks if
-        * they are bigger than the page size
-        */
-       if (btrfs_super_leafsize(disk_super) > PAGE_CACHE_SIZE) {
-               if (!(features & BTRFS_FEATURE_INCOMPAT_BIG_METADATA))
-                       printk(KERN_INFO "BTRFS: flagging fs with big metadata 
feature\n");
-               features |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA;
-       }
-
-       nodesize = btrfs_super_nodesize(disk_super);
-       leafsize = btrfs_super_leafsize(disk_super);
-       sectorsize = btrfs_super_sectorsize(disk_super);
-       stripesize = btrfs_super_stripesize(disk_super);
-       fs_info->dirty_metadata_batch = leafsize * (1 + ilog2(nr_cpu_ids));
-       fs_info->delalloc_batch = sectorsize * 512 * (1 + ilog2(nr_cpu_ids));
-
-       /*
-        * mixed block groups end up with duplicate but slightly offset
-        * extent buffers for the same range.  It leads to corruptions
-        */
-       if ((features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) &&
-           (sectorsize != leafsize)) {
-               printk(KERN_WARNING "BTRFS: unequal leaf/node/sector sizes "
-                               "are not allowed for mixed block groups on 
%s\n",
-                               sb->s_id);
-               goto fail_alloc;
-       }
-
-       /*
-        * Needn't use the lock because there is no other task which will
-        * update the flag.
-        */
-       btrfs_set_super_incompat_flags(disk_super, features);
-
-       features = btrfs_super_compat_ro_flags(disk_super) &
-               ~BTRFS_FEATURE_COMPAT_RO_SUPP;
-       if (!(sb->s_flags & MS_RDONLY) && features) {
-               printk(KERN_ERR "BTRFS: couldn't mount RDWR because of "
-                      "unsupported option features (%Lx).\n",
-                      features);
-               err = -EINVAL;
-               goto fail_alloc;
-       }
-
        max_active = fs_info->thread_pool_size;
 
        fs_info->workers =
@@ -2636,6 +2655,14 @@ int open_ctree(struct super_block *sb,
        fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages,
                                    4 * 1024 * 1024 / PAGE_CACHE_SIZE);
 
+       nodesize = btrfs_super_nodesize(disk_super);
+       leafsize = btrfs_super_leafsize(disk_super);
+       sectorsize = btrfs_super_sectorsize(disk_super);
+       stripesize = btrfs_super_stripesize(disk_super);
+
+       fs_info->dirty_metadata_batch = leafsize * (1 + ilog2(nr_cpu_ids));
+       fs_info->delalloc_batch = sectorsize * 512 * (1 + ilog2(nr_cpu_ids));
+
        tree_root->nodesize = nodesize;
        tree_root->leafsize = leafsize;
        tree_root->sectorsize = sectorsize;
@@ -2644,16 +2671,6 @@ int open_ctree(struct super_block *sb,
        sb->s_blocksize = sectorsize;
        sb->s_blocksize_bits = blksize_bits(sectorsize);
 
-       if (btrfs_super_magic(disk_super) != BTRFS_MAGIC) {
-               printk(KERN_INFO "BTRFS: valid FS not found on %s\n", sb->s_id);
-               goto fail_sb_buffer;
-       }
-
-       if (sectorsize != PAGE_SIZE) {
-               printk(KERN_WARNING "BTRFS: Incompatible sector size(%lu) "
-                      "found on %s\n", (unsigned long)sectorsize, sb->s_id);
-               goto fail_sb_buffer;
-       }
 
        mutex_lock(&fs_info->chunk_mutex);
        ret = btrfs_read_sys_array(tree_root);
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to