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

Commit 90a800de authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable:
  Btrfs: avoid delayed metadata items during commits
  btrfs: fix uninitialized return value
  btrfs: fix wrong reservation when doing delayed inode operations
  btrfs: Remove unused sysfs code
  btrfs: fix dereference of ERR_PTR value
  Btrfs: fix relocation races
  Btrfs: set no_trans_join after trying to expand the transaction
  Btrfs: protect the pending_snapshots list with trans_lock
  Btrfs: fix path leakage on subvol deletion
  Btrfs: drop the delalloc_bytes check in shrink_delalloc
  Btrfs: check the return value from set_anon_super
parents 10e18e62 e999376f
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -967,6 +967,12 @@ struct btrfs_fs_info {
	struct srcu_struct subvol_srcu;

	spinlock_t trans_lock;
	/*
	 * the reloc mutex goes with the trans lock, it is taken
	 * during commit to protect us from the relocation code
	 */
	struct mutex reloc_mutex;

	struct list_head trans_list;
	struct list_head hashers;
	struct list_head dead_roots;
@@ -1172,6 +1178,14 @@ struct btrfs_root {
	u32 type;

	u64 highest_objectid;

	/* btrfs_record_root_in_trans is a multi-step process,
	 * and it can race with the balancing code.   But the
	 * race is very small, and only the first time the root
	 * is added to each transaction.  So in_trans_setup
	 * is used to tell us when more checks are required
	 */
	unsigned long in_trans_setup;
	int ref_cows;
	int track_dirty;
	int in_radix;
@@ -1181,7 +1195,6 @@ struct btrfs_root {
	struct btrfs_key defrag_max;
	int defrag_running;
	char *name;
	int in_sysfs;

	/* the dirty list is only used by non-reference counted roots */
	struct list_head dirty_list;
+27 −5
Original line number Diff line number Diff line
@@ -297,7 +297,6 @@ struct btrfs_delayed_item *btrfs_alloc_delayed_item(u32 data_len)
		item->data_len = data_len;
		item->ins_or_del = 0;
		item->bytes_reserved = 0;
		item->block_rsv = NULL;
		item->delayed_node = NULL;
		atomic_set(&item->refs, 1);
	}
@@ -593,10 +592,8 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans,

	num_bytes = btrfs_calc_trans_metadata_size(root, 1);
	ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes);
	if (!ret) {
	if (!ret)
		item->bytes_reserved = num_bytes;
		item->block_rsv = dst_rsv;
	}

	return ret;
}
@@ -604,10 +601,13 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans,
static void btrfs_delayed_item_release_metadata(struct btrfs_root *root,
						struct btrfs_delayed_item *item)
{
	struct btrfs_block_rsv *rsv;

	if (!item->bytes_reserved)
		return;

	btrfs_block_rsv_release(root, item->block_rsv,
	rsv = &root->fs_info->global_block_rsv;
	btrfs_block_rsv_release(root, rsv,
				item->bytes_reserved);
}

@@ -1014,6 +1014,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
	struct btrfs_delayed_root *delayed_root;
	struct btrfs_delayed_node *curr_node, *prev_node;
	struct btrfs_path *path;
	struct btrfs_block_rsv *block_rsv;
	int ret = 0;

	path = btrfs_alloc_path();
@@ -1021,6 +1022,9 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
		return -ENOMEM;
	path->leave_spinning = 1;

	block_rsv = trans->block_rsv;
	trans->block_rsv = &root->fs_info->global_block_rsv;

	delayed_root = btrfs_get_delayed_root(root);

	curr_node = btrfs_first_delayed_node(delayed_root);
@@ -1045,6 +1049,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
	}

	btrfs_free_path(path);
	trans->block_rsv = block_rsv;
	return ret;
}

@@ -1052,6 +1057,7 @@ static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
					      struct btrfs_delayed_node *node)
{
	struct btrfs_path *path;
	struct btrfs_block_rsv *block_rsv;
	int ret;

	path = btrfs_alloc_path();
@@ -1059,6 +1065,9 @@ static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
		return -ENOMEM;
	path->leave_spinning = 1;

	block_rsv = trans->block_rsv;
	trans->block_rsv = &node->root->fs_info->global_block_rsv;

	ret = btrfs_insert_delayed_items(trans, path, node->root, node);
	if (!ret)
		ret = btrfs_delete_delayed_items(trans, path, node->root, node);
@@ -1066,6 +1075,7 @@ static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
		ret = btrfs_update_delayed_inode(trans, node->root, path, node);
	btrfs_free_path(path);

	trans->block_rsv = block_rsv;
	return ret;
}

@@ -1116,6 +1126,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work)
	struct btrfs_path *path;
	struct btrfs_delayed_node *delayed_node = NULL;
	struct btrfs_root *root;
	struct btrfs_block_rsv *block_rsv;
	unsigned long nr = 0;
	int need_requeue = 0;
	int ret;
@@ -1134,6 +1145,9 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work)
	if (IS_ERR(trans))
		goto free_path;

	block_rsv = trans->block_rsv;
	trans->block_rsv = &root->fs_info->global_block_rsv;

	ret = btrfs_insert_delayed_items(trans, path, root, delayed_node);
	if (!ret)
		ret = btrfs_delete_delayed_items(trans, path, root,
@@ -1176,6 +1190,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work)

	nr = trans->blocks_used;

	trans->block_rsv = block_rsv;
	btrfs_end_transaction_dmeta(trans, root);
	__btrfs_btree_balance_dirty(root, nr);
free_path:
@@ -1222,6 +1237,13 @@ again:
	return 0;
}

void btrfs_assert_delayed_root_empty(struct btrfs_root *root)
{
	struct btrfs_delayed_root *delayed_root;
	delayed_root = btrfs_get_delayed_root(root);
	WARN_ON(btrfs_first_delayed_node(delayed_root));
}

void btrfs_balance_delayed_items(struct btrfs_root *root)
{
	struct btrfs_delayed_root *delayed_root;
+4 −1
Original line number Diff line number Diff line
@@ -75,7 +75,6 @@ struct btrfs_delayed_item {
	struct list_head tree_list;	/* used for batch insert/delete items */
	struct list_head readdir_list;	/* used for readdir items */
	u64 bytes_reserved;
	struct btrfs_block_rsv *block_rsv;
	struct btrfs_delayed_node *delayed_node;
	atomic_t refs;
	int ins_or_del;
@@ -138,4 +137,8 @@ int btrfs_readdir_delayed_dir_index(struct file *filp, void *dirent,
/* for init */
int __init btrfs_delayed_inode_init(void);
void btrfs_delayed_inode_exit(void);

/* for debugging */
void btrfs_assert_delayed_root_empty(struct btrfs_root *root);

#endif
+7 −5
Original line number Diff line number Diff line
@@ -1044,7 +1044,6 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
	root->last_trans = 0;
	root->highest_objectid = 0;
	root->name = NULL;
	root->in_sysfs = 0;
	root->inode_tree = RB_ROOT;
	INIT_RADIX_TREE(&root->delayed_nodes_tree, GFP_ATOMIC);
	root->block_rsv = NULL;
@@ -1300,19 +1299,21 @@ again:
		return root;

	root->free_ino_ctl = kzalloc(sizeof(*root->free_ino_ctl), GFP_NOFS);
	if (!root->free_ino_ctl)
		goto fail;
	root->free_ino_pinned = kzalloc(sizeof(*root->free_ino_pinned),
					GFP_NOFS);
	if (!root->free_ino_pinned)
	if (!root->free_ino_pinned || !root->free_ino_ctl) {
		ret = -ENOMEM;
		goto fail;
	}

	btrfs_init_free_ino_ctl(root);
	mutex_init(&root->fs_commit_mutex);
	spin_lock_init(&root->cache_lock);
	init_waitqueue_head(&root->cache_wait);

	set_anon_super(&root->anon_super, NULL);
	ret = set_anon_super(&root->anon_super, NULL);
	if (ret)
		goto fail;

	if (btrfs_root_refs(&root->root_item) == 0) {
		ret = -ENOENT;
@@ -1618,6 +1619,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
	spin_lock_init(&fs_info->fs_roots_radix_lock);
	spin_lock_init(&fs_info->delayed_iput_lock);
	spin_lock_init(&fs_info->defrag_inodes_lock);
	mutex_init(&fs_info->reloc_mutex);

	init_completion(&fs_info->kobj_unregister);
	fs_info->tree_root = tree_root;
+0 −4
Original line number Diff line number Diff line
@@ -3314,10 +3314,6 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
	if (reserved == 0)
		return 0;

	/* nothing to shrink - nothing to reclaim */
	if (root->fs_info->delalloc_bytes == 0)
		return 0;

	max_reclaim = min(reserved, to_reclaim);

	while (loops < 1024) {
Loading