Commit 5e485ac6 authored by Filipe Manana's avatar Filipe Manana Committed by David Sterba
Browse files

btrfs: export find_next_inode() as btrfs_find_first_inode()



Export the relocation private helper find_next_inode() to inode.c, as this
same logic is also used at btrfs_prune_dentries() and will be used by an
upcoming change that adds an extent map shrinker. The next patch will
change btrfs_prune_dentries() to use this helper.

Reviewed-by: default avatarQu Wenruo <wqu@suse.com>
Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent ed48adf8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -543,6 +543,7 @@ ssize_t btrfs_dio_read(struct kiocb *iocb, struct iov_iter *iter,
		       size_t done_before);
struct iomap_dio *btrfs_dio_write(struct kiocb *iocb, struct iov_iter *iter,
				  size_t done_before);
struct btrfs_inode *btrfs_find_first_inode(struct btrfs_root *root, u64 min_ino);

extern const struct dentry_operations btrfs_dentry_operations;

+59 −0
Original line number Diff line number Diff line
@@ -10807,6 +10807,65 @@ void btrfs_assert_inode_range_clean(struct btrfs_inode *inode, u64 start, u64 en
	ASSERT(ordered == NULL);
}

/*
 * Find the first inode with a minimum number.
 *
 * @root:	The root to search for.
 * @min_ino:	The minimum inode number.
 *
 * Find the first inode in the @root with a number >= @min_ino and return it.
 * Returns NULL if no such inode found.
 */
struct btrfs_inode *btrfs_find_first_inode(struct btrfs_root *root, u64 min_ino)
{
	struct rb_node *node;
	struct rb_node *prev;
	struct btrfs_inode *inode;

	spin_lock(&root->inode_lock);
again:
	node = root->inode_tree.rb_node;
	prev = NULL;
	while (node) {
		prev = node;
		inode = rb_entry(node, struct btrfs_inode, rb_node);
		if (min_ino < btrfs_ino(inode))
			node = node->rb_left;
		else if (min_ino > btrfs_ino(inode))
			node = node->rb_right;
		else
			break;
	}

	if (!node) {
		while (prev) {
			inode = rb_entry(prev, struct btrfs_inode, rb_node);
			if (min_ino <= btrfs_ino(inode)) {
				node = prev;
				break;
			}
			prev = rb_next(prev);
		}
	}

	while (node) {
		inode = rb_entry(prev, struct btrfs_inode, rb_node);
		if (igrab(&inode->vfs_inode)) {
			spin_unlock(&root->inode_lock);
			return inode;
		}

		min_ino = btrfs_ino(inode) + 1;
		if (cond_resched_lock(&root->inode_lock))
			goto again;

		node = rb_next(node);
	}
	spin_unlock(&root->inode_lock);

	return NULL;
}

static const struct inode_operations btrfs_dir_inode_operations = {
	.getattr	= btrfs_getattr,
	.lookup		= btrfs_lookup,
+25 −80
Original line number Diff line number Diff line
@@ -951,60 +951,6 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
	return ret;
}

/*
 * helper to find first cached inode with inode number >= objectid
 * in a subvolume
 */
static struct inode *find_next_inode(struct btrfs_root *root, u64 objectid)
{
	struct rb_node *node;
	struct rb_node *prev;
	struct btrfs_inode *entry;
	struct inode *inode;

	spin_lock(&root->inode_lock);
again:
	node = root->inode_tree.rb_node;
	prev = NULL;
	while (node) {
		prev = node;
		entry = rb_entry(node, struct btrfs_inode, rb_node);

		if (objectid < btrfs_ino(entry))
			node = node->rb_left;
		else if (objectid > btrfs_ino(entry))
			node = node->rb_right;
		else
			break;
	}
	if (!node) {
		while (prev) {
			entry = rb_entry(prev, struct btrfs_inode, rb_node);
			if (objectid <= btrfs_ino(entry)) {
				node = prev;
				break;
			}
			prev = rb_next(prev);
		}
	}
	while (node) {
		entry = rb_entry(node, struct btrfs_inode, rb_node);
		inode = igrab(&entry->vfs_inode);
		if (inode) {
			spin_unlock(&root->inode_lock);
			return inode;
		}

		objectid = btrfs_ino(entry) + 1;
		if (cond_resched_lock(&root->inode_lock))
			goto again;

		node = rb_next(node);
	}
	spin_unlock(&root->inode_lock);
	return NULL;
}

/*
 * get new location of data
 */
@@ -1065,7 +1011,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_key key;
	struct btrfs_file_extent_item *fi;
	struct inode *inode = NULL;
	struct btrfs_inode *inode = NULL;
	u64 parent;
	u64 bytenr;
	u64 new_bytenr = 0;
@@ -1112,13 +1058,13 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
		 */
		if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) {
			if (first) {
				inode = find_next_inode(root, key.objectid);
				inode = btrfs_find_first_inode(root, key.objectid);
				first = 0;
			} else if (inode && btrfs_ino(BTRFS_I(inode)) < key.objectid) {
				btrfs_add_delayed_iput(BTRFS_I(inode));
				inode = find_next_inode(root, key.objectid);
			} else if (inode && btrfs_ino(inode) < key.objectid) {
				btrfs_add_delayed_iput(inode);
				inode = btrfs_find_first_inode(root, key.objectid);
			}
			if (inode && btrfs_ino(BTRFS_I(inode)) == key.objectid) {
			if (inode && btrfs_ino(inode) == key.objectid) {
				struct extent_state *cached_state = NULL;

				end = key.offset +
@@ -1128,21 +1074,19 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
				WARN_ON(!IS_ALIGNED(end, fs_info->sectorsize));
				end--;
				/* Take mmap lock to serialize with reflinks. */
				if (!down_read_trylock(&BTRFS_I(inode)->i_mmap_lock))
				if (!down_read_trylock(&inode->i_mmap_lock))
					continue;
				ret = try_lock_extent(&BTRFS_I(inode)->io_tree,
						      key.offset, end,
						      &cached_state);
				ret = try_lock_extent(&inode->io_tree, key.offset,
						      end, &cached_state);
				if (!ret) {
					up_read(&BTRFS_I(inode)->i_mmap_lock);
					up_read(&inode->i_mmap_lock);
					continue;
				}

				btrfs_drop_extent_map_range(BTRFS_I(inode),
							    key.offset, end, true);
				unlock_extent(&BTRFS_I(inode)->io_tree,
					      key.offset, end, &cached_state);
				up_read(&BTRFS_I(inode)->i_mmap_lock);
				btrfs_drop_extent_map_range(inode, key.offset, end, true);
				unlock_extent(&inode->io_tree, key.offset, end,
					      &cached_state);
				up_read(&inode->i_mmap_lock);
			}
		}

@@ -1185,7 +1129,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
	if (dirty)
		btrfs_mark_buffer_dirty(trans, leaf);
	if (inode)
		btrfs_add_delayed_iput(BTRFS_I(inode));
		btrfs_add_delayed_iput(inode);
	return ret;
}

@@ -1527,7 +1471,7 @@ static int invalidate_extent_cache(struct btrfs_root *root,
				   const struct btrfs_key *max_key)
{
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct inode *inode = NULL;
	struct btrfs_inode *inode = NULL;
	u64 objectid;
	u64 start, end;
	u64 ino;
@@ -1537,23 +1481,24 @@ static int invalidate_extent_cache(struct btrfs_root *root,
		struct extent_state *cached_state = NULL;

		cond_resched();
		iput(inode);
		if (inode)
			iput(&inode->vfs_inode);

		if (objectid > max_key->objectid)
			break;

		inode = find_next_inode(root, objectid);
		inode = btrfs_find_first_inode(root, objectid);
		if (!inode)
			break;
		ino = btrfs_ino(BTRFS_I(inode));
		ino = btrfs_ino(inode);

		if (ino > max_key->objectid) {
			iput(inode);
			iput(&inode->vfs_inode);
			break;
		}

		objectid = ino + 1;
		if (!S_ISREG(inode->i_mode))
		if (!S_ISREG(inode->vfs_inode.i_mode))
			continue;

		if (unlikely(min_key->objectid == ino)) {
@@ -1586,9 +1531,9 @@ static int invalidate_extent_cache(struct btrfs_root *root,
		}

		/* the lock_extent waits for read_folio to complete */
		lock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached_state);
		btrfs_drop_extent_map_range(BTRFS_I(inode), start, end, true);
		unlock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached_state);
		lock_extent(&inode->io_tree, start, end, &cached_state);
		btrfs_drop_extent_map_range(inode, start, end, true);
		unlock_extent(&inode->io_tree, start, end, &cached_state);
	}
	return 0;
}