Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 49b25e05 authored by Jeff Mahoney's avatar Jeff Mahoney Committed by David Sterba
Browse files

btrfs: enhance transaction abort infrastructure



Signed-off-by: default avatarJeff Mahoney <jeffm@suse.com>
parent 4da35113
Loading
Loading
Loading
Loading
+12 −1
Original line number Original line Diff line number Diff line
@@ -2968,6 +2968,16 @@ void btrfs_printk(struct btrfs_fs_info *fs_info, const char *fmt, ...);
void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function,
void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function,
		     unsigned int line, int errno, const char *fmt, ...);
		     unsigned int line, int errno, const char *fmt, ...);


void __btrfs_abort_transaction(struct btrfs_trans_handle *trans,
			       struct btrfs_root *root, const char *function,
			       unsigned int line, int errno);

#define btrfs_abort_transaction(trans, root, errno)		\
do {								\
	__btrfs_abort_transaction(trans, root, __func__,	\
				  __LINE__, errno);		\
} while (0)

#define btrfs_std_error(fs_info, errno)				\
#define btrfs_std_error(fs_info, errno)				\
do {								\
do {								\
	if ((errno))						\
	if ((errno))						\
@@ -3024,7 +3034,7 @@ void btrfs_reloc_cow_block(struct btrfs_trans_handle *trans,
void btrfs_reloc_pre_snapshot(struct btrfs_trans_handle *trans,
void btrfs_reloc_pre_snapshot(struct btrfs_trans_handle *trans,
			      struct btrfs_pending_snapshot *pending,
			      struct btrfs_pending_snapshot *pending,
			      u64 *bytes_to_reserve);
			      u64 *bytes_to_reserve);
void btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
int btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
			      struct btrfs_pending_snapshot *pending);
			      struct btrfs_pending_snapshot *pending);


/* scrub.c */
/* scrub.c */
@@ -3034,6 +3044,7 @@ void btrfs_scrub_pause(struct btrfs_root *root);
void btrfs_scrub_pause_super(struct btrfs_root *root);
void btrfs_scrub_pause_super(struct btrfs_root *root);
void btrfs_scrub_continue(struct btrfs_root *root);
void btrfs_scrub_continue(struct btrfs_root *root);
void btrfs_scrub_continue_super(struct btrfs_root *root);
void btrfs_scrub_continue_super(struct btrfs_root *root);
int __btrfs_scrub_cancel(struct btrfs_fs_info *info);
int btrfs_scrub_cancel(struct btrfs_root *root);
int btrfs_scrub_cancel(struct btrfs_root *root);
int btrfs_scrub_cancel_dev(struct btrfs_root *root, struct btrfs_device *dev);
int btrfs_scrub_cancel_dev(struct btrfs_root *root, struct btrfs_device *dev);
int btrfs_scrub_cancel_devid(struct btrfs_root *root, u64 devid);
int btrfs_scrub_cancel_devid(struct btrfs_root *root, u64 devid);
+46 −4
Original line number Original line Diff line number Diff line
@@ -61,7 +61,6 @@ static int btrfs_destroy_marked_extents(struct btrfs_root *root,
					int mark);
					int mark);
static int btrfs_destroy_pinned_extent(struct btrfs_root *root,
static int btrfs_destroy_pinned_extent(struct btrfs_root *root,
				       struct extent_io_tree *pinned_extents);
				       struct extent_io_tree *pinned_extents);
static int btrfs_cleanup_transaction(struct btrfs_root *root);


/*
/*
 * end_io_wq structs are used to do processing in task context when an IO is
 * end_io_wq structs are used to do processing in task context when an IO is
@@ -2896,6 +2895,19 @@ int write_ctree_super(struct btrfs_trans_handle *trans,
	return ret;
	return ret;
}
}


/* Kill all outstanding I/O */
void btrfs_abort_devices(struct btrfs_root *root)
{
	struct list_head *head;
	struct btrfs_device *dev;
	mutex_lock(&root->fs_info->fs_devices->device_list_mutex);
	head = &root->fs_info->fs_devices->devices;
	list_for_each_entry_rcu(dev, head, dev_list) {
		blk_abort_queue(dev->bdev->bd_disk->queue);
	}
	mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
}

void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
{
{
	spin_lock(&fs_info->fs_roots_radix_lock);
	spin_lock(&fs_info->fs_roots_radix_lock);
@@ -3536,13 +3548,43 @@ static int btrfs_destroy_pinned_extent(struct btrfs_root *root,
	return 0;
	return 0;
}
}


static int btrfs_cleanup_transaction(struct btrfs_root *root)
void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
				   struct btrfs_root *root)
{
	btrfs_destroy_delayed_refs(cur_trans, root);
	btrfs_block_rsv_release(root, &root->fs_info->trans_block_rsv,
				cur_trans->dirty_pages.dirty_bytes);

	/* FIXME: cleanup wait for commit */
	cur_trans->in_commit = 1;
	cur_trans->blocked = 1;
	if (waitqueue_active(&root->fs_info->transaction_blocked_wait))
		wake_up(&root->fs_info->transaction_blocked_wait);

	cur_trans->blocked = 0;
	if (waitqueue_active(&root->fs_info->transaction_wait))
		wake_up(&root->fs_info->transaction_wait);

	cur_trans->commit_done = 1;
	if (waitqueue_active(&cur_trans->commit_wait))
		wake_up(&cur_trans->commit_wait);

	btrfs_destroy_pending_snapshots(cur_trans);

	btrfs_destroy_marked_extents(root, &cur_trans->dirty_pages,
				     EXTENT_DIRTY);

	/*
	memset(cur_trans, 0, sizeof(*cur_trans));
	kmem_cache_free(btrfs_transaction_cachep, cur_trans);
	*/
}

int btrfs_cleanup_transaction(struct btrfs_root *root)
{
{
	struct btrfs_transaction *t;
	struct btrfs_transaction *t;
	LIST_HEAD(list);
	LIST_HEAD(list);


	WARN_ON(1);

	mutex_lock(&root->fs_info->transaction_kthread_mutex);
	mutex_lock(&root->fs_info->transaction_kthread_mutex);


	spin_lock(&root->fs_info->trans_lock);
	spin_lock(&root->fs_info->trans_lock);
+4 −0
Original line number Original line Diff line number Diff line
@@ -85,6 +85,10 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans,
			     struct btrfs_fs_info *fs_info);
			     struct btrfs_fs_info *fs_info);
int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
		       struct btrfs_root *root);
		       struct btrfs_root *root);
int btrfs_cleanup_transaction(struct btrfs_root *root);
void btrfs_cleanup_one_transaction(struct btrfs_transaction *trans,
				  struct btrfs_root *root);
void btrfs_abort_devices(struct btrfs_root *root);


#ifdef CONFIG_DEBUG_LOCK_ALLOC
#ifdef CONFIG_DEBUG_LOCK_ALLOC
void btrfs_init_lockdep(void);
void btrfs_init_lockdep(void);
+8 −6
Original line number Original line Diff line number Diff line
@@ -4410,7 +4410,7 @@ void btrfs_reloc_pre_snapshot(struct btrfs_trans_handle *trans,
 * called after snapshot is created. migrate block reservation
 * called after snapshot is created. migrate block reservation
 * and create reloc root for the newly created snapshot
 * and create reloc root for the newly created snapshot
 */
 */
void btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
int btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
			       struct btrfs_pending_snapshot *pending)
			       struct btrfs_pending_snapshot *pending)
{
{
	struct btrfs_root *root = pending->root;
	struct btrfs_root *root = pending->root;
@@ -4420,7 +4420,7 @@ void btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
	int ret;
	int ret;


	if (!root->reloc_root)
	if (!root->reloc_root)
		return;
		return 0;


	rc = root->fs_info->reloc_ctl;
	rc = root->fs_info->reloc_ctl;
	rc->merging_rsv_size += rc->nodes_relocated;
	rc->merging_rsv_size += rc->nodes_relocated;
@@ -4429,19 +4429,21 @@ void btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
		ret = btrfs_block_rsv_migrate(&pending->block_rsv,
		ret = btrfs_block_rsv_migrate(&pending->block_rsv,
					      rc->block_rsv,
					      rc->block_rsv,
					      rc->nodes_relocated);
					      rc->nodes_relocated);
		BUG_ON(ret);
		if (ret)
			return ret;
	}
	}


	new_root = pending->snap;
	new_root = pending->snap;
	reloc_root = create_reloc_root(trans, root->reloc_root,
	reloc_root = create_reloc_root(trans, root->reloc_root,
				       new_root->root_key.objectid);
				       new_root->root_key.objectid);
	if (IS_ERR(reloc_root))
		return PTR_ERR(reloc_root);


	ret = __add_reloc_root(reloc_root);
	ret = __add_reloc_root(reloc_root);
	BUG_ON(ret < 0);
	BUG_ON(ret < 0);
	new_root->reloc_root = reloc_root;
	new_root->reloc_root = reloc_root;


	if (rc->create_reloc_tree) {
	if (rc->create_reloc_tree)
		ret = clone_backref_node(trans, rc, root, reloc_root);
		ret = clone_backref_node(trans, rc, root, reloc_root);
		BUG_ON(ret);
	return ret;
	}
}
}
+6 −2
Original line number Original line Diff line number Diff line
@@ -1680,9 +1680,8 @@ void btrfs_scrub_continue_super(struct btrfs_root *root)
	up_write(&root->fs_info->scrub_super_lock);
	up_write(&root->fs_info->scrub_super_lock);
}
}


int btrfs_scrub_cancel(struct btrfs_root *root)
int __btrfs_scrub_cancel(struct btrfs_fs_info *fs_info)
{
{
	struct btrfs_fs_info *fs_info = root->fs_info;


	mutex_lock(&fs_info->scrub_lock);
	mutex_lock(&fs_info->scrub_lock);
	if (!atomic_read(&fs_info->scrubs_running)) {
	if (!atomic_read(&fs_info->scrubs_running)) {
@@ -1703,6 +1702,11 @@ int btrfs_scrub_cancel(struct btrfs_root *root)
	return 0;
	return 0;
}
}


int btrfs_scrub_cancel(struct btrfs_root *root)
{
	return __btrfs_scrub_cancel(root->fs_info);
}

int btrfs_scrub_cancel_dev(struct btrfs_root *root, struct btrfs_device *dev)
int btrfs_scrub_cancel_dev(struct btrfs_root *root, struct btrfs_device *dev)
{
{
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_fs_info *fs_info = root->fs_info;
Loading