Commit 1be969f4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
struct btrfs_trans_handle;
struct btrfs_transaction;
struct btrfs_pending_snapshot;
struct btrfs_delayed_ref_root;
extern struct kmem_cache *btrfs_trans_handle_cachep;
extern struct kmem_cache *btrfs_bit_radix_cachep;
extern struct kmem_cache *btrfs_path_cachep;
@@ -786,6 +787,9 @@ enum {
	 * main phase. The fs_info::balance_ctl is initialized.
	 */
	BTRFS_FS_BALANCE_RUNNING,

	/* Indicate that the cleaner thread is awake and doing something. */
	BTRFS_FS_CLEANER_RUNNING,
};

struct btrfs_fs_info {
@@ -2661,6 +2665,9 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
			   unsigned long count);
int btrfs_async_run_delayed_refs(struct btrfs_fs_info *fs_info,
				 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_extent_info(struct btrfs_trans_handle *trans,
			     struct btrfs_fs_info *fs_info, u64 bytenr,
+12 −0
Original line number Diff line number Diff line
@@ -1682,6 +1682,8 @@ static int cleaner_kthread(void *arg)
	while (1) {
		again = 0;

		set_bit(BTRFS_FS_CLEANER_RUNNING, &fs_info->flags);

		/* Make the cleaner go to sleep early. */
		if (btrfs_need_cleaner_sleep(fs_info))
			goto sleep;
@@ -1728,6 +1730,7 @@ static int cleaner_kthread(void *arg)
		 */
		btrfs_delete_unused_bgs(fs_info);
sleep:
		clear_bit(BTRFS_FS_CLEANER_RUNNING, &fs_info->flags);
		if (kthread_should_park())
			kthread_parkme();
		if (kthread_should_stop())
@@ -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_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,
@@ -4265,6 +4276,7 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
		if (pin_bytes)
			btrfs_pin_extent(fs_info, head->bytenr,
					 head->num_bytes, 1);
		btrfs_cleanup_ref_head_accounting(fs_info, delayed_refs, head);
		btrfs_put_delayed_ref_head(head);
		cond_resched();
		spin_lock(&delayed_refs->lock);
+14 −7
Original line number Diff line number Diff line
@@ -2456,12 +2456,10 @@ static int run_and_cleanup_extent_op(struct btrfs_trans_handle *trans,
	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_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. */

	if (head->total_ref_mod < 0) {
@@ -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);
	btrfs_delayed_ref_unlock(head);
@@ -4954,6 +4952,15 @@ static void flush_space(struct btrfs_fs_info *fs_info,
			ret = 0;
		break;
	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);
		break;
	default:
@@ -7188,7 +7195,7 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans,
	if (head->must_insert_reserved)
		ret = 1;

	cleanup_ref_head_accounting(trans, head);
	btrfs_cleanup_ref_head_accounting(trans->fs_info, delayed_refs, head);
	mutex_unlock(&head->mutex);
	btrfs_put_delayed_ref_head(head);
	return ret;
+2 −3
Original line number Diff line number Diff line
@@ -3129,9 +3129,6 @@ out:
	/* once for the tree */
	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;
}

@@ -3254,6 +3251,8 @@ void btrfs_add_delayed_iput(struct inode *inode)
	ASSERT(list_empty(&binode->delayed_iput));
	list_add_tail(&binode->delayed_iput, &fs_info->delayed_iputs);
	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)