diff options
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/tree-log.c | 29 |
1 files changed, 12 insertions, 17 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index bb3781fed8da..0b841eab6169 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -4428,12 +4428,9 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, char *ins_data; int i; int dst_index; - struct list_head ordered_sums; const bool skip_csum = (inode->flags & BTRFS_INODE_NODATASUM); const u64 i_size = i_size_read(&inode->vfs_inode); - INIT_LIST_HEAD(&ordered_sums); - ins_data = kmalloc(nr * sizeof(struct btrfs_key) + nr * sizeof(u32), GFP_NOFS); if (!ins_data) @@ -4450,6 +4447,9 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, for (i = 0; i < nr; i++) { const int src_slot = start_slot + i; struct btrfs_root *csum_root; + struct btrfs_ordered_sum *sums; + struct btrfs_ordered_sum *sums_next; + LIST_HEAD(ordered_sums); u64 disk_bytenr; u64 disk_num_bytes; u64 extent_offset; @@ -4523,6 +4523,15 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, if (ret) goto out; + list_for_each_entry_safe(sums, sums_next, &ordered_sums, list) { + if (!ret) + ret = log_csums(trans, inode, log, sums); + list_del(&sums->list); + kfree(sums); + } + if (ret) + goto out; + add_to_batch: ins_sizes[dst_index] = btrfs_item_size(src, src_slot); batch.total_data_size += ins_sizes[dst_index]; @@ -4596,20 +4605,6 @@ copy_item: out: kfree(ins_data); - /* - * we have to do this after the loop above to avoid changing the - * log tree while trying to change the log tree. - */ - while (!list_empty(&ordered_sums)) { - struct btrfs_ordered_sum *sums = list_entry(ordered_sums.next, - struct btrfs_ordered_sum, - list); - if (!ret) - ret = log_csums(trans, inode, log, sums); - list_del(&sums->list); - kfree(sums); - } - return ret; } |