Commit 0870295b authored by Filipe Manana's avatar Filipe Manana Committed by Chris Mason

Btrfs: collect only the necessary ordered extents on ranged fsync

Instead of collecting all ordered extents from the inode's ordered tree
and then wait for all of them to complete, just collect the ones that
overlap the fsync range.
Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent 5ab5e44a
...@@ -432,21 +432,31 @@ int btrfs_dec_test_ordered_pending(struct inode *inode, ...@@ -432,21 +432,31 @@ int btrfs_dec_test_ordered_pending(struct inode *inode,
/* Needs to either be called under a log transaction or the log_mutex */ /* Needs to either be called under a log transaction or the log_mutex */
void btrfs_get_logged_extents(struct inode *inode, void btrfs_get_logged_extents(struct inode *inode,
struct list_head *logged_list) struct list_head *logged_list,
const loff_t start,
const loff_t end)
{ {
struct btrfs_ordered_inode_tree *tree; struct btrfs_ordered_inode_tree *tree;
struct btrfs_ordered_extent *ordered; struct btrfs_ordered_extent *ordered;
struct rb_node *n; struct rb_node *n;
struct rb_node *prev;
tree = &BTRFS_I(inode)->ordered_tree; tree = &BTRFS_I(inode)->ordered_tree;
spin_lock_irq(&tree->lock); spin_lock_irq(&tree->lock);
for (n = rb_first(&tree->tree); n; n = rb_next(n)) { n = __tree_search(&tree->tree, end, &prev);
if (!n)
n = prev;
for (; n; n = rb_prev(n)) {
ordered = rb_entry(n, struct btrfs_ordered_extent, rb_node); ordered = rb_entry(n, struct btrfs_ordered_extent, rb_node);
if (ordered->file_offset > end)
continue;
if (entry_end(ordered) <= start)
break;
if (!list_empty(&ordered->log_list)) if (!list_empty(&ordered->log_list))
continue; continue;
if (test_bit(BTRFS_ORDERED_LOGGED, &ordered->flags)) if (test_bit(BTRFS_ORDERED_LOGGED, &ordered->flags))
continue; continue;
list_add_tail(&ordered->log_list, logged_list); list_add(&ordered->log_list, logged_list);
atomic_inc(&ordered->refs); atomic_inc(&ordered->refs);
} }
spin_unlock_irq(&tree->lock); spin_unlock_irq(&tree->lock);
......
...@@ -198,7 +198,9 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, ...@@ -198,7 +198,9 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr); int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr);
void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr); void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr);
void btrfs_get_logged_extents(struct inode *inode, void btrfs_get_logged_extents(struct inode *inode,
struct list_head *logged_list); struct list_head *logged_list,
const loff_t start,
const loff_t end);
void btrfs_put_logged_extents(struct list_head *logged_list); void btrfs_put_logged_extents(struct list_head *logged_list);
void btrfs_submit_logged_extents(struct list_head *logged_list, void btrfs_submit_logged_extents(struct list_head *logged_list,
struct btrfs_root *log); struct btrfs_root *log);
......
...@@ -3972,7 +3972,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, ...@@ -3972,7 +3972,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
mutex_lock(&BTRFS_I(inode)->log_mutex); mutex_lock(&BTRFS_I(inode)->log_mutex);
btrfs_get_logged_extents(inode, &logged_list); btrfs_get_logged_extents(inode, &logged_list, start, end);
/* /*
* a brute force approach to making sure we get the most uptodate * a brute force approach to making sure we get the most uptodate
......
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