diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-07 09:07:30 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-07 09:07:30 -0800 |
commit | b1e243957e9b3ba8e820fb8583bdf18e7c737aa2 (patch) | |
tree | c50e7f561426612570b15cf6df063df8751661fa /fs/btrfs/disk-io.c | |
parent | 0556161ff9069c938ca5409e1e102ac6f371a1c8 (diff) | |
parent | f65e25e343cfc0e6f4db9a687c4085fad268325d (diff) |
Merge tag 'for-5.1-part1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs updates from David Sterba:
"This contains usual mix of new features, core changes and fixes; full
list below. I'm planning second pull request, with a few more fixes
that arrived recently but too close to merge window, will send it next
week.
New features:
- support zstd compression levels
- new ioctl to unregister a device from the module (ie. reverse of
device scan)
- scrub prints a message to log when it's about to start or finish
Core changes:
- qgroups can now skip part of a tree that does not get updated
during relocation, because this does not affect the quota
accounting, estimated speedup in run time is about 20%
- the compression workspace management had to be enhanced due to zstd
requirements
- various enospc fixes, when there's high fragmentation the
over-reservation can cause ENOSPC that might not happen after a
flush, in such cases try to wait if the situation improves
Fixes:
- various ioctls could overwrite previous return value if
copy_to_user fails, fix this so the original error is reported
- more reclaim vs GFP_KERNEL fixes
- other cleanups and refactoring
- fix a (valid) lockdep warning in a test when device replace is
destroying worker threads
- make qgroup async transaction commit more aggressive, this avoids
some 'quota limit reached' errors if there are not enough data to
trigger transaction in order to flush
- fix deadlock between snapshot deletion and quotas when backref
walking is called from context that already holds the same locks
- fsync fixes:
- fix fsync after succession of renames of different files
- fix fsync after succession of renames and unlink/rmdir"
* tag 'for-5.1-part1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: (92 commits)
btrfs: Remove unnecessary casts in btrfs_read_root_item
Btrfs: remove assertion when searching for a key in a node/leaf
Btrfs: add missing error handling after doing leaf/node binary search
btrfs: drop the lock on error in btrfs_dev_replace_cancel
btrfs: ensure that a DUP or RAID1 block group has exactly two stripes
btrfs: init csum_list before possible free
Btrfs: remove no longer needed range length checks for deduplication
Btrfs: fix fsync after succession of renames and unlink/rmdir
Btrfs: fix fsync after succession of renames of different files
btrfs: honor path->skip_locking in backref code
btrfs: qgroup: Make qgroup async transaction commit more aggressive
btrfs: qgroup: Move reserved data accounting from btrfs_delayed_ref_head to btrfs_qgroup_extent_record
btrfs: scrub: remove unused nocow worker pointer
btrfs: scrub: add assertions for worker pointers
btrfs: scrub: convert scrub_workers_refcnt to refcount_t
btrfs: scrub: add scrub_lock lockdep check in scrub_workers_get
btrfs: scrub: fix circular locking dependency warning
btrfs: fix comment its device list mutex not volume lock
btrfs: extent_io: Kill the forward declaration of flush_write_bio
btrfs: Fix grossly misleading argument names in extent io search
...
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 39 |
1 files changed, 18 insertions, 21 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 6a2a2a951705..5216e7b3f9ad 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -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, @@ -1120,7 +1121,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 +1176,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 +1220,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 +1261,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 +1717,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 +2109,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 +2674,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 +2695,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 +2773,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); @@ -4238,16 +4247,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 +4265,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); |