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

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
......@@ -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;
......
......@@ -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,
......
......@@ -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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment