Commit 1be969f4 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-5.0-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba:
 "A handful of fixes (some of them in testing for a long time):

   - fix some test failures regarding cleanup after transaction abort

   - revert of a patch that could cause a deadlock

   - delayed iput fixes, that can help in ENOSPC situation when there's
     low space and a lot data to write"

* tag 'for-5.0-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: wakeup cleaner thread when adding delayed iput
  btrfs: run delayed iputs before committing
  btrfs: wait on ordered extents on abort cleanup
  btrfs: handle delayed ref head accounting cleanup in abort
  Revert "btrfs: balance dirty metadata pages in btrfs_finish_ordered_io"
parents 315a6d85 fd340d0f
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
struct btrfs_trans_handle; struct btrfs_trans_handle;
struct btrfs_transaction; struct btrfs_transaction;
struct btrfs_pending_snapshot; struct btrfs_pending_snapshot;
struct btrfs_delayed_ref_root;
extern struct kmem_cache *btrfs_trans_handle_cachep; extern struct kmem_cache *btrfs_trans_handle_cachep;
extern struct kmem_cache *btrfs_bit_radix_cachep; extern struct kmem_cache *btrfs_bit_radix_cachep;
extern struct kmem_cache *btrfs_path_cachep; extern struct kmem_cache *btrfs_path_cachep;
...@@ -786,6 +787,9 @@ enum { ...@@ -786,6 +787,9 @@ enum {
* main phase. The fs_info::balance_ctl is initialized. * main phase. The fs_info::balance_ctl is initialized.
*/ */
BTRFS_FS_BALANCE_RUNNING, BTRFS_FS_BALANCE_RUNNING,
/* Indicate that the cleaner thread is awake and doing something. */
BTRFS_FS_CLEANER_RUNNING,
}; };
struct btrfs_fs_info { struct btrfs_fs_info {
...@@ -2661,6 +2665,9 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, ...@@ -2661,6 +2665,9 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
unsigned long count); unsigned long count);
int btrfs_async_run_delayed_refs(struct btrfs_fs_info *fs_info, int btrfs_async_run_delayed_refs(struct btrfs_fs_info *fs_info,
unsigned long count, u64 transid, int wait); unsigned long count, u64 transid, int wait);
void btrfs_cleanup_ref_head_accounting(struct btrfs_fs_info *fs_info,
struct btrfs_delayed_ref_root *delayed_refs,
struct btrfs_delayed_ref_head *head);
int btrfs_lookup_data_extent(struct btrfs_fs_info *fs_info, u64 start, u64 len); int btrfs_lookup_data_extent(struct btrfs_fs_info *fs_info, u64 start, u64 len);
int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, u64 bytenr, struct btrfs_fs_info *fs_info, u64 bytenr,
......
...@@ -1682,6 +1682,8 @@ static int cleaner_kthread(void *arg) ...@@ -1682,6 +1682,8 @@ static int cleaner_kthread(void *arg)
while (1) { while (1) {
again = 0; again = 0;
set_bit(BTRFS_FS_CLEANER_RUNNING, &fs_info->flags);
/* Make the cleaner go to sleep early. */ /* Make the cleaner go to sleep early. */
if (btrfs_need_cleaner_sleep(fs_info)) if (btrfs_need_cleaner_sleep(fs_info))
goto sleep; goto sleep;
...@@ -1728,6 +1730,7 @@ static int cleaner_kthread(void *arg) ...@@ -1728,6 +1730,7 @@ static int cleaner_kthread(void *arg)
*/ */
btrfs_delete_unused_bgs(fs_info); btrfs_delete_unused_bgs(fs_info);
sleep: sleep:
clear_bit(BTRFS_FS_CLEANER_RUNNING, &fs_info->flags);
if (kthread_should_park()) if (kthread_should_park())
kthread_parkme(); kthread_parkme();
if (kthread_should_stop()) if (kthread_should_stop())
...@@ -4201,6 +4204,14 @@ static void btrfs_destroy_all_ordered_extents(struct btrfs_fs_info *fs_info) ...@@ -4201,6 +4204,14 @@ static void btrfs_destroy_all_ordered_extents(struct btrfs_fs_info *fs_info)
spin_lock(&fs_info->ordered_root_lock); spin_lock(&fs_info->ordered_root_lock);
} }
spin_unlock(&fs_info->ordered_root_lock); spin_unlock(&fs_info->ordered_root_lock);
/*
* We need this here because if we've been flipped read-only we won't
* get sync() from the umount, so we need to make sure any ordered
* extents that haven't had their dirty pages IO start writeout yet
* actually get run and error out properly.
*/
btrfs_wait_ordered_roots(fs_info, U64_MAX, 0, (u64)-1);
} }
static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
...@@ -4265,6 +4276,7 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, ...@@ -4265,6 +4276,7 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
if (pin_bytes) if (pin_bytes)
btrfs_pin_extent(fs_info, head->bytenr, btrfs_pin_extent(fs_info, head->bytenr,
head->num_bytes, 1); head->num_bytes, 1);
btrfs_cleanup_ref_head_accounting(fs_info, delayed_refs, head);
btrfs_put_delayed_ref_head(head); btrfs_put_delayed_ref_head(head);
cond_resched(); cond_resched();
spin_lock(&delayed_refs->lock); spin_lock(&delayed_refs->lock);
......
...@@ -2456,12 +2456,10 @@ static int run_and_cleanup_extent_op(struct btrfs_trans_handle *trans, ...@@ -2456,12 +2456,10 @@ static int run_and_cleanup_extent_op(struct btrfs_trans_handle *trans,
return ret ? ret : 1; return ret ? ret : 1;
} }
static void cleanup_ref_head_accounting(struct btrfs_trans_handle *trans, void btrfs_cleanup_ref_head_accounting(struct btrfs_fs_info *fs_info,
struct btrfs_delayed_ref_head *head) struct btrfs_delayed_ref_root *delayed_refs,
struct btrfs_delayed_ref_head *head)
{ {
struct btrfs_fs_info *fs_info = trans->fs_info;
struct btrfs_delayed_ref_root *delayed_refs =
&trans->transaction->delayed_refs;
int nr_items = 1; /* Dropping this ref head update. */ int nr_items = 1; /* Dropping this ref head update. */
if (head->total_ref_mod < 0) { if (head->total_ref_mod < 0) {
...@@ -2544,7 +2542,7 @@ static int cleanup_ref_head(struct btrfs_trans_handle *trans, ...@@ -2544,7 +2542,7 @@ static int cleanup_ref_head(struct btrfs_trans_handle *trans,
} }
} }
cleanup_ref_head_accounting(trans, head); btrfs_cleanup_ref_head_accounting(fs_info, delayed_refs, head);
trace_run_delayed_ref_head(fs_info, head, 0); trace_run_delayed_ref_head(fs_info, head, 0);
btrfs_delayed_ref_unlock(head); btrfs_delayed_ref_unlock(head);
...@@ -4954,6 +4952,15 @@ static void flush_space(struct btrfs_fs_info *fs_info, ...@@ -4954,6 +4952,15 @@ static void flush_space(struct btrfs_fs_info *fs_info,
ret = 0; ret = 0;
break; break;
case COMMIT_TRANS: case COMMIT_TRANS:
/*
* If we have pending delayed iputs then we could free up a
* bunch of pinned space, so make sure we run the iputs before
* we do our pinned bytes check below.
*/
mutex_lock(&fs_info->cleaner_delayed_iput_mutex);
btrfs_run_delayed_iputs(fs_info);
mutex_unlock(&fs_info->cleaner_delayed_iput_mutex);
ret = may_commit_transaction(fs_info, space_info); ret = may_commit_transaction(fs_info, space_info);
break; break;
default: default:
...@@ -7188,7 +7195,7 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans, ...@@ -7188,7 +7195,7 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans,
if (head->must_insert_reserved) if (head->must_insert_reserved)
ret = 1; ret = 1;
cleanup_ref_head_accounting(trans, head); btrfs_cleanup_ref_head_accounting(trans->fs_info, delayed_refs, head);
mutex_unlock(&head->mutex); mutex_unlock(&head->mutex);
btrfs_put_delayed_ref_head(head); btrfs_put_delayed_ref_head(head);
return ret; return ret;
......
...@@ -3129,9 +3129,6 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent) ...@@ -3129,9 +3129,6 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
/* once for the tree */ /* once for the tree */
btrfs_put_ordered_extent(ordered_extent); btrfs_put_ordered_extent(ordered_extent);
/* Try to release some metadata so we don't get an OOM but don't wait */
btrfs_btree_balance_dirty_nodelay(fs_info);
return ret; return ret;
} }
...@@ -3254,6 +3251,8 @@ void btrfs_add_delayed_iput(struct inode *inode) ...@@ -3254,6 +3251,8 @@ void btrfs_add_delayed_iput(struct inode *inode)
ASSERT(list_empty(&binode->delayed_iput)); ASSERT(list_empty(&binode->delayed_iput));
list_add_tail(&binode->delayed_iput, &fs_info->delayed_iputs); list_add_tail(&binode->delayed_iput, &fs_info->delayed_iputs);
spin_unlock(&fs_info->delayed_iput_lock); spin_unlock(&fs_info->delayed_iput_lock);
if (!test_bit(BTRFS_FS_CLEANER_RUNNING, &fs_info->flags))
wake_up_process(fs_info->cleaner_kthread);
} }
void btrfs_run_delayed_iputs(struct btrfs_fs_info *fs_info) void btrfs_run_delayed_iputs(struct btrfs_fs_info *fs_info)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment