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

Commit 655c5d8f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: (22 commits)
  Btrfs: Fix async caching interaction with unmount
  Btrfs: change how we unpin extents
  Btrfs: Correct redundant test in add_inode_ref
  Btrfs: find smallest available device extent during chunk allocation
  Btrfs: clear all space_info->full after removing a block group
  Btrfs: make flushoncommit mount option correctly wait on ordered_extents
  Btrfs: Avoid delayed reference update looping
  Btrfs: Fix ordering of key field checks in btrfs_previous_item
  Btrfs: find_free_dev_extent doesn't handle holes at the start of the device
  Btrfs: Remove code duplication in comp_keys
  Btrfs: async block group caching
  Btrfs: use hybrid extents+bitmap rb tree for free space
  Btrfs: Fix crash on read failures at mount
  Btrfs: remove of redundant btrfs_header_level
  Btrfs: adjust NULL test
  Btrfs: Remove broken sanity check from btrfs_rmap_block()
  Btrfs: convert nested spin_lock_irqsave to spin_lock
  Btrfs: make sure all dirty blocks are written at commit time
  Btrfs: fix locking issue in btrfs_find_next_key
  Btrfs: fix double increment of path->slots[0] in btrfs_next_leaf
  ...
parents ce4adcc6 f25784b3
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -424,11 +424,11 @@ int btrfs_requeue_work(struct btrfs_work *work)
	 * list
	 * list
	 */
	 */
	if (worker->idle) {
	if (worker->idle) {
		spin_lock_irqsave(&worker->workers->lock, flags);
		spin_lock(&worker->workers->lock);
		worker->idle = 0;
		worker->idle = 0;
		list_move_tail(&worker->worker_list,
		list_move_tail(&worker->worker_list,
			       &worker->workers->worker_list);
			       &worker->workers->worker_list);
		spin_unlock_irqrestore(&worker->workers->lock, flags);
		spin_unlock(&worker->workers->lock);
	}
	}
	if (!worker->working) {
	if (!worker->working) {
		wake = 1;
		wake = 1;
+68 −53
Original line number Original line Diff line number Diff line
@@ -557,19 +557,7 @@ static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)


	btrfs_disk_key_to_cpu(&k1, disk);
	btrfs_disk_key_to_cpu(&k1, disk);


	if (k1.objectid > k2->objectid)
	return btrfs_comp_cpu_keys(&k1, k2);
		return 1;
	if (k1.objectid < k2->objectid)
		return -1;
	if (k1.type > k2->type)
		return 1;
	if (k1.type < k2->type)
		return -1;
	if (k1.offset > k2->offset)
		return 1;
	if (k1.offset < k2->offset)
		return -1;
	return 0;
}
}


/*
/*
@@ -1052,9 +1040,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
	    BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
	    BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
		return 0;
		return 0;


	if (btrfs_header_nritems(mid) > 2)
		return 0;

	if (btrfs_header_nritems(mid) < 2)
	if (btrfs_header_nritems(mid) < 2)
		err_on_enospc = 1;
		err_on_enospc = 1;


@@ -1701,6 +1686,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
	struct extent_buffer *b;
	struct extent_buffer *b;
	int slot;
	int slot;
	int ret;
	int ret;
	int err;
	int level;
	int level;
	int lowest_unlock = 1;
	int lowest_unlock = 1;
	u8 lowest_level = 0;
	u8 lowest_level = 0;
@@ -1737,8 +1723,6 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
			p->locks[level] = 1;
			p->locks[level] = 1;


		if (cow) {
		if (cow) {
			int wret;

			/*
			/*
			 * if we don't really need to cow this block
			 * if we don't really need to cow this block
			 * then we don't want to set the path blocking,
			 * then we don't want to set the path blocking,
@@ -1749,12 +1733,12 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root


			btrfs_set_path_blocking(p);
			btrfs_set_path_blocking(p);


			wret = btrfs_cow_block(trans, root, b,
			err = btrfs_cow_block(trans, root, b,
					      p->nodes[level + 1],
					      p->nodes[level + 1],
					      p->slots[level + 1], &b);
					      p->slots[level + 1], &b);
			if (wret) {
			if (err) {
				free_extent_buffer(b);
				free_extent_buffer(b);
				ret = wret;
				ret = err;
				goto done;
				goto done;
			}
			}
		}
		}
@@ -1793,41 +1777,45 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
		ret = bin_search(b, key, level, &slot);
		ret = bin_search(b, key, level, &slot);


		if (level != 0) {
		if (level != 0) {
			if (ret && slot > 0)
			int dec = 0;
			if (ret && slot > 0) {
				dec = 1;
				slot -= 1;
				slot -= 1;
			}
			p->slots[level] = slot;
			p->slots[level] = slot;
			ret = setup_nodes_for_search(trans, root, p, b, level,
			err = setup_nodes_for_search(trans, root, p, b, level,
						     ins_len);
						     ins_len);
			if (ret == -EAGAIN)
			if (err == -EAGAIN)
				goto again;
				goto again;
			else if (ret)
			if (err) {
				ret = err;
				goto done;
				goto done;
			}
			b = p->nodes[level];
			b = p->nodes[level];
			slot = p->slots[level];
			slot = p->slots[level];


			unlock_up(p, level, lowest_unlock);
			unlock_up(p, level, lowest_unlock);


			/* this is only true while dropping a snapshot */
			if (level == lowest_level) {
			if (level == lowest_level) {
				ret = 0;
				if (dec)
					p->slots[level]++;
				goto done;
				goto done;
			}
			}


			ret = read_block_for_search(trans, root, p,
			err = read_block_for_search(trans, root, p,
						    &b, level, slot, key);
						    &b, level, slot, key);
			if (ret == -EAGAIN)
			if (err == -EAGAIN)
				goto again;
				goto again;

			if (err) {
			if (ret == -EIO)
				ret = err;
				goto done;
				goto done;
			}


			if (!p->skip_locking) {
			if (!p->skip_locking) {
				int lret;

				btrfs_clear_path_blocking(p, NULL);
				btrfs_clear_path_blocking(p, NULL);
				lret = btrfs_try_spin_lock(b);
				err = btrfs_try_spin_lock(b);


				if (!lret) {
				if (!err) {
					btrfs_set_path_blocking(p);
					btrfs_set_path_blocking(p);
					btrfs_tree_lock(b);
					btrfs_tree_lock(b);
					btrfs_clear_path_blocking(p, b);
					btrfs_clear_path_blocking(p, b);
@@ -1837,16 +1825,14 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
			p->slots[level] = slot;
			p->slots[level] = slot;
			if (ins_len > 0 &&
			if (ins_len > 0 &&
			    btrfs_leaf_free_space(root, b) < ins_len) {
			    btrfs_leaf_free_space(root, b) < ins_len) {
				int sret;

				btrfs_set_path_blocking(p);
				btrfs_set_path_blocking(p);
				sret = split_leaf(trans, root, key,
				err = split_leaf(trans, root, key,
						 p, ins_len, ret == 0);
						 p, ins_len, ret == 0);
				btrfs_clear_path_blocking(p, NULL);
				btrfs_clear_path_blocking(p, NULL);


				BUG_ON(sret > 0);
				BUG_ON(err > 0);
				if (sret) {
				if (err) {
					ret = sret;
					ret = err;
					goto done;
					goto done;
				}
				}
			}
			}
@@ -3807,7 +3793,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		}
		}


		/* delete the leaf if it is mostly empty */
		/* delete the leaf if it is mostly empty */
		if (used < BTRFS_LEAF_DATA_SIZE(root) / 2) {
		if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) {
			/* push_leaf_left fixes the path.
			/* push_leaf_left fixes the path.
			 * make sure the path still points to our leaf
			 * make sure the path still points to our leaf
			 * for possible call to del_ptr below
			 * for possible call to del_ptr below
@@ -4042,10 +4028,9 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key,
 * calling this function.
 * calling this function.
 */
 */
int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path,
int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path,
			struct btrfs_key *key, int lowest_level,
			struct btrfs_key *key, int level,
			int cache_only, u64 min_trans)
			int cache_only, u64 min_trans)
{
{
	int level = lowest_level;
	int slot;
	int slot;
	struct extent_buffer *c;
	struct extent_buffer *c;


@@ -4058,11 +4043,40 @@ int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path,
		c = path->nodes[level];
		c = path->nodes[level];
next:
next:
		if (slot >= btrfs_header_nritems(c)) {
		if (slot >= btrfs_header_nritems(c)) {
			level++;
			int ret;
			if (level == BTRFS_MAX_LEVEL)
			int orig_lowest;
			struct btrfs_key cur_key;
			if (level + 1 >= BTRFS_MAX_LEVEL ||
			    !path->nodes[level + 1])
				return 1;
				return 1;

			if (path->locks[level + 1]) {
				level++;
				continue;
				continue;
			}
			}

			slot = btrfs_header_nritems(c) - 1;
			if (level == 0)
				btrfs_item_key_to_cpu(c, &cur_key, slot);
			else
				btrfs_node_key_to_cpu(c, &cur_key, slot);

			orig_lowest = path->lowest_level;
			btrfs_release_path(root, path);
			path->lowest_level = level;
			ret = btrfs_search_slot(NULL, root, &cur_key, path,
						0, 0);
			path->lowest_level = orig_lowest;
			if (ret < 0)
				return ret;

			c = path->nodes[level];
			slot = path->slots[level];
			if (ret == 0)
				slot++;
			goto next;
		}

		if (level == 0)
		if (level == 0)
			btrfs_item_key_to_cpu(c, key, slot);
			btrfs_item_key_to_cpu(c, key, slot);
		else {
		else {
@@ -4146,6 +4160,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
	 * advance the path if there are now more items available.
	 * advance the path if there are now more items available.
	 */
	 */
	if (nritems > 0 && path->slots[0] < nritems - 1) {
	if (nritems > 0 && path->slots[0] < nritems - 1) {
		if (ret == 0)
			path->slots[0]++;
			path->slots[0]++;
		ret = 0;
		ret = 0;
		goto done;
		goto done;
@@ -4278,10 +4293,10 @@ int btrfs_previous_item(struct btrfs_root *root,
			path->slots[0]--;
			path->slots[0]--;


		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
		if (found_key.type == type)
			return 0;
		if (found_key.objectid < min_objectid)
		if (found_key.objectid < min_objectid)
			break;
			break;
		if (found_key.type == type)
			return 0;
		if (found_key.objectid == min_objectid &&
		if (found_key.objectid == min_objectid &&
		    found_key.type < type)
		    found_key.type < type)
			break;
			break;
+25 −4
Original line number Original line Diff line number Diff line
@@ -481,7 +481,7 @@ struct btrfs_shared_data_ref {


struct btrfs_extent_inline_ref {
struct btrfs_extent_inline_ref {
	u8 type;
	u8 type;
	u64 offset;
	__le64 offset;
} __attribute__ ((__packed__));
} __attribute__ ((__packed__));


/* old style backrefs item */
/* old style backrefs item */
@@ -689,6 +689,7 @@ struct btrfs_space_info {
	struct list_head block_groups;
	struct list_head block_groups;
	spinlock_t lock;
	spinlock_t lock;
	struct rw_semaphore groups_sem;
	struct rw_semaphore groups_sem;
	atomic_t caching_threads;
};
};


/*
/*
@@ -707,6 +708,9 @@ struct btrfs_free_cluster {
	/* first extent starting offset */
	/* first extent starting offset */
	u64 window_start;
	u64 window_start;


	/* if this cluster simply points at a bitmap in the block group */
	bool points_to_bitmap;

	struct btrfs_block_group_cache *block_group;
	struct btrfs_block_group_cache *block_group;
	/*
	/*
	 * when a cluster is allocated from a block group, we put the
	 * when a cluster is allocated from a block group, we put the
@@ -716,24 +720,37 @@ struct btrfs_free_cluster {
	struct list_head block_group_list;
	struct list_head block_group_list;
};
};


enum btrfs_caching_type {
	BTRFS_CACHE_NO		= 0,
	BTRFS_CACHE_STARTED	= 1,
	BTRFS_CACHE_FINISHED	= 2,
};

struct btrfs_block_group_cache {
struct btrfs_block_group_cache {
	struct btrfs_key key;
	struct btrfs_key key;
	struct btrfs_block_group_item item;
	struct btrfs_block_group_item item;
	struct btrfs_fs_info *fs_info;
	spinlock_t lock;
	spinlock_t lock;
	struct mutex cache_mutex;
	u64 pinned;
	u64 pinned;
	u64 reserved;
	u64 reserved;
	u64 flags;
	u64 flags;
	int cached;
	u64 sectorsize;
	int extents_thresh;
	int free_extents;
	int total_bitmaps;
	int ro;
	int ro;
	int dirty;
	int dirty;


	/* cache tracking stuff */
	wait_queue_head_t caching_q;
	int cached;

	struct btrfs_space_info *space_info;
	struct btrfs_space_info *space_info;


	/* free space cache stuff */
	/* free space cache stuff */
	spinlock_t tree_lock;
	spinlock_t tree_lock;
	struct rb_root free_space_bytes;
	struct rb_root free_space_offset;
	struct rb_root free_space_offset;
	u64 free_space;


	/* block group cache stuff */
	/* block group cache stuff */
	struct rb_node cache_node;
	struct rb_node cache_node;
@@ -942,6 +959,9 @@ struct btrfs_root {
	/* the node lock is held while changing the node pointer */
	/* the node lock is held while changing the node pointer */
	spinlock_t node_lock;
	spinlock_t node_lock;


	/* taken when updating the commit root */
	struct rw_semaphore commit_root_sem;

	struct extent_buffer *commit_root;
	struct extent_buffer *commit_root;
	struct btrfs_root *log_root;
	struct btrfs_root *log_root;
	struct btrfs_root *reloc_root;
	struct btrfs_root *reloc_root;
@@ -1988,6 +2008,7 @@ void btrfs_delalloc_reserve_space(struct btrfs_root *root, struct inode *inode,
				 u64 bytes);
				 u64 bytes);
void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode,
void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode,
			      u64 bytes);
			      u64 bytes);
void btrfs_free_pinned_extents(struct btrfs_fs_info *info);
/* ctree.c */
/* ctree.c */
int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key,
int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key,
		     int level, int *slot);
		     int level, int *slot);
+15 −0
Original line number Original line Diff line number Diff line
@@ -909,6 +909,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
	spin_lock_init(&root->inode_lock);
	spin_lock_init(&root->inode_lock);
	mutex_init(&root->objectid_mutex);
	mutex_init(&root->objectid_mutex);
	mutex_init(&root->log_mutex);
	mutex_init(&root->log_mutex);
	init_rwsem(&root->commit_root_sem);
	init_waitqueue_head(&root->log_writer_wait);
	init_waitqueue_head(&root->log_writer_wait);
	init_waitqueue_head(&root->log_commit_wait[0]);
	init_waitqueue_head(&root->log_commit_wait[0]);
	init_waitqueue_head(&root->log_commit_wait[1]);
	init_waitqueue_head(&root->log_commit_wait[1]);
@@ -1799,6 +1800,11 @@ struct btrfs_root *open_ctree(struct super_block *sb,
					   btrfs_super_chunk_root(disk_super),
					   btrfs_super_chunk_root(disk_super),
					   blocksize, generation);
					   blocksize, generation);
	BUG_ON(!chunk_root->node);
	BUG_ON(!chunk_root->node);
	if (!test_bit(EXTENT_BUFFER_UPTODATE, &chunk_root->node->bflags)) {
		printk(KERN_WARNING "btrfs: failed to read chunk root on %s\n",
		       sb->s_id);
		goto fail_chunk_root;
	}
	btrfs_set_root_node(&chunk_root->root_item, chunk_root->node);
	btrfs_set_root_node(&chunk_root->root_item, chunk_root->node);
	chunk_root->commit_root = btrfs_root_node(chunk_root);
	chunk_root->commit_root = btrfs_root_node(chunk_root);


@@ -1826,6 +1832,11 @@ struct btrfs_root *open_ctree(struct super_block *sb,
					  blocksize, generation);
					  blocksize, generation);
	if (!tree_root->node)
	if (!tree_root->node)
		goto fail_chunk_root;
		goto fail_chunk_root;
	if (!test_bit(EXTENT_BUFFER_UPTODATE, &tree_root->node->bflags)) {
		printk(KERN_WARNING "btrfs: failed to read tree root on %s\n",
		       sb->s_id);
		goto fail_tree_root;
	}
	btrfs_set_root_node(&tree_root->root_item, tree_root->node);
	btrfs_set_root_node(&tree_root->root_item, tree_root->node);
	tree_root->commit_root = btrfs_root_node(tree_root);
	tree_root->commit_root = btrfs_root_node(tree_root);


@@ -2322,6 +2333,9 @@ int close_ctree(struct btrfs_root *root)
			printk(KERN_ERR "btrfs: commit super ret %d\n", ret);
			printk(KERN_ERR "btrfs: commit super ret %d\n", ret);
	}
	}


	fs_info->closing = 2;
	smp_mb();

	if (fs_info->delalloc_bytes) {
	if (fs_info->delalloc_bytes) {
		printk(KERN_INFO "btrfs: at unmount delalloc count %llu\n",
		printk(KERN_INFO "btrfs: at unmount delalloc count %llu\n",
		       (unsigned long long)fs_info->delalloc_bytes);
		       (unsigned long long)fs_info->delalloc_bytes);
@@ -2343,6 +2357,7 @@ int close_ctree(struct btrfs_root *root)
	free_extent_buffer(root->fs_info->csum_root->commit_root);
	free_extent_buffer(root->fs_info->csum_root->commit_root);


	btrfs_free_block_groups(root->fs_info);
	btrfs_free_block_groups(root->fs_info);
	btrfs_free_pinned_extents(root->fs_info);


	del_fs_roots(fs_info);
	del_fs_roots(fs_info);


+389 −127

File changed.

Preview size limit exceeded, changes collapsed.

Loading