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: Qu Wenruo <wqu@suse.com> Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
ed48adf83e
commit
5e485ac6f0
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user