Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull second set of btrfs updates from Chris Mason: "The most important changes here are from Josef, fixing a btrfs regression in 3.14 that can cause corruptions in the extent allocation tree when snapshots are in use. Josef also fixed some deadlocks in send/recv and other assorted races when balance is running" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (23 commits) Btrfs: fix compile warnings on on avr32 platform btrfs: allow mounting btrfs subvolumes with different ro/rw options btrfs: export global block reserve size as space_info btrfs: fix crash in remount(thread_pool=) case Btrfs: abort the transaction when we don't find our extent ref Btrfs: fix EINVAL checks in btrfs_clone Btrfs: fix unlock in __start_delalloc_inodes() Btrfs: scrub raid56 stripes in the right way Btrfs: don't compress for a small write Btrfs: more efficient io tree navigation on wait_extent_bit Btrfs: send, build path string only once in send_hole btrfs: filter invalid arg for btrfs resize Btrfs: send, fix data corruption due to incorrect hole detection Btrfs: kmalloc() doesn't return an ERR_PTR Btrfs: fix snapshot vs nocow writting btrfs: Change the expanding write sequence to fix snapshot related bug. btrfs: make device scan less noisy btrfs: fix lockdep warning with reclaim lock inversion Btrfs: hold the commit_root_sem when getting the commit root during send Btrfs: remove transaction from send ...
This commit is contained in:
@@ -394,6 +394,14 @@ static noinline int compress_file_range(struct inode *inode,
|
||||
(start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size))
|
||||
btrfs_add_inode_defrag(NULL, inode);
|
||||
|
||||
/*
|
||||
* skip compression for a small file range(<=blocksize) that
|
||||
* isn't an inline extent, since it dosen't save disk space at all.
|
||||
*/
|
||||
if ((end - start + 1) <= blocksize &&
|
||||
(start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size))
|
||||
goto cleanup_and_bail_uncompressed;
|
||||
|
||||
actual_end = min_t(u64, isize, end + 1);
|
||||
again:
|
||||
will_compress = 0;
|
||||
@@ -1270,6 +1278,15 @@ next_slot:
|
||||
disk_bytenr += extent_offset;
|
||||
disk_bytenr += cur_offset - found_key.offset;
|
||||
num_bytes = min(end + 1, extent_end) - cur_offset;
|
||||
/*
|
||||
* if there are pending snapshots for this root,
|
||||
* we fall into common COW way.
|
||||
*/
|
||||
if (!nolock) {
|
||||
err = btrfs_start_nocow_write(root);
|
||||
if (!err)
|
||||
goto out_check;
|
||||
}
|
||||
/*
|
||||
* force cow if csum exists in the range.
|
||||
* this ensure that csum for a given extent are
|
||||
@@ -1289,6 +1306,8 @@ next_slot:
|
||||
out_check:
|
||||
if (extent_end <= start) {
|
||||
path->slots[0]++;
|
||||
if (!nolock && nocow)
|
||||
btrfs_end_nocow_write(root);
|
||||
goto next_slot;
|
||||
}
|
||||
if (!nocow) {
|
||||
@@ -1306,8 +1325,11 @@ out_check:
|
||||
ret = cow_file_range(inode, locked_page,
|
||||
cow_start, found_key.offset - 1,
|
||||
page_started, nr_written, 1);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
if (!nolock && nocow)
|
||||
btrfs_end_nocow_write(root);
|
||||
goto error;
|
||||
}
|
||||
cow_start = (u64)-1;
|
||||
}
|
||||
|
||||
@@ -1354,8 +1376,11 @@ out_check:
|
||||
BTRFS_DATA_RELOC_TREE_OBJECTID) {
|
||||
ret = btrfs_reloc_clone_csums(inode, cur_offset,
|
||||
num_bytes);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
if (!nolock && nocow)
|
||||
btrfs_end_nocow_write(root);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
extent_clear_unlock_delalloc(inode, cur_offset,
|
||||
@@ -1363,6 +1388,8 @@ out_check:
|
||||
locked_page, EXTENT_LOCKED |
|
||||
EXTENT_DELALLOC, PAGE_UNLOCK |
|
||||
PAGE_SET_PRIVATE2);
|
||||
if (!nolock && nocow)
|
||||
btrfs_end_nocow_write(root);
|
||||
cur_offset = extent_end;
|
||||
if (cur_offset > end)
|
||||
break;
|
||||
@@ -8476,19 +8503,20 @@ static int __start_delalloc_inodes(struct btrfs_root *root, int delay_iput,
|
||||
else
|
||||
iput(inode);
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
goto out;
|
||||
}
|
||||
list_add_tail(&work->list, &works);
|
||||
btrfs_queue_work(root->fs_info->flush_workers,
|
||||
&work->work);
|
||||
ret++;
|
||||
if (nr != -1 && ret >= nr)
|
||||
break;
|
||||
goto out;
|
||||
cond_resched();
|
||||
spin_lock(&root->delalloc_lock);
|
||||
}
|
||||
spin_unlock(&root->delalloc_lock);
|
||||
|
||||
out:
|
||||
list_for_each_entry_safe(work, next, &works, list) {
|
||||
list_del_init(&work->list);
|
||||
btrfs_wait_and_free_delalloc_work(work);
|
||||
|
Reference in New Issue
Block a user