]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/btrfs/disk-io.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[linux.git] / fs / btrfs / disk-io.c
index 6a2a2a9517058b429b286557fd0a2b1a512c833d..6fe9197f6ee44c54a726435da5a83ac4a7490ac1 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/semaphore.h>
 #include <linux/error-injection.h>
 #include <linux/crc32c.h>
+#include <linux/sched/mm.h>
 #include <asm/unaligned.h>
 #include "ctree.h"
 #include "disk-io.h"
@@ -341,7 +342,7 @@ static int verify_parent_transid(struct extent_io_tree *io_tree,
 
        if (need_lock) {
                btrfs_tree_read_lock(eb);
-               btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
+               btrfs_set_lock_blocking_read(eb);
        }
 
        lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1,
@@ -832,9 +833,10 @@ static blk_status_t btree_csum_one_bio(struct bio *bio)
        struct bio_vec *bvec;
        struct btrfs_root *root;
        int i, ret = 0;
+       struct bvec_iter_all iter_all;
 
        ASSERT(!bio_flagged(bio, BIO_CLONED));
-       bio_for_each_segment_all(bvec, bio, i) {
+       bio_for_each_segment_all(bvec, bio, i, iter_all) {
                root = BTRFS_I(bvec->bv_page->mapping->host)->root;
                ret = csum_dirty_buffer(root->fs_info, bvec->bv_page);
                if (ret)
@@ -1120,7 +1122,7 @@ void clean_tree_block(struct btrfs_fs_info *fs_info,
                                                 -buf->len,
                                                 fs_info->dirty_metadata_batch);
                        /* ugh, clear_extent_buffer_dirty needs to lock the page */
-                       btrfs_set_lock_blocking(buf);
+                       btrfs_set_lock_blocking_write(buf);
                        clear_extent_buffer_dirty(buf);
                }
        }
@@ -1175,6 +1177,7 @@ static void __setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info,
        INIT_LIST_HEAD(&root->delalloc_root);
        INIT_LIST_HEAD(&root->ordered_extents);
        INIT_LIST_HEAD(&root->ordered_root);
+       INIT_LIST_HEAD(&root->reloc_dirty_list);
        INIT_LIST_HEAD(&root->logged_list[0]);
        INIT_LIST_HEAD(&root->logged_list[1]);
        spin_lock_init(&root->inode_lock);
@@ -1218,6 +1221,7 @@ static void __setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info,
        root->anon_dev = 0;
 
        spin_lock_init(&root->root_item_lock);
+       btrfs_qgroup_init_swapped_blocks(&root->swapped_blocks);
 }
 
 static struct btrfs_root *btrfs_alloc_root(struct btrfs_fs_info *fs_info,
@@ -1258,10 +1262,17 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
        struct btrfs_root *tree_root = fs_info->tree_root;
        struct btrfs_root *root;
        struct btrfs_key key;
+       unsigned int nofs_flag;
        int ret = 0;
        uuid_le uuid = NULL_UUID_LE;
 
+       /*
+        * We're holding a transaction handle, so use a NOFS memory allocation
+        * context to avoid deadlock if reclaim happens.
+        */
+       nofs_flag = memalloc_nofs_save();
        root = btrfs_alloc_root(fs_info, GFP_KERNEL);
+       memalloc_nofs_restore(nofs_flag);
        if (!root)
                return ERR_PTR(-ENOMEM);
 
@@ -1707,9 +1718,7 @@ static int cleaner_kthread(void *arg)
                        goto sleep;
                }
 
-               mutex_lock(&fs_info->cleaner_delayed_iput_mutex);
                btrfs_run_delayed_iputs(fs_info);
-               mutex_unlock(&fs_info->cleaner_delayed_iput_mutex);
 
                again = btrfs_clean_one_deleted_snapshot(root);
                mutex_unlock(&fs_info->cleaner_mutex);
@@ -2101,7 +2110,7 @@ static void btrfs_init_scrub(struct btrfs_fs_info *fs_info)
        atomic_set(&fs_info->scrubs_paused, 0);
        atomic_set(&fs_info->scrub_cancel_req, 0);
        init_waitqueue_head(&fs_info->scrub_pause_wait);
-       fs_info->scrub_workers_refcnt = 0;
+       refcount_set(&fs_info->scrub_workers_refcnt, 0);
 }
 
 static void btrfs_init_balance(struct btrfs_fs_info *fs_info)
@@ -2666,7 +2675,6 @@ int open_ctree(struct super_block *sb,
        mutex_init(&fs_info->delete_unused_bgs_mutex);
        mutex_init(&fs_info->reloc_mutex);
        mutex_init(&fs_info->delalloc_root_mutex);
-       mutex_init(&fs_info->cleaner_delayed_iput_mutex);
        seqlock_init(&fs_info->profiles_lock);
 
        INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
@@ -2688,6 +2696,7 @@ int open_ctree(struct super_block *sb,
        atomic_set(&fs_info->defrag_running, 0);
        atomic_set(&fs_info->qgroup_op_seq, 0);
        atomic_set(&fs_info->reada_works_cnt, 0);
+       atomic_set(&fs_info->nr_delayed_iputs, 0);
        atomic64_set(&fs_info->tree_mod_seq, 0);
        fs_info->sb = sb;
        fs_info->max_inline = BTRFS_DEFAULT_MAX_INLINE;
@@ -2765,6 +2774,7 @@ int open_ctree(struct super_block *sb,
        init_waitqueue_head(&fs_info->transaction_wait);
        init_waitqueue_head(&fs_info->transaction_blocked_wait);
        init_waitqueue_head(&fs_info->async_submit_wait);
+       init_waitqueue_head(&fs_info->delayed_iputs_wait);
 
        INIT_LIST_HEAD(&fs_info->pinned_chunks);
 
@@ -2948,7 +2958,7 @@ int open_ctree(struct super_block *sb,
        sb->s_bdi->congested_fn = btrfs_congested_fn;
        sb->s_bdi->congested_data = fs_info;
        sb->s_bdi->capabilities |= BDI_CAP_CGROUP_WRITEBACK;
-       sb->s_bdi->ra_pages = VM_MAX_READAHEAD * SZ_1K / PAGE_SIZE;
+       sb->s_bdi->ra_pages = VM_READAHEAD_PAGES;
        sb->s_bdi->ra_pages *= btrfs_super_num_devices(disk_super);
        sb->s_bdi->ra_pages = max(sb->s_bdi->ra_pages, SZ_4M / PAGE_SIZE);
 
@@ -4238,16 +4248,9 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
 
                head = rb_entry(node, struct btrfs_delayed_ref_head,
                                href_node);
-               if (!mutex_trylock(&head->mutex)) {
-                       refcount_inc(&head->refs);
-                       spin_unlock(&delayed_refs->lock);
-
-                       mutex_lock(&head->mutex);
-                       mutex_unlock(&head->mutex);
-                       btrfs_put_delayed_ref_head(head);
-                       spin_lock(&delayed_refs->lock);
+               if (btrfs_delayed_ref_lock(delayed_refs, head))
                        continue;
-               }
+
                spin_lock(&head->lock);
                while ((n = rb_first_cached(&head->ref_tree)) != NULL) {
                        ref = rb_entry(n, struct btrfs_delayed_ref_node,
@@ -4263,12 +4266,7 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
                if (head->must_insert_reserved)
                        pin_bytes = true;
                btrfs_free_delayed_extent_op(head->extent_op);
-               delayed_refs->num_heads--;
-               if (head->processing == 0)
-                       delayed_refs->num_heads_ready--;
-               atomic_dec(&delayed_refs->num_entries);
-               rb_erase_cached(&head->href_node, &delayed_refs->href_root);
-               RB_CLEAR_NODE(&head->href_node);
+               btrfs_delete_ref_head(delayed_refs, head);
                spin_unlock(&head->lock);
                spin_unlock(&delayed_refs->lock);
                mutex_unlock(&head->mutex);