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

Commit 4313b399 authored by Chris Mason's avatar Chris Mason
Browse files

Btrfs: Reduce stack usage in the resizer, fix 32 bit compiles

parent 56b453c9
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -386,6 +386,7 @@ struct btrfs_root {
	int defrag_running;
	int defrag_running;
	int defrag_level;
	int defrag_level;
	char *name;
	char *name;
	int in_sysfs;
};
};


/*
/*
+5 −0
Original line number Original line Diff line number Diff line
@@ -374,6 +374,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
	root->highest_inode = 0;
	root->highest_inode = 0;
	root->last_inode_alloc = 0;
	root->last_inode_alloc = 0;
	root->name = NULL;
	root->name = NULL;
	root->in_sysfs = 0;
	memset(&root->root_key, 0, sizeof(root->root_key));
	memset(&root->root_key, 0, sizeof(root->root_key));
	memset(&root->root_item, 0, sizeof(root->root_item));
	memset(&root->root_item, 0, sizeof(root->root_item));
	memset(&root->defrag_progress, 0, sizeof(root->defrag_progress));
	memset(&root->defrag_progress, 0, sizeof(root->defrag_progress));
@@ -516,6 +517,9 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
	if (!root)
	if (!root)
		return NULL;
		return NULL;


	if (root->in_sysfs)
		return root;

	ret = btrfs_set_root_name(root, name, namelen);
	ret = btrfs_set_root_name(root, name, namelen);
	if (ret) {
	if (ret) {
		free_extent_buffer(root->node);
		free_extent_buffer(root->node);
@@ -530,6 +534,7 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
		kfree(root);
		kfree(root);
		return ERR_PTR(ret);
		return ERR_PTR(ret);
	}
	}
	root->in_sysfs = 1;
	return root;
	return root;
}
}
#if 0
#if 0
+38 −36
Original line number Original line Diff line number Diff line
@@ -751,7 +751,7 @@ u32 btrfs_count_snapshots_in_path(struct btrfs_root *root,


		if (found_objectid != root_objectid) {
		if (found_objectid != root_objectid) {
			total_count = 2;
			total_count = 2;
			break;
			goto out;
		}
		}
		total_count = 1;
		total_count = 1;
		path->slots[0]++;
		path->slots[0]++;
@@ -760,8 +760,6 @@ u32 btrfs_count_snapshots_in_path(struct btrfs_root *root,
		total_count = 0;
		total_count = 0;
		goto out;
		goto out;
	}
	}
	if (total_count > 1)
		goto out;
	if (level >= 0 && root->node == count_path->nodes[level])
	if (level >= 0 && root->node == count_path->nodes[level])
		goto out;
		goto out;
	level++;
	level++;
@@ -2109,22 +2107,23 @@ static int relocate_inode_pages(struct inode *inode, u64 start, u64 len)
	u64 delalloc_start;
	u64 delalloc_start;
	u64 existing_delalloc;
	u64 existing_delalloc;
	unsigned long last_index;
	unsigned long last_index;
	unsigned long first_index;
	unsigned long i;
	unsigned long i;
	struct page *page;
	struct page *page;
	struct btrfs_root *root = BTRFS_I(inode)->root;
	struct btrfs_root *root = BTRFS_I(inode)->root;
	struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
	struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
	struct file_ra_state ra;
	struct file_ra_state *ra;

	ra = kzalloc(sizeof(*ra), GFP_NOFS);


	mutex_lock(&inode->i_mutex);
	mutex_lock(&inode->i_mutex);
	first_index = start >> PAGE_CACHE_SHIFT;
	i = start >> PAGE_CACHE_SHIFT;
	last_index = (start + len - 1) >> PAGE_CACHE_SHIFT;
	last_index = (start + len - 1) >> PAGE_CACHE_SHIFT;


	memset(&ra, 0, sizeof(ra));
	file_ra_state_init(ra, inode->i_mapping);
	file_ra_state_init(&ra, inode->i_mapping);
	btrfs_force_ra(inode->i_mapping, ra, NULL, i, last_index);
	btrfs_force_ra(inode->i_mapping, &ra, NULL, first_index, last_index);
	kfree(ra);


	for (i = first_index; i <= last_index; i++) {
	for (; i <= last_index; i++) {
		page = grab_cache_page(inode->i_mapping, i);
		page = grab_cache_page(inode->i_mapping, i);
		if (!page)
		if (!page)
			goto out_unlock;
			goto out_unlock;
@@ -2167,27 +2166,43 @@ static int relocate_inode_pages(struct inode *inode, u64 start, u64 len)
	return 0;
	return 0;
}
}


/*
 * note, this releases the path
 */
static int relocate_one_reference(struct btrfs_root *extent_root,
static int relocate_one_reference(struct btrfs_root *extent_root,
				  struct btrfs_path *path,
				  struct btrfs_path *path,
				  struct btrfs_key *extent_key,
				  struct btrfs_key *extent_key)
				  u64 ref_root, u64 ref_gen, u64 ref_objectid,
				  u64 ref_offset)
{
{
	struct inode *inode;
	struct inode *inode;
	struct btrfs_root *found_root;
	struct btrfs_root *found_root;
	struct btrfs_key root_location;
	struct btrfs_key *root_location;
	struct btrfs_extent_ref *ref;
	u64 ref_root;
	u64 ref_gen;
	u64 ref_objectid;
	u64 ref_offset;
	int ret;
	int ret;


	root_location.objectid = ref_root;
	ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
			     struct btrfs_extent_ref);
	ref_root = btrfs_ref_root(path->nodes[0], ref);
	ref_gen = btrfs_ref_generation(path->nodes[0], ref);
	ref_objectid = btrfs_ref_objectid(path->nodes[0], ref);
	ref_offset = btrfs_ref_offset(path->nodes[0], ref);
	btrfs_release_path(extent_root, path);

	root_location = kmalloc(sizeof(*root_location), GFP_NOFS);
	root_location->objectid = ref_root;
	if (ref_gen == 0)
	if (ref_gen == 0)
		root_location.offset = 0;
		root_location->offset = 0;
	else
	else
		root_location.offset = (u64)-1;
		root_location->offset = (u64)-1;
	root_location.type = BTRFS_ROOT_ITEM_KEY;
	root_location->type = BTRFS_ROOT_ITEM_KEY;


	found_root = btrfs_read_fs_root_no_name(extent_root->fs_info,
	found_root = btrfs_read_fs_root_no_name(extent_root->fs_info,
						&root_location);
						root_location);
	BUG_ON(!found_root);
	BUG_ON(!found_root);
	kfree(root_location);


	if (ref_objectid >= BTRFS_FIRST_FREE_OBJECTID) {
	if (ref_objectid >= BTRFS_FIRST_FREE_OBJECTID) {
		mutex_unlock(&extent_root->fs_info->fs_mutex);
		mutex_unlock(&extent_root->fs_info->fs_mutex);
@@ -2259,12 +2274,7 @@ static int relocate_one_extent(struct btrfs_root *extent_root,
{
{
	struct btrfs_key key;
	struct btrfs_key key;
	struct btrfs_key found_key;
	struct btrfs_key found_key;
	struct btrfs_extent_ref *ref;
	struct extent_buffer *leaf;
	struct extent_buffer *leaf;
	u64 ref_root;
	u64 ref_gen;
	u64 ref_objectid;
	u64 ref_offset;
	u32 nritems;
	u32 nritems;
	u32 item_size;
	u32 item_size;
	int ret = 0;
	int ret = 0;
@@ -2297,17 +2307,7 @@ static int relocate_one_extent(struct btrfs_root *extent_root,
		key.offset = found_key.offset + 1;
		key.offset = found_key.offset + 1;
		item_size = btrfs_item_size_nr(leaf, path->slots[0]);
		item_size = btrfs_item_size_nr(leaf, path->slots[0]);


		ref = btrfs_item_ptr(leaf, path->slots[0],
		ret = relocate_one_reference(extent_root, path, extent_key);
				     struct btrfs_extent_ref);
		ref_root = btrfs_ref_root(leaf, ref);
		ref_gen = btrfs_ref_generation(leaf, ref);
		ref_objectid = btrfs_ref_objectid(leaf, ref);
		ref_offset = btrfs_ref_offset(leaf, ref);
		btrfs_release_path(extent_root, path);

		ret = relocate_one_reference(extent_root, path,
					     extent_key, ref_root, ref_gen,
					     ref_objectid, ref_offset);
		if (ret)
		if (ret)
			goto out;
			goto out;
	}
	}
@@ -2354,7 +2354,6 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 new_size)
	struct btrfs_path *path;
	struct btrfs_path *path;
	u64 cur_byte;
	u64 cur_byte;
	u64 total_found;
	u64 total_found;
	u64 ptr;
	struct btrfs_fs_info *info = root->fs_info;
	struct btrfs_fs_info *info = root->fs_info;
	struct extent_map_tree *block_group_cache;
	struct extent_map_tree *block_group_cache;
	struct btrfs_key key;
	struct btrfs_key key;
@@ -2377,6 +2376,7 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 new_size)
	key.offset = 0;
	key.offset = 0;
	key.type = 0;
	key.type = 0;
	while(1) {
	while(1) {

		ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
		ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
		if (ret < 0)
		if (ret < 0)
			goto out;
			goto out;
@@ -2441,6 +2441,8 @@ int btrfs_shrink_extent_tree(struct btrfs_root *root, u64 new_size)
	key.offset = 0;
	key.offset = 0;
	key.type = 0;
	key.type = 0;
	while(1) {
	while(1) {
		u64 ptr;

		ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
		ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
		if (ret < 0)
		if (ret < 0)
			goto out;
			goto out;
+4 −2
Original line number Original line Diff line number Diff line
@@ -2108,7 +2108,8 @@ static void btrfs_truncate(struct inode *inode)
	btrfs_btree_balance_dirty(root, nr);
	btrfs_btree_balance_dirty(root, nr);
}
}


static int create_subvol(struct btrfs_root *root, char *name, int namelen)
static int noinline create_subvol(struct btrfs_root *root, char *name,
				  int namelen)
{
{
	struct btrfs_trans_handle *trans;
	struct btrfs_trans_handle *trans;
	struct btrfs_key key;
	struct btrfs_key key;
@@ -2492,7 +2493,8 @@ printk("new size is %Lu\n", new_size);
	return ret;
	return ret;
}
}


static int btrfs_ioctl_snap_create(struct btrfs_root *root, void __user *arg)
static int noinline btrfs_ioctl_snap_create(struct btrfs_root *root,
					    void __user *arg)
{
{
	struct btrfs_ioctl_vol_args *vol_args;
	struct btrfs_ioctl_vol_args *vol_args;
	struct btrfs_dir_item *di;
	struct btrfs_dir_item *di;
+15 −5
Original line number Original line Diff line number Diff line
@@ -481,12 +481,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
	struct btrfs_transaction *cur_trans;
	struct btrfs_transaction *cur_trans;
	struct btrfs_transaction *prev_trans = NULL;
	struct btrfs_transaction *prev_trans = NULL;
	struct list_head dirty_fs_roots;
	struct list_head dirty_fs_roots;
	struct extent_map_tree pinned_copy;
	struct extent_map_tree *pinned_copy;
	DEFINE_WAIT(wait);
	DEFINE_WAIT(wait);
	int ret;
	int ret;


	extent_map_tree_init(&pinned_copy,
			     root->fs_info->btree_inode->i_mapping, GFP_NOFS);
	INIT_LIST_HEAD(&dirty_fs_roots);
	INIT_LIST_HEAD(&dirty_fs_roots);


	mutex_lock(&root->fs_info->trans_mutex);
	mutex_lock(&root->fs_info->trans_mutex);
@@ -507,6 +505,14 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
		mutex_lock(&root->fs_info->fs_mutex);
		mutex_lock(&root->fs_info->fs_mutex);
		return 0;
		return 0;
	}
	}

	pinned_copy = kmalloc(sizeof(*pinned_copy), GFP_NOFS);
	if (!pinned_copy)
		return -ENOMEM;

	extent_map_tree_init(pinned_copy,
			     root->fs_info->btree_inode->i_mapping, GFP_NOFS);

	trans->transaction->in_commit = 1;
	trans->transaction->in_commit = 1;
	cur_trans = trans->transaction;
	cur_trans = trans->transaction;
	if (cur_trans->list.prev != &root->fs_info->trans_list) {
	if (cur_trans->list.prev != &root->fs_info->trans_list) {
@@ -568,16 +574,20 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
			    &root->fs_info->super_copy, 0,
			    &root->fs_info->super_copy, 0,
			    sizeof(root->fs_info->super_copy));
			    sizeof(root->fs_info->super_copy));


	btrfs_copy_pinned(root, &pinned_copy);
	btrfs_copy_pinned(root, pinned_copy);


	mutex_unlock(&root->fs_info->trans_mutex);
	mutex_unlock(&root->fs_info->trans_mutex);
	mutex_unlock(&root->fs_info->fs_mutex);
	mutex_unlock(&root->fs_info->fs_mutex);
	ret = btrfs_write_and_wait_transaction(trans, root);
	ret = btrfs_write_and_wait_transaction(trans, root);
	BUG_ON(ret);
	BUG_ON(ret);
	write_ctree_super(trans, root);
	write_ctree_super(trans, root);

	mutex_lock(&root->fs_info->fs_mutex);
	mutex_lock(&root->fs_info->fs_mutex);
	btrfs_finish_extent_commit(trans, root, &pinned_copy);
	btrfs_finish_extent_commit(trans, root, pinned_copy);
	mutex_lock(&root->fs_info->trans_mutex);
	mutex_lock(&root->fs_info->trans_mutex);

	kfree(pinned_copy);

	cur_trans->commit_done = 1;
	cur_trans->commit_done = 1;
	root->fs_info->last_trans_committed = cur_trans->transid;
	root->fs_info->last_trans_committed = cur_trans->transid;
	wake_up(&cur_trans->commit_wait);
	wake_up(&cur_trans->commit_wait);