|
@@ -3479,7 +3479,8 @@ static int extent_cmp(void *priv, struct list_head *a, struct list_head *b)
|
|
|
|
|
|
static int log_one_extent(struct btrfs_trans_handle *trans,
|
|
static int log_one_extent(struct btrfs_trans_handle *trans,
|
|
struct inode *inode, struct btrfs_root *root,
|
|
struct inode *inode, struct btrfs_root *root,
|
|
- struct extent_map *em, struct btrfs_path *path)
|
|
|
|
|
|
+ struct extent_map *em, struct btrfs_path *path,
|
|
|
|
+ struct list_head *logged_list)
|
|
{
|
|
{
|
|
struct btrfs_root *log = root->log_root;
|
|
struct btrfs_root *log = root->log_root;
|
|
struct btrfs_file_extent_item *fi;
|
|
struct btrfs_file_extent_item *fi;
|
|
@@ -3495,7 +3496,6 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
|
|
u64 extent_offset = em->start - em->orig_start;
|
|
u64 extent_offset = em->start - em->orig_start;
|
|
u64 block_len;
|
|
u64 block_len;
|
|
int ret;
|
|
int ret;
|
|
- int index = log->log_transid % 2;
|
|
|
|
bool skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
|
|
bool skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
|
|
int extent_inserted = 0;
|
|
int extent_inserted = 0;
|
|
|
|
|
|
@@ -3579,17 +3579,12 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
|
|
* First check and see if our csums are on our outstanding ordered
|
|
* First check and see if our csums are on our outstanding ordered
|
|
* extents.
|
|
* extents.
|
|
*/
|
|
*/
|
|
-again:
|
|
|
|
- spin_lock_irq(&log->log_extents_lock[index]);
|
|
|
|
- list_for_each_entry(ordered, &log->logged_list[index], log_list) {
|
|
|
|
|
|
+ list_for_each_entry(ordered, logged_list, log_list) {
|
|
struct btrfs_ordered_sum *sum;
|
|
struct btrfs_ordered_sum *sum;
|
|
|
|
|
|
if (!mod_len)
|
|
if (!mod_len)
|
|
break;
|
|
break;
|
|
|
|
|
|
- if (ordered->inode != inode)
|
|
|
|
- continue;
|
|
|
|
-
|
|
|
|
if (ordered->file_offset + ordered->len <= mod_start ||
|
|
if (ordered->file_offset + ordered->len <= mod_start ||
|
|
mod_start + mod_len <= ordered->file_offset)
|
|
mod_start + mod_len <= ordered->file_offset)
|
|
continue;
|
|
continue;
|
|
@@ -3632,12 +3627,6 @@ again:
|
|
if (test_and_set_bit(BTRFS_ORDERED_LOGGED_CSUM,
|
|
if (test_and_set_bit(BTRFS_ORDERED_LOGGED_CSUM,
|
|
&ordered->flags))
|
|
&ordered->flags))
|
|
continue;
|
|
continue;
|
|
- atomic_inc(&ordered->refs);
|
|
|
|
- spin_unlock_irq(&log->log_extents_lock[index]);
|
|
|
|
- /*
|
|
|
|
- * we've dropped the lock, we must either break or
|
|
|
|
- * start over after this.
|
|
|
|
- */
|
|
|
|
|
|
|
|
if (ordered->csum_bytes_left) {
|
|
if (ordered->csum_bytes_left) {
|
|
btrfs_start_ordered_extent(inode, ordered, 0);
|
|
btrfs_start_ordered_extent(inode, ordered, 0);
|
|
@@ -3647,16 +3636,11 @@ again:
|
|
|
|
|
|
list_for_each_entry(sum, &ordered->list, list) {
|
|
list_for_each_entry(sum, &ordered->list, list) {
|
|
ret = btrfs_csum_file_blocks(trans, log, sum);
|
|
ret = btrfs_csum_file_blocks(trans, log, sum);
|
|
- if (ret) {
|
|
|
|
- btrfs_put_ordered_extent(ordered);
|
|
|
|
|
|
+ if (ret)
|
|
goto unlocked;
|
|
goto unlocked;
|
|
- }
|
|
|
|
}
|
|
}
|
|
- btrfs_put_ordered_extent(ordered);
|
|
|
|
- goto again;
|
|
|
|
|
|
|
|
}
|
|
}
|
|
- spin_unlock_irq(&log->log_extents_lock[index]);
|
|
|
|
unlocked:
|
|
unlocked:
|
|
|
|
|
|
if (!mod_len || ret)
|
|
if (!mod_len || ret)
|
|
@@ -3694,7 +3678,8 @@ unlocked:
|
|
static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
|
|
static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
|
|
struct btrfs_root *root,
|
|
struct btrfs_root *root,
|
|
struct inode *inode,
|
|
struct inode *inode,
|
|
- struct btrfs_path *path)
|
|
|
|
|
|
+ struct btrfs_path *path,
|
|
|
|
+ struct list_head *logged_list)
|
|
{
|
|
{
|
|
struct extent_map *em, *n;
|
|
struct extent_map *em, *n;
|
|
struct list_head extents;
|
|
struct list_head extents;
|
|
@@ -3752,7 +3737,7 @@ process:
|
|
|
|
|
|
write_unlock(&tree->lock);
|
|
write_unlock(&tree->lock);
|
|
|
|
|
|
- ret = log_one_extent(trans, inode, root, em, path);
|
|
|
|
|
|
+ ret = log_one_extent(trans, inode, root, em, path, logged_list);
|
|
write_lock(&tree->lock);
|
|
write_lock(&tree->lock);
|
|
clear_em_logging(tree, em);
|
|
clear_em_logging(tree, em);
|
|
free_extent_map(em);
|
|
free_extent_map(em);
|
|
@@ -3788,6 +3773,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
|
|
struct btrfs_key max_key;
|
|
struct btrfs_key max_key;
|
|
struct btrfs_root *log = root->log_root;
|
|
struct btrfs_root *log = root->log_root;
|
|
struct extent_buffer *src = NULL;
|
|
struct extent_buffer *src = NULL;
|
|
|
|
+ LIST_HEAD(logged_list);
|
|
u64 last_extent = 0;
|
|
u64 last_extent = 0;
|
|
int err = 0;
|
|
int err = 0;
|
|
int ret;
|
|
int ret;
|
|
@@ -3836,7 +3822,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(log, inode);
|
|
|
|
|
|
+ btrfs_get_logged_extents(inode, &logged_list);
|
|
|
|
|
|
/*
|
|
/*
|
|
* a brute force approach to making sure we get the most uptodate
|
|
* a brute force approach to making sure we get the most uptodate
|
|
@@ -3962,7 +3948,8 @@ log_extents:
|
|
btrfs_release_path(path);
|
|
btrfs_release_path(path);
|
|
btrfs_release_path(dst_path);
|
|
btrfs_release_path(dst_path);
|
|
if (fast_search) {
|
|
if (fast_search) {
|
|
- ret = btrfs_log_changed_extents(trans, root, inode, dst_path);
|
|
|
|
|
|
+ ret = btrfs_log_changed_extents(trans, root, inode, dst_path,
|
|
|
|
+ &logged_list);
|
|
if (ret) {
|
|
if (ret) {
|
|
err = ret;
|
|
err = ret;
|
|
goto out_unlock;
|
|
goto out_unlock;
|
|
@@ -3987,8 +3974,10 @@ log_extents:
|
|
BTRFS_I(inode)->logged_trans = trans->transid;
|
|
BTRFS_I(inode)->logged_trans = trans->transid;
|
|
BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->last_sub_trans;
|
|
BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->last_sub_trans;
|
|
out_unlock:
|
|
out_unlock:
|
|
- if (err)
|
|
|
|
- btrfs_free_logged_extents(log, log->log_transid);
|
|
|
|
|
|
+ if (unlikely(err))
|
|
|
|
+ btrfs_put_logged_extents(&logged_list);
|
|
|
|
+ else
|
|
|
|
+ btrfs_submit_logged_extents(&logged_list, log);
|
|
mutex_unlock(&BTRFS_I(inode)->log_mutex);
|
|
mutex_unlock(&BTRFS_I(inode)->log_mutex);
|
|
|
|
|
|
btrfs_free_path(path);
|
|
btrfs_free_path(path);
|