Skip to content

Commit bb48a59

Browse files
committed
Merge tag 'for-5.4-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "A bunch of fixes that accumulated in recent weeks, mostly material for stable. Summary: - fix for regression from 5.3 that prevents to use balance convert with single profile - qgroup fixes: rescan race, accounting leak with multiple writers, potential leak after io failure recovery - fix for use after free in relocation (reported by KASAN) - other error handling fixups" * tag 'for-5.4-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: qgroup: Fix reserved data space leak if we have multiple reserve calls btrfs: qgroup: Fix the wrong target io_tree when freeing reserved data space btrfs: Fix a regression which we can't convert to SINGLE profile btrfs: relocation: fix use-after-free on dead relocation roots Btrfs: fix race setting up and completing qgroup rescan workers Btrfs: fix missing error return if writeback for extent buffer never started btrfs: adjust dirty_metadata_bytes after writeback failure of extent buffer Btrfs: fix selftests failure due to uninitialized i_mode in test inodes
2 parents 80b29b6 + d4e2049 commit bb48a59

File tree

5 files changed

+58
-18
lines changed

5 files changed

+58
-18
lines changed

fs/btrfs/extent_io.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3745,11 +3745,20 @@ static noinline_for_stack int lock_extent_buffer_for_io(struct extent_buffer *eb
37453745
static void set_btree_ioerr(struct page *page)
37463746
{
37473747
struct extent_buffer *eb = (struct extent_buffer *)page->private;
3748+
struct btrfs_fs_info *fs_info;
37483749

37493750
SetPageError(page);
37503751
if (test_and_set_bit(EXTENT_BUFFER_WRITE_ERR, &eb->bflags))
37513752
return;
37523753

3754+
/*
3755+
* If we error out, we should add back the dirty_metadata_bytes
3756+
* to make it consistent.
3757+
*/
3758+
fs_info = eb->fs_info;
3759+
percpu_counter_add_batch(&fs_info->dirty_metadata_bytes,
3760+
eb->len, fs_info->dirty_metadata_batch);
3761+
37533762
/*
37543763
* If writeback for a btree extent that doesn't belong to a log tree
37553764
* failed, increment the counter transaction->eb_write_errors.
@@ -3986,6 +3995,10 @@ int btree_write_cache_pages(struct address_space *mapping,
39863995
if (!ret) {
39873996
free_extent_buffer(eb);
39883997
continue;
3998+
} else if (ret < 0) {
3999+
done = 1;
4000+
free_extent_buffer(eb);
4001+
break;
39894002
}
39904003

39914004
ret = write_one_eb(eb, wbc, &epd);

fs/btrfs/qgroup.c

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3166,9 +3166,6 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
31663166
btrfs_free_path(path);
31673167

31683168
mutex_lock(&fs_info->qgroup_rescan_lock);
3169-
if (!btrfs_fs_closing(fs_info))
3170-
fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
3171-
31723169
if (err > 0 &&
31733170
fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT) {
31743171
fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
@@ -3184,16 +3181,30 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
31843181
trans = btrfs_start_transaction(fs_info->quota_root, 1);
31853182
if (IS_ERR(trans)) {
31863183
err = PTR_ERR(trans);
3184+
trans = NULL;
31873185
btrfs_err(fs_info,
31883186
"fail to start transaction for status update: %d",
31893187
err);
3190-
goto done;
31913188
}
3192-
ret = update_qgroup_status_item(trans);
3193-
if (ret < 0) {
3194-
err = ret;
3195-
btrfs_err(fs_info, "fail to update qgroup status: %d", err);
3189+
3190+
mutex_lock(&fs_info->qgroup_rescan_lock);
3191+
if (!btrfs_fs_closing(fs_info))
3192+
fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
3193+
if (trans) {
3194+
ret = update_qgroup_status_item(trans);
3195+
if (ret < 0) {
3196+
err = ret;
3197+
btrfs_err(fs_info, "fail to update qgroup status: %d",
3198+
err);
3199+
}
31963200
}
3201+
fs_info->qgroup_rescan_running = false;
3202+
complete_all(&fs_info->qgroup_rescan_completion);
3203+
mutex_unlock(&fs_info->qgroup_rescan_lock);
3204+
3205+
if (!trans)
3206+
return;
3207+
31973208
btrfs_end_transaction(trans);
31983209

31993210
if (btrfs_fs_closing(fs_info)) {
@@ -3204,12 +3215,6 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
32043215
} else {
32053216
btrfs_err(fs_info, "qgroup scan failed with %d", err);
32063217
}
3207-
3208-
done:
3209-
mutex_lock(&fs_info->qgroup_rescan_lock);
3210-
fs_info->qgroup_rescan_running = false;
3211-
mutex_unlock(&fs_info->qgroup_rescan_lock);
3212-
complete_all(&fs_info->qgroup_rescan_completion);
32133218
}
32143219

32153220
/*
@@ -3437,6 +3442,9 @@ int btrfs_qgroup_reserve_data(struct inode *inode,
34373442
while ((unode = ulist_next(&reserved->range_changed, &uiter)))
34383443
clear_extent_bit(&BTRFS_I(inode)->io_tree, unode->val,
34393444
unode->aux, EXTENT_QGROUP_RESERVED, 0, 0, NULL);
3445+
/* Also free data bytes of already reserved one */
3446+
btrfs_qgroup_free_refroot(root->fs_info, root->root_key.objectid,
3447+
orig_reserved, BTRFS_QGROUP_RSV_DATA);
34403448
extent_changeset_release(reserved);
34413449
return ret;
34423450
}
@@ -3481,7 +3489,7 @@ static int qgroup_free_reserved_data(struct inode *inode,
34813489
* EXTENT_QGROUP_RESERVED, we won't double free.
34823490
* So not need to rush.
34833491
*/
3484-
ret = clear_record_extent_bits(&BTRFS_I(inode)->io_failure_tree,
3492+
ret = clear_record_extent_bits(&BTRFS_I(inode)->io_tree,
34853493
free_start, free_start + free_len - 1,
34863494
EXTENT_QGROUP_RESERVED, &changeset);
34873495
if (ret < 0)

fs/btrfs/relocation.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1435,6 +1435,13 @@ int btrfs_init_reloc_root(struct btrfs_trans_handle *trans,
14351435
int clear_rsv = 0;
14361436
int ret;
14371437

1438+
/*
1439+
* The subvolume has reloc tree but the swap is finished, no need to
1440+
* create/update the dead reloc tree
1441+
*/
1442+
if (test_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state))
1443+
return 0;
1444+
14381445
if (root->reloc_root) {
14391446
reloc_root = root->reloc_root;
14401447
reloc_root->last_trans = trans->transid;
@@ -2187,7 +2194,6 @@ static int clean_dirty_subvols(struct reloc_control *rc)
21872194
/* Merged subvolume, cleanup its reloc root */
21882195
struct btrfs_root *reloc_root = root->reloc_root;
21892196

2190-
clear_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state);
21912197
list_del_init(&root->reloc_dirty_list);
21922198
root->reloc_root = NULL;
21932199
if (reloc_root) {
@@ -2196,6 +2202,7 @@ static int clean_dirty_subvols(struct reloc_control *rc)
21962202
if (ret2 < 0 && !ret)
21972203
ret = ret2;
21982204
}
2205+
clear_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state);
21992206
btrfs_put_fs_root(root);
22002207
} else {
22012208
/* Orphan reloc tree, just clean it up */

fs/btrfs/tests/btrfs-tests.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,13 @@ static struct file_system_type test_type = {
5252

5353
struct inode *btrfs_new_test_inode(void)
5454
{
55-
return new_inode(test_mnt->mnt_sb);
55+
struct inode *inode;
56+
57+
inode = new_inode(test_mnt->mnt_sb);
58+
if (inode)
59+
inode_init_owner(inode, NULL, S_IFREG);
60+
61+
return inode;
5662
}
5763

5864
static int btrfs_init_test_fs(void)

fs/btrfs/volumes.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4063,7 +4063,13 @@ int btrfs_balance(struct btrfs_fs_info *fs_info,
40634063
}
40644064

40654065
num_devices = btrfs_num_devices(fs_info);
4066-
allowed = 0;
4066+
4067+
/*
4068+
* SINGLE profile on-disk has no profile bit, but in-memory we have a
4069+
* special bit for it, to make it easier to distinguish. Thus we need
4070+
* to set it manually, or balance would refuse the profile.
4071+
*/
4072+
allowed = BTRFS_AVAIL_ALLOC_BIT_SINGLE;
40674073
for (i = 0; i < ARRAY_SIZE(btrfs_raid_array); i++)
40684074
if (num_devices >= btrfs_raid_array[i].devs_min)
40694075
allowed |= btrfs_raid_array[i].bg_flag;

0 commit comments

Comments
 (0)