Skip to content

Commit 2187f21

Browse files
committed
Merge tag 'for-5.5-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "A mix of regression fixes and regular fixes for stable trees: - fix swapped error messages for qgroup enable/rescan - fixes for NO_HOLES feature with clone range - fix deadlock between iget/srcu lock/synchronize srcu while freeing an inode - fix double lock on subvolume cross-rename - tree log fixes * fix missing data checksums after replaying a log tree * also teach tree-checker about this problem * skip log replay on orphaned roots - fix maximum devices constraints for RAID1C -3 and -4 - send: don't print warning on read-only mount regarding orphan cleanup - error handling fixes" * tag 'for-5.5-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: send: remove WARN_ON for readonly mount btrfs: do not leak reloc root if we fail to read the fs root btrfs: skip log replay on orphaned roots btrfs: handle ENOENT in btrfs_uuid_tree_iterate btrfs: abort transaction after failed inode updates in create_subvol Btrfs: fix hole extent items with a zero size after range cloning Btrfs: fix removal logic of the tree mod log that leads to use-after-free issues Btrfs: make tree checker detect checksum items with overlapping ranges Btrfs: fix missing data checksums after replaying a log tree btrfs: return error pointer from alloc_test_extent_buffer btrfs: fix devs_max constraints for raid1c3 and raid1c4 btrfs: tree-checker: Fix error format string for size_t btrfs: don't double lock the subvol_sem for rename exchange btrfs: handle error in btrfs_cache_block_group btrfs: do not call synchronize_srcu() in inode_tree_del Btrfs: fix cloning range with a hole when using the NO_HOLES feature btrfs: Fix error messages in qgroup_rescan_init
2 parents 2d3145f + fbd5429 commit 2187f21

17 files changed

+127
-56
lines changed

fs/btrfs/ctree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info,
379379
for (node = rb_first(tm_root); node; node = next) {
380380
next = rb_next(node);
381381
tm = rb_entry(node, struct tree_mod_elem, node);
382-
if (tm->seq > min_seq)
382+
if (tm->seq >= min_seq)
383383
continue;
384384
rb_erase(node, tm_root);
385385
kfree(tm);

fs/btrfs/ctree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2787,7 +2787,7 @@ struct btrfs_inode_extref *btrfs_find_name_in_ext_backref(
27872787
/* file-item.c */
27882788
struct btrfs_dio_private;
27892789
int btrfs_del_csums(struct btrfs_trans_handle *trans,
2790-
struct btrfs_fs_info *fs_info, u64 bytenr, u64 len);
2790+
struct btrfs_root *root, u64 bytenr, u64 len);
27912791
blk_status_t btrfs_lookup_bio_sums(struct inode *inode, struct bio *bio,
27922792
u8 *dst);
27932793
blk_status_t btrfs_lookup_bio_sums_dio(struct inode *inode, struct bio *bio,

fs/btrfs/extent-tree.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,8 +1869,8 @@ static int cleanup_ref_head(struct btrfs_trans_handle *trans,
18691869
btrfs_pin_extent(fs_info, head->bytenr,
18701870
head->num_bytes, 1);
18711871
if (head->is_data) {
1872-
ret = btrfs_del_csums(trans, fs_info, head->bytenr,
1873-
head->num_bytes);
1872+
ret = btrfs_del_csums(trans, fs_info->csum_root,
1873+
head->bytenr, head->num_bytes);
18741874
}
18751875
}
18761876

@@ -3175,7 +3175,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
31753175
btrfs_release_path(path);
31763176

31773177
if (is_data) {
3178-
ret = btrfs_del_csums(trans, info, bytenr, num_bytes);
3178+
ret = btrfs_del_csums(trans, info->csum_root, bytenr,
3179+
num_bytes);
31793180
if (ret) {
31803181
btrfs_abort_transaction(trans, ret);
31813182
goto out;
@@ -3799,6 +3800,7 @@ static noinline int find_free_extent(struct btrfs_fs_info *fs_info,
37993800
u64 flags, int delalloc)
38003801
{
38013802
int ret = 0;
3803+
int cache_block_group_error = 0;
38023804
struct btrfs_free_cluster *last_ptr = NULL;
38033805
struct btrfs_block_group *block_group = NULL;
38043806
struct find_free_extent_ctl ffe_ctl = {0};
@@ -3958,7 +3960,20 @@ static noinline int find_free_extent(struct btrfs_fs_info *fs_info,
39583960
if (unlikely(!ffe_ctl.cached)) {
39593961
ffe_ctl.have_caching_bg = true;
39603962
ret = btrfs_cache_block_group(block_group, 0);
3961-
BUG_ON(ret < 0);
3963+
3964+
/*
3965+
* If we get ENOMEM here or something else we want to
3966+
* try other block groups, because it may not be fatal.
3967+
* However if we can't find anything else we need to
3968+
* save our return here so that we return the actual
3969+
* error that caused problems, not ENOSPC.
3970+
*/
3971+
if (ret < 0) {
3972+
if (!cache_block_group_error)
3973+
cache_block_group_error = ret;
3974+
ret = 0;
3975+
goto loop;
3976+
}
39623977
ret = 0;
39633978
}
39643979

@@ -4045,7 +4060,7 @@ static noinline int find_free_extent(struct btrfs_fs_info *fs_info,
40454060
if (ret > 0)
40464061
goto search;
40474062

4048-
if (ret == -ENOSPC) {
4063+
if (ret == -ENOSPC && !cache_block_group_error) {
40494064
/*
40504065
* Use ffe_ctl->total_free_space as fallback if we can't find
40514066
* any contiguous hole.
@@ -4056,6 +4071,8 @@ static noinline int find_free_extent(struct btrfs_fs_info *fs_info,
40564071
space_info->max_extent_size = ffe_ctl.max_extent_size;
40574072
spin_unlock(&space_info->lock);
40584073
ins->offset = ffe_ctl.max_extent_size;
4074+
} else if (ret == -ENOSPC) {
4075+
ret = cache_block_group_error;
40594076
}
40604077
return ret;
40614078
}

fs/btrfs/extent_io.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5074,12 +5074,14 @@ struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info,
50745074
return eb;
50755075
eb = alloc_dummy_extent_buffer(fs_info, start);
50765076
if (!eb)
5077-
return NULL;
5077+
return ERR_PTR(-ENOMEM);
50785078
eb->fs_info = fs_info;
50795079
again:
50805080
ret = radix_tree_preload(GFP_NOFS);
5081-
if (ret)
5081+
if (ret) {
5082+
exists = ERR_PTR(ret);
50825083
goto free_eb;
5084+
}
50835085
spin_lock(&fs_info->buffer_lock);
50845086
ret = radix_tree_insert(&fs_info->buffer_radix,
50855087
start >> PAGE_SHIFT, eb);

fs/btrfs/file-item.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -590,9 +590,9 @@ static noinline void truncate_one_csum(struct btrfs_fs_info *fs_info,
590590
* range of bytes.
591591
*/
592592
int btrfs_del_csums(struct btrfs_trans_handle *trans,
593-
struct btrfs_fs_info *fs_info, u64 bytenr, u64 len)
593+
struct btrfs_root *root, u64 bytenr, u64 len)
594594
{
595-
struct btrfs_root *root = fs_info->csum_root;
595+
struct btrfs_fs_info *fs_info = trans->fs_info;
596596
struct btrfs_path *path;
597597
struct btrfs_key key;
598598
u64 end_byte = bytenr + len;
@@ -602,6 +602,9 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans,
602602
u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
603603
int blocksize_bits = fs_info->sb->s_blocksize_bits;
604604

605+
ASSERT(root == fs_info->csum_root ||
606+
root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID);
607+
605608
path = btrfs_alloc_path();
606609
if (!path)
607610
return -ENOMEM;

fs/btrfs/file.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2599,8 +2599,8 @@ int btrfs_punch_hole_range(struct inode *inode, struct btrfs_path *path,
25992599
}
26002600
}
26012601

2602-
if (clone_info) {
2603-
u64 clone_len = drop_end - cur_offset;
2602+
if (clone_info && drop_end > clone_info->file_offset) {
2603+
u64 clone_len = drop_end - clone_info->file_offset;
26042604

26052605
ret = btrfs_insert_clone_extent(trans, inode, path,
26062606
clone_info, clone_len);

fs/btrfs/inode.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5728,7 +5728,6 @@ static void inode_tree_add(struct inode *inode)
57285728

57295729
static void inode_tree_del(struct inode *inode)
57305730
{
5731-
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
57325731
struct btrfs_root *root = BTRFS_I(inode)->root;
57335732
int empty = 0;
57345733

@@ -5741,7 +5740,6 @@ static void inode_tree_del(struct inode *inode)
57415740
spin_unlock(&root->inode_lock);
57425741

57435742
if (empty && btrfs_root_refs(&root->root_item) == 0) {
5744-
synchronize_srcu(&fs_info->subvol_srcu);
57455743
spin_lock(&root->inode_lock);
57465744
empty = RB_EMPTY_ROOT(&root->inode_tree);
57475745
spin_unlock(&root->inode_lock);
@@ -9556,9 +9554,8 @@ static int btrfs_rename_exchange(struct inode *old_dir,
95569554
btrfs_init_log_ctx(&ctx_dest, new_inode);
95579555

95589556
/* close the race window with snapshot create/destroy ioctl */
9559-
if (old_ino == BTRFS_FIRST_FREE_OBJECTID)
9560-
down_read(&fs_info->subvol_sem);
9561-
if (new_ino == BTRFS_FIRST_FREE_OBJECTID)
9557+
if (old_ino == BTRFS_FIRST_FREE_OBJECTID ||
9558+
new_ino == BTRFS_FIRST_FREE_OBJECTID)
95629559
down_read(&fs_info->subvol_sem);
95639560

95649561
/*
@@ -9792,9 +9789,8 @@ static int btrfs_rename_exchange(struct inode *old_dir,
97929789
ret = ret ? ret : ret2;
97939790
}
97949791
out_notrans:
9795-
if (new_ino == BTRFS_FIRST_FREE_OBJECTID)
9796-
up_read(&fs_info->subvol_sem);
9797-
if (old_ino == BTRFS_FIRST_FREE_OBJECTID)
9792+
if (new_ino == BTRFS_FIRST_FREE_OBJECTID ||
9793+
old_ino == BTRFS_FIRST_FREE_OBJECTID)
97989794
up_read(&fs_info->subvol_sem);
97999795

98009796
ASSERT(list_empty(&ctx_root.list));

fs/btrfs/ioctl.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -704,11 +704,17 @@ static noinline int create_subvol(struct inode *dir,
704704

705705
btrfs_i_size_write(BTRFS_I(dir), dir->i_size + namelen * 2);
706706
ret = btrfs_update_inode(trans, root, dir);
707-
BUG_ON(ret);
707+
if (ret) {
708+
btrfs_abort_transaction(trans, ret);
709+
goto fail;
710+
}
708711

709712
ret = btrfs_add_root_ref(trans, objectid, root->root_key.objectid,
710713
btrfs_ino(BTRFS_I(dir)), index, name, namelen);
711-
BUG_ON(ret);
714+
if (ret) {
715+
btrfs_abort_transaction(trans, ret);
716+
goto fail;
717+
}
712718

713719
ret = btrfs_uuid_tree_add(trans, root_item->uuid,
714720
BTRFS_UUID_KEY_SUBVOL, objectid);
@@ -3720,24 +3726,18 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
37203726
ret = 0;
37213727

37223728
if (last_dest_end < destoff + len) {
3723-
struct btrfs_clone_extent_info clone_info = { 0 };
37243729
/*
3725-
* We have an implicit hole (NO_HOLES feature is enabled) that
3726-
* fully or partially overlaps our cloning range at its end.
3730+
* We have an implicit hole that fully or partially overlaps our
3731+
* cloning range at its end. This means that we either have the
3732+
* NO_HOLES feature enabled or the implicit hole happened due to
3733+
* mixing buffered and direct IO writes against this file.
37273734
*/
37283735
btrfs_release_path(path);
37293736
path->leave_spinning = 0;
37303737

3731-
/*
3732-
* We are dealing with a hole and our clone_info already has a
3733-
* disk_offset of 0, we only need to fill the data length and
3734-
* file offset.
3735-
*/
3736-
clone_info.data_len = destoff + len - last_dest_end;
3737-
clone_info.file_offset = last_dest_end;
37383738
ret = btrfs_punch_hole_range(inode, path,
37393739
last_dest_end, destoff + len - 1,
3740-
&clone_info, &trans);
3740+
NULL, &trans);
37413741
if (ret)
37423742
goto out;
37433743

fs/btrfs/qgroup.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3232,12 +3232,12 @@ qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
32323232
if (!(fs_info->qgroup_flags &
32333233
BTRFS_QGROUP_STATUS_FLAG_RESCAN)) {
32343234
btrfs_warn(fs_info,
3235-
"qgroup rescan init failed, qgroup is not enabled");
3235+
"qgroup rescan init failed, qgroup rescan is not queued");
32363236
ret = -EINVAL;
32373237
} else if (!(fs_info->qgroup_flags &
32383238
BTRFS_QGROUP_STATUS_FLAG_ON)) {
32393239
btrfs_warn(fs_info,
3240-
"qgroup rescan init failed, qgroup rescan is not queued");
3240+
"qgroup rescan init failed, qgroup is not enabled");
32413241
ret = -EINVAL;
32423242
}
32433243

fs/btrfs/relocation.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4552,6 +4552,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
45524552
fs_root = read_fs_root(fs_info, reloc_root->root_key.offset);
45534553
if (IS_ERR(fs_root)) {
45544554
err = PTR_ERR(fs_root);
4555+
list_add_tail(&reloc_root->root_list, &reloc_roots);
45554556
goto out_free;
45564557
}
45574558

0 commit comments

Comments
 (0)