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, ...@@ -543,6 +543,7 @@ ssize_t btrfs_dio_read(struct kiocb *iocb, struct iov_iter *iter,
size_t done_before); size_t done_before);
struct iomap_dio *btrfs_dio_write(struct kiocb *iocb, struct iov_iter *iter, struct iomap_dio *btrfs_dio_write(struct kiocb *iocb, struct iov_iter *iter,
size_t done_before); 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; 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 ...@@ -10807,6 +10807,65 @@ void btrfs_assert_inode_range_clean(struct btrfs_inode *inode, u64 start, u64 en
ASSERT(ordered == NULL); 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 = { static const struct inode_operations btrfs_dir_inode_operations = {
.getattr = btrfs_getattr, .getattr = btrfs_getattr,
.lookup = btrfs_lookup, .lookup = btrfs_lookup,
......
...@@ -951,60 +951,6 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans, ...@@ -951,60 +951,6 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
return ret; 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 * get new location of data
*/ */
...@@ -1065,7 +1011,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans, ...@@ -1065,7 +1011,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
struct btrfs_key key; struct btrfs_key key;
struct btrfs_file_extent_item *fi; struct btrfs_file_extent_item *fi;
struct inode *inode = NULL; struct btrfs_inode *inode = NULL;
u64 parent; u64 parent;
u64 bytenr; u64 bytenr;
u64 new_bytenr = 0; u64 new_bytenr = 0;
...@@ -1112,13 +1058,13 @@ int replace_file_extents(struct btrfs_trans_handle *trans, ...@@ -1112,13 +1058,13 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
*/ */
if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) { if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) {
if (first) { if (first) {
inode = find_next_inode(root, key.objectid); inode = btrfs_find_first_inode(root, key.objectid);
first = 0; first = 0;
} else if (inode && btrfs_ino(BTRFS_I(inode)) < key.objectid) { } else if (inode && btrfs_ino(inode) < key.objectid) {
btrfs_add_delayed_iput(BTRFS_I(inode)); btrfs_add_delayed_iput(inode);
inode = find_next_inode(root, key.objectid); 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; struct extent_state *cached_state = NULL;
end = key.offset + end = key.offset +
...@@ -1128,21 +1074,19 @@ int replace_file_extents(struct btrfs_trans_handle *trans, ...@@ -1128,21 +1074,19 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
WARN_ON(!IS_ALIGNED(end, fs_info->sectorsize)); WARN_ON(!IS_ALIGNED(end, fs_info->sectorsize));
end--; end--;
/* Take mmap lock to serialize with reflinks. */ /* 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; continue;
ret = try_lock_extent(&BTRFS_I(inode)->io_tree, ret = try_lock_extent(&inode->io_tree, key.offset,
key.offset, end, end, &cached_state);
&cached_state);
if (!ret) { if (!ret) {
up_read(&BTRFS_I(inode)->i_mmap_lock); up_read(&inode->i_mmap_lock);
continue; continue;
} }
btrfs_drop_extent_map_range(BTRFS_I(inode), btrfs_drop_extent_map_range(inode, key.offset, end, true);
key.offset, end, true); unlock_extent(&inode->io_tree, key.offset, end,
unlock_extent(&BTRFS_I(inode)->io_tree, &cached_state);
key.offset, end, &cached_state); up_read(&inode->i_mmap_lock);
up_read(&BTRFS_I(inode)->i_mmap_lock);
} }
} }
...@@ -1185,7 +1129,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans, ...@@ -1185,7 +1129,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
if (dirty) if (dirty)
btrfs_mark_buffer_dirty(trans, leaf); btrfs_mark_buffer_dirty(trans, leaf);
if (inode) if (inode)
btrfs_add_delayed_iput(BTRFS_I(inode)); btrfs_add_delayed_iput(inode);
return ret; return ret;
} }
...@@ -1527,7 +1471,7 @@ static int invalidate_extent_cache(struct btrfs_root *root, ...@@ -1527,7 +1471,7 @@ static int invalidate_extent_cache(struct btrfs_root *root,
const struct btrfs_key *max_key) const struct btrfs_key *max_key)
{ {
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
struct inode *inode = NULL; struct btrfs_inode *inode = NULL;
u64 objectid; u64 objectid;
u64 start, end; u64 start, end;
u64 ino; u64 ino;
...@@ -1537,23 +1481,24 @@ static int invalidate_extent_cache(struct btrfs_root *root, ...@@ -1537,23 +1481,24 @@ static int invalidate_extent_cache(struct btrfs_root *root,
struct extent_state *cached_state = NULL; struct extent_state *cached_state = NULL;
cond_resched(); cond_resched();
iput(inode); if (inode)
iput(&inode->vfs_inode);
if (objectid > max_key->objectid) if (objectid > max_key->objectid)
break; break;
inode = find_next_inode(root, objectid); inode = btrfs_find_first_inode(root, objectid);
if (!inode) if (!inode)
break; break;
ino = btrfs_ino(BTRFS_I(inode)); ino = btrfs_ino(inode);
if (ino > max_key->objectid) { if (ino > max_key->objectid) {
iput(inode); iput(&inode->vfs_inode);
break; break;
} }
objectid = ino + 1; objectid = ino + 1;
if (!S_ISREG(inode->i_mode)) if (!S_ISREG(inode->vfs_inode.i_mode))
continue; continue;
if (unlikely(min_key->objectid == ino)) { if (unlikely(min_key->objectid == ino)) {
...@@ -1586,9 +1531,9 @@ static int invalidate_extent_cache(struct btrfs_root *root, ...@@ -1586,9 +1531,9 @@ static int invalidate_extent_cache(struct btrfs_root *root,
} }
/* the lock_extent waits for read_folio to complete */ /* the lock_extent waits for read_folio to complete */
lock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached_state); lock_extent(&inode->io_tree, start, end, &cached_state);
btrfs_drop_extent_map_range(BTRFS_I(inode), start, end, true); btrfs_drop_extent_map_range(inode, start, end, true);
unlock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached_state); unlock_extent(&inode->io_tree, start, end, &cached_state);
} }
return 0; 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