]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - fs/btrfs/disk-io.c
Btrfs: Integrate metadata reservation with start_transaction
[net-next-2.6.git] / fs / btrfs / disk-io.c
index 11d0ad30e203c7ebecd9845d2989fe1c04311f60..054b4475c757ea91bc8bb54c9adffdedcab3a1fd 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/crc32c.h>
+#include <linux/slab.h>
 #include "compat.h"
 #include "ctree.h"
 #include "disk-io.h"
@@ -43,8 +44,6 @@ static struct extent_io_ops btree_extent_io_ops;
 static void end_workqueue_fn(struct btrfs_work *work);
 static void free_fs_root(struct btrfs_root *root);
 
-static atomic_t btrfs_bdi_num = ATOMIC_INIT(0);
-
 /*
  * end_io_wq structs are used to do processing in task context when an IO is
  * complete.  This is used during reads to verify checksums, and it is used
@@ -904,6 +903,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
        root->name = NULL;
        root->in_sysfs = 0;
        root->inode_tree = RB_ROOT;
+       root->block_rsv = NULL;
 
        INIT_LIST_HEAD(&root->dirty_list);
        INIT_LIST_HEAD(&root->orphan_list);
@@ -911,6 +911,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
        spin_lock_init(&root->node_lock);
        spin_lock_init(&root->list_lock);
        spin_lock_init(&root->inode_lock);
+       spin_lock_init(&root->accounting_lock);
        mutex_init(&root->objectid_mutex);
        mutex_init(&root->log_mutex);
        init_waitqueue_head(&root->log_writer_wait);
@@ -1374,19 +1375,11 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi)
 {
        int err;
 
-       bdi->name = "btrfs";
        bdi->capabilities = BDI_CAP_MAP_COPY;
-       err = bdi_init(bdi);
+       err = bdi_setup_and_register(bdi, "btrfs", BDI_CAP_MAP_COPY);
        if (err)
                return err;
 
-       err = bdi_register(bdi, NULL, "btrfs-%d",
-                               atomic_inc_return(&btrfs_bdi_num));
-       if (err) {
-               bdi_destroy(bdi);
-               return err;
-       }
-
        bdi->ra_pages   = default_backing_dev_info.ra_pages;
        bdi->unplug_io_fn       = btrfs_unplug_io_fn;
        bdi->unplug_io_data     = info;
@@ -1529,7 +1522,7 @@ static int transaction_kthread(void *arg)
                        goto sleep;
                }
                mutex_unlock(&root->fs_info->trans_mutex);
-               trans = btrfs_start_transaction(root, 1);
+               trans = btrfs_join_transaction(root, 1);
                ret = btrfs_commit_transaction(trans, root);
 
 sleep:
@@ -1629,12 +1622,18 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
        INIT_LIST_HEAD(&fs_info->space_info);
        btrfs_mapping_init(&fs_info->mapping_tree);
+       btrfs_init_block_rsv(&fs_info->global_block_rsv);
+       btrfs_init_block_rsv(&fs_info->delalloc_block_rsv);
+       btrfs_init_block_rsv(&fs_info->trans_block_rsv);
+       btrfs_init_block_rsv(&fs_info->chunk_block_rsv);
+       btrfs_init_block_rsv(&fs_info->empty_block_rsv);
+       INIT_LIST_HEAD(&fs_info->durable_block_rsv_list);
+       mutex_init(&fs_info->durable_block_rsv_mutex);
        atomic_set(&fs_info->nr_async_submits, 0);
        atomic_set(&fs_info->async_delalloc_pages, 0);
        atomic_set(&fs_info->async_submit_draining, 0);
        atomic_set(&fs_info->nr_async_bios, 0);
        fs_info->sb = sb;
-       fs_info->max_extent = (u64)-1;
        fs_info->max_inline = 8192 * 1024;
        fs_info->metadata_ratio = 0;
 
@@ -1769,9 +1768,6 @@ struct btrfs_root *open_ctree(struct super_block *sb,
                           min_t(u64, fs_devices->num_devices,
                           fs_info->thread_pool_size),
                           &fs_info->generic_worker);
-       btrfs_init_workers(&fs_info->enospc_workers, "enospc",
-                          fs_info->thread_pool_size,
-                          &fs_info->generic_worker);
 
        /* a higher idle thresh on the submit workers makes it much more
         * likely that bios will be send down in a sane order to the
@@ -1819,7 +1815,6 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        btrfs_start_workers(&fs_info->endio_meta_workers, 1);
        btrfs_start_workers(&fs_info->endio_meta_write_workers, 1);
        btrfs_start_workers(&fs_info->endio_write_workers, 1);
-       btrfs_start_workers(&fs_info->enospc_workers, 1);
 
        fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super);
        fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages,
@@ -1922,7 +1917,11 @@ struct btrfs_root *open_ctree(struct super_block *sb,
 
        csum_root->track_dirty = 1;
 
-       btrfs_read_block_groups(extent_root);
+       ret = btrfs_read_block_groups(extent_root);
+       if (ret) {
+               printk(KERN_ERR "Failed to read block groups: %d\n", ret);
+               goto fail_block_groups;
+       }
 
        fs_info->generation = generation;
        fs_info->last_trans_committed = generation;
@@ -1932,7 +1931,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root,
                                               "btrfs-cleaner");
        if (IS_ERR(fs_info->cleaner_kthread))
-               goto fail_csum_root;
+               goto fail_block_groups;
 
        fs_info->transaction_kthread = kthread_run(transaction_kthread,
                                                   tree_root,
@@ -2020,7 +2019,8 @@ fail_cleaner:
        filemap_write_and_wait(fs_info->btree_inode->i_mapping);
        invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
 
-fail_csum_root:
+fail_block_groups:
+       btrfs_free_block_groups(fs_info);
        free_extent_buffer(csum_root->node);
        free_extent_buffer(csum_root->commit_root);
 fail_dev_root:
@@ -2045,7 +2045,6 @@ fail_sb_buffer:
        btrfs_stop_workers(&fs_info->endio_meta_write_workers);
        btrfs_stop_workers(&fs_info->endio_write_workers);
        btrfs_stop_workers(&fs_info->submit_workers);
-       btrfs_stop_workers(&fs_info->enospc_workers);
 fail_iput:
        invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
        iput(fs_info->btree_inode);
@@ -2410,11 +2409,11 @@ int btrfs_commit_super(struct btrfs_root *root)
        down_write(&root->fs_info->cleanup_work_sem);
        up_write(&root->fs_info->cleanup_work_sem);
 
-       trans = btrfs_start_transaction(root, 1);
+       trans = btrfs_join_transaction(root, 1);
        ret = btrfs_commit_transaction(trans, root);
        BUG_ON(ret);
        /* run commit again to drop the original snapshot */
-       trans = btrfs_start_transaction(root, 1);
+       trans = btrfs_join_transaction(root, 1);
        btrfs_commit_transaction(trans, root);
        ret = btrfs_write_and_wait_transaction(NULL, root);
        BUG_ON(ret);
@@ -2478,7 +2477,6 @@ int close_ctree(struct btrfs_root *root)
        btrfs_stop_workers(&fs_info->endio_meta_write_workers);
        btrfs_stop_workers(&fs_info->endio_write_workers);
        btrfs_stop_workers(&fs_info->submit_workers);
-       btrfs_stop_workers(&fs_info->enospc_workers);
 
        btrfs_close_devices(fs_info->fs_devices);
        btrfs_mapping_tree_free(&fs_info->mapping_tree);