Btrfs: remove empty block groups automatically
[cascardo/linux.git] / fs / btrfs / disk-io.c
index a1d36e6..4780e66 100644 (file)
@@ -348,9 +348,9 @@ static int verify_parent_transid(struct extent_io_tree *io_tree,
                ret = 0;
                goto out;
        }
-       printk_ratelimited("parent transid verify failed on %llu wanted %llu "
-                      "found %llu\n",
-                      eb->start, parent_transid, btrfs_header_generation(eb));
+       printk_ratelimited(KERN_INFO "BTRFS (device %s): parent transid verify failed on %llu wanted %llu found %llu\n",
+                       eb->fs_info->sb->s_id, eb->start,
+                       parent_transid, btrfs_header_generation(eb));
        ret = 1;
 
        /*
@@ -614,15 +614,15 @@ static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
 
        found_start = btrfs_header_bytenr(eb);
        if (found_start != eb->start) {
-               printk_ratelimited(KERN_INFO "BTRFS: bad tree block start "
+               printk_ratelimited(KERN_INFO "BTRFS (device %s): bad tree block start "
                               "%llu %llu\n",
-                              found_start, eb->start);
+                              eb->fs_info->sb->s_id, found_start, eb->start);
                ret = -EIO;
                goto err;
        }
        if (check_tree_block_fsid(root, eb)) {
-               printk_ratelimited(KERN_INFO "BTRFS: bad fsid on block %llu\n",
-                              eb->start);
+               printk_ratelimited(KERN_INFO "BTRFS (device %s): bad fsid on block %llu\n",
+                              eb->fs_info->sb->s_id, eb->start);
                ret = -EIO;
                goto err;
        }
@@ -713,7 +713,11 @@ static void end_workqueue_bio(struct bio *bio, int err)
                        func = btrfs_endio_write_helper;
                }
        } else {
-               if (end_io_wq->metadata == BTRFS_WQ_ENDIO_RAID56) {
+               if (unlikely(end_io_wq->metadata ==
+                            BTRFS_WQ_ENDIO_DIO_REPAIR)) {
+                       wq = fs_info->endio_repair_workers;
+                       func = btrfs_endio_repair_helper;
+               } else if (end_io_wq->metadata == BTRFS_WQ_ENDIO_RAID56) {
                        wq = fs_info->endio_raid56_workers;
                        func = btrfs_endio_raid56_helper;
                } else if (end_io_wq->metadata) {
@@ -741,6 +745,7 @@ int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio,
                        int metadata)
 {
        struct end_io_wq *end_io_wq;
+
        end_io_wq = kmalloc(sizeof(*end_io_wq), GFP_NOFS);
        if (!end_io_wq)
                return -ENOMEM;
@@ -1200,16 +1205,14 @@ btrfs_free_subvolume_writers(struct btrfs_subvolume_writers *writers)
        kfree(writers);
 }
 
-static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
-                        u32 stripesize, struct btrfs_root *root,
-                        struct btrfs_fs_info *fs_info,
+static void __setup_root(u32 nodesize, u32 sectorsize, u32 stripesize,
+                        struct btrfs_root *root, struct btrfs_fs_info *fs_info,
                         u64 objectid)
 {
        root->node = NULL;
        root->commit_root = NULL;
        root->sectorsize = sectorsize;
        root->nodesize = nodesize;
-       root->leafsize = leafsize;
        root->stripesize = stripesize;
        root->state = 0;
        root->orphan_cleanup_state = 0;
@@ -1295,7 +1298,7 @@ struct btrfs_root *btrfs_alloc_dummy_root(void)
        root = btrfs_alloc_root(NULL);
        if (!root)
                return ERR_PTR(-ENOMEM);
-       __setup_root(4096, 4096, 4096, 4096, root, NULL, 1);
+       __setup_root(4096, 4096, 4096, root, NULL, 1);
        set_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state);
        root->alloc_bytenr = 0;
 
@@ -1318,14 +1321,13 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
        if (!root)
                return ERR_PTR(-ENOMEM);
 
-       __setup_root(tree_root->nodesize, tree_root->leafsize,
-                    tree_root->sectorsize, tree_root->stripesize,
-                    root, fs_info, objectid);
+       __setup_root(tree_root->nodesize, tree_root->sectorsize,
+               tree_root->stripesize, root, fs_info, objectid);
        root->root_key.objectid = objectid;
        root->root_key.type = BTRFS_ROOT_ITEM_KEY;
        root->root_key.offset = 0;
 
-       leaf = btrfs_alloc_free_block(trans, root, root->leafsize,
+       leaf = btrfs_alloc_free_block(trans, root, root->nodesize,
                                      0, objectid, NULL, 0, 0, 0);
        if (IS_ERR(leaf)) {
                ret = PTR_ERR(leaf);
@@ -1396,9 +1398,9 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans,
        if (!root)
                return ERR_PTR(-ENOMEM);
 
-       __setup_root(tree_root->nodesize, tree_root->leafsize,
-                    tree_root->sectorsize, tree_root->stripesize,
-                    root, fs_info, BTRFS_TREE_LOG_OBJECTID);
+       __setup_root(tree_root->nodesize, tree_root->sectorsize,
+                    tree_root->stripesize, root, fs_info,
+                    BTRFS_TREE_LOG_OBJECTID);
 
        root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID;
        root->root_key.type = BTRFS_ROOT_ITEM_KEY;
@@ -1413,7 +1415,7 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans,
         * updated (along with back refs to the log tree).
         */
 
-       leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0,
+       leaf = btrfs_alloc_free_block(trans, root, root->nodesize, 0,
                                      BTRFS_TREE_LOG_OBJECTID, NULL,
                                      0, 0, 0);
        if (IS_ERR(leaf)) {
@@ -1465,7 +1467,7 @@ int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
        btrfs_set_stack_inode_generation(inode_item, 1);
        btrfs_set_stack_inode_size(inode_item, 3);
        btrfs_set_stack_inode_nlink(inode_item, 1);
-       btrfs_set_stack_inode_nbytes(inode_item, root->leafsize);
+       btrfs_set_stack_inode_nbytes(inode_item, root->nodesize);
        btrfs_set_stack_inode_mode(inode_item, S_IFDIR | 0755);
 
        btrfs_set_root_node(&log_root->root_item, log_root->node);
@@ -1498,9 +1500,8 @@ static struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
                goto alloc_fail;
        }
 
-       __setup_root(tree_root->nodesize, tree_root->leafsize,
-                    tree_root->sectorsize, tree_root->stripesize,
-                    root, fs_info, key->objectid);
+       __setup_root(tree_root->nodesize, tree_root->sectorsize,
+               tree_root->stripesize, root, fs_info, key->objectid);
 
        ret = btrfs_find_root(tree_root, key, path,
                              &root->root_item, &root->root_key);
@@ -1511,7 +1512,7 @@ static struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
        }
 
        generation = btrfs_root_generation(&root->root_item);
-       blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
+       blocksize = root->nodesize;
        root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
                                     blocksize, generation);
        if (!root->node) {
@@ -1573,8 +1574,8 @@ int btrfs_init_fs_root(struct btrfs_root *root)
        root->subv_writers = writers;
 
        btrfs_init_free_ino_ctl(root);
-       spin_lock_init(&root->cache_lock);
-       init_waitqueue_head(&root->cache_wait);
+       spin_lock_init(&root->ino_cache_lock);
+       init_waitqueue_head(&root->ino_cache_wait);
 
        ret = get_anon_bdev(&root->anon_dev);
        if (ret)
@@ -1708,10 +1709,6 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits)
        return ret;
 }
 
-/*
- * If this fails, caller must call bdi_destroy() to get rid of the
- * bdi again.
- */
 static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi)
 {
        int err;
@@ -1772,6 +1769,7 @@ static int cleaner_kthread(void *arg)
                }
 
                btrfs_run_delayed_iputs(root);
+               btrfs_delete_unused_bgs(root->fs_info);
                again = btrfs_clean_one_deleted_snapshot(root);
                mutex_unlock(&root->fs_info->cleaner_mutex);
 
@@ -2063,6 +2061,7 @@ static void btrfs_stop_all_workers(struct btrfs_fs_info *fs_info)
        btrfs_destroy_workqueue(fs_info->endio_workers);
        btrfs_destroy_workqueue(fs_info->endio_meta_workers);
        btrfs_destroy_workqueue(fs_info->endio_raid56_workers);
+       btrfs_destroy_workqueue(fs_info->endio_repair_workers);
        btrfs_destroy_workqueue(fs_info->rmw_workers);
        btrfs_destroy_workqueue(fs_info->endio_meta_write_workers);
        btrfs_destroy_workqueue(fs_info->endio_write_workers);
@@ -2143,7 +2142,6 @@ int open_ctree(struct super_block *sb,
 {
        u32 sectorsize;
        u32 nodesize;
-       u32 leafsize;
        u32 blocksize;
        u32 stripesize;
        u64 generation;
@@ -2233,6 +2231,7 @@ int open_ctree(struct super_block *sb,
        spin_lock_init(&fs_info->super_lock);
        spin_lock_init(&fs_info->qgroup_op_lock);
        spin_lock_init(&fs_info->buffer_lock);
+       spin_lock_init(&fs_info->unused_bgs_lock);
        rwlock_init(&fs_info->tree_mod_log_lock);
        mutex_init(&fs_info->reloc_mutex);
        mutex_init(&fs_info->delalloc_root_mutex);
@@ -2242,6 +2241,7 @@ int open_ctree(struct super_block *sb,
        INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
        INIT_LIST_HEAD(&fs_info->space_info);
        INIT_LIST_HEAD(&fs_info->tree_mod_seq_list);
+       INIT_LIST_HEAD(&fs_info->unused_bgs);
        btrfs_mapping_init(&fs_info->mapping_tree);
        btrfs_init_block_rsv(&fs_info->global_block_rsv,
                             BTRFS_BLOCK_RSV_GLOBAL);
@@ -2389,7 +2389,7 @@ int open_ctree(struct super_block *sb,
                goto fail_alloc;
        }
 
-       __setup_root(4096, 4096, 4096, 4096, tree_root,
+       __setup_root(4096, 4096, 4096, tree_root,
                     fs_info, BTRFS_ROOT_TREE_OBJECTID);
 
        invalidate_bdev(fs_devices->latest_bdev);
@@ -2469,19 +2469,22 @@ int open_ctree(struct super_block *sb,
                goto fail_alloc;
        }
 
-       if (btrfs_super_leafsize(disk_super) !=
+       /*
+        * Leafsize and nodesize were always equal, this is only a sanity check.
+        */
+       if (le32_to_cpu(disk_super->__unused_leafsize) !=
            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));
+                      le32_to_cpu(disk_super->__unused_leafsize));
                err = -EINVAL;
                goto fail_alloc;
        }
-       if (btrfs_super_leafsize(disk_super) > BTRFS_MAX_METADATA_BLOCKSIZE) {
+       if (btrfs_super_nodesize(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));
+                      btrfs_super_nodesize(disk_super));
                err = -EINVAL;
                goto fail_alloc;
        }
@@ -2498,17 +2501,16 @@ int open_ctree(struct super_block *sb,
         * 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 (btrfs_super_nodesize(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->dirty_metadata_batch = nodesize * (1 + ilog2(nr_cpu_ids));
        fs_info->delalloc_batch = sectorsize * 512 * (1 + ilog2(nr_cpu_ids));
 
        /*
@@ -2516,7 +2518,7 @@ int open_ctree(struct super_block *sb,
         * extent buffers for the same range.  It leads to corruptions
         */
        if ((features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) &&
-           (sectorsize != leafsize)) {
+           (sectorsize != nodesize)) {
                printk(KERN_WARNING "BTRFS: unequal leaf/node/sector sizes "
                                "are not allowed for mixed block groups on %s\n",
                                sb->s_id);
@@ -2579,6 +2581,8 @@ int open_ctree(struct super_block *sb,
                btrfs_alloc_workqueue("endio-meta-write", flags, max_active, 2);
        fs_info->endio_raid56_workers =
                btrfs_alloc_workqueue("endio-raid56", flags, max_active, 4);
+       fs_info->endio_repair_workers =
+               btrfs_alloc_workqueue("endio-repair", flags, 1, 0);
        fs_info->rmw_workers =
                btrfs_alloc_workqueue("rmw", flags, max_active, 2);
        fs_info->endio_write_workers =
@@ -2600,11 +2604,12 @@ int open_ctree(struct super_block *sb,
              fs_info->submit_workers && fs_info->flush_workers &&
              fs_info->endio_workers && fs_info->endio_meta_workers &&
              fs_info->endio_meta_write_workers &&
+             fs_info->endio_repair_workers &&
              fs_info->endio_write_workers && fs_info->endio_raid56_workers &&
              fs_info->endio_freespace_worker && fs_info->rmw_workers &&
              fs_info->caching_workers && fs_info->readahead_workers &&
              fs_info->fixup_workers && fs_info->delayed_workers &&
-             fs_info->fixup_workers && fs_info->extent_workers &&
+             fs_info->extent_workers &&
              fs_info->qgroup_rescan_workers)) {
                err = -ENOMEM;
                goto fail_sb_buffer;
@@ -2615,7 +2620,6 @@ int open_ctree(struct super_block *sb,
                                    4 * 1024 * 1024 / PAGE_CACHE_SIZE);
 
        tree_root->nodesize = nodesize;
-       tree_root->leafsize = leafsize;
        tree_root->sectorsize = sectorsize;
        tree_root->stripesize = stripesize;
 
@@ -2642,12 +2646,11 @@ int open_ctree(struct super_block *sb,
                goto fail_sb_buffer;
        }
 
-       blocksize = btrfs_level_size(tree_root,
-                                    btrfs_super_chunk_root_level(disk_super));
+       blocksize = tree_root->nodesize;
        generation = btrfs_super_chunk_root_generation(disk_super);
 
-       __setup_root(nodesize, leafsize, sectorsize, stripesize,
-                    chunk_root, fs_info, BTRFS_CHUNK_TREE_OBJECTID);
+       __setup_root(nodesize, sectorsize, stripesize, chunk_root,
+                    fs_info, BTRFS_CHUNK_TREE_OBJECTID);
 
        chunk_root->node = read_tree_block(chunk_root,
                                           btrfs_super_chunk_root(disk_super),
@@ -2684,8 +2687,7 @@ int open_ctree(struct super_block *sb,
        }
 
 retry_root_backup:
-       blocksize = btrfs_level_size(tree_root,
-                                    btrfs_super_root_level(disk_super));
+       blocksize = tree_root->nodesize;
        generation = btrfs_super_generation(disk_super);
 
        tree_root->node = read_tree_block(tree_root,
@@ -2859,9 +2861,7 @@ retry_root_backup:
                        err = -EIO;
                        goto fail_qgroup;
                }
-               blocksize =
-                    btrfs_level_size(tree_root,
-                                     btrfs_super_log_root_level(disk_super));
+               blocksize = tree_root->nodesize;
 
                log_tree_root = btrfs_alloc_root(fs_info);
                if (!log_tree_root) {
@@ -2869,7 +2869,7 @@ retry_root_backup:
                        goto fail_qgroup;
                }
 
-               __setup_root(nodesize, leafsize, sectorsize, stripesize,
+               __setup_root(nodesize, sectorsize, stripesize,
                             log_tree_root, fs_info, BTRFS_TREE_LOG_OBJECTID);
 
                log_tree_root->node = read_tree_block(tree_root, bytenr,
@@ -2980,6 +2980,8 @@ retry_root_backup:
                fs_info->update_uuid_tree_gen = 1;
        }
 
+       fs_info->open = 1;
+
        return 0;
 
 fail_qgroup:
@@ -3139,7 +3141,8 @@ static int write_dev_supers(struct btrfs_device *device,
 
        for (i = 0; i < max_mirrors; i++) {
                bytenr = btrfs_sb_offset(i);
-               if (bytenr + BTRFS_SUPER_INFO_SIZE >= device->total_bytes)
+               if (bytenr + BTRFS_SUPER_INFO_SIZE >=
+                   device->commit_total_bytes)
                        break;
 
                if (wait) {
@@ -3456,8 +3459,9 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors)
                btrfs_set_stack_device_type(dev_item, dev->type);
                btrfs_set_stack_device_id(dev_item, dev->devid);
                btrfs_set_stack_device_total_bytes(dev_item,
-                                                  dev->disk_total_bytes);
-               btrfs_set_stack_device_bytes_used(dev_item, dev->bytes_used);
+                                                  dev->commit_total_bytes);
+               btrfs_set_stack_device_bytes_used(dev_item,
+                                                 dev->commit_bytes_used);
                btrfs_set_stack_device_io_align(dev_item, dev->io_align);
                btrfs_set_stack_device_io_width(dev_item, dev->io_width);
                btrfs_set_stack_device_sector_size(dev_item, dev->sector_size);
@@ -3532,7 +3536,7 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
 
 static void free_fs_root(struct btrfs_root *root)
 {
-       iput(root->cache_inode);
+       iput(root->ino_cache_inode);
        WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree));
        btrfs_free_block_rsv(root, root->orphan_block_rsv);
        root->orphan_block_rsv = NULL;
@@ -3623,7 +3627,7 @@ int btrfs_commit_super(struct btrfs_root *root)
        return btrfs_commit_transaction(trans, root);
 }
 
-int close_ctree(struct btrfs_root *root)
+void close_ctree(struct btrfs_root *root)
 {
        struct btrfs_fs_info *fs_info = root->fs_info;
        int ret;
@@ -3689,6 +3693,7 @@ int close_ctree(struct btrfs_root *root)
        invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
        btrfs_stop_all_workers(fs_info);
 
+       fs_info->open = 0;
        free_root_pointers(fs_info, 1);
 
        iput(fs_info->btree_inode);
@@ -3711,8 +3716,6 @@ int close_ctree(struct btrfs_root *root)
 
        btrfs_free_block_rsv(root, root->orphan_block_rsv);
        root->orphan_block_rsv = NULL;
-
-       return 0;
 }
 
 int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid,
@@ -4010,8 +4013,8 @@ static int btrfs_destroy_marked_extents(struct btrfs_root *root,
                clear_extent_bits(dirty_pages, start, end, mark, GFP_NOFS);
                while (start <= end) {
                        eb = btrfs_find_tree_block(root, start,
-                                                  root->leafsize);
-                       start += root->leafsize;
+                                                  root->nodesize);
+                       start += root->nodesize;
                        if (!eb)
                                continue;
                        wait_on_extent_buffer_writeback(eb);