Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+58 -18
+13
fs/btrfs/extent_io.c
··· 3745 3745 static void set_btree_ioerr(struct page *page) 3746 3746 { 3747 3747 struct extent_buffer *eb = (struct extent_buffer *)page->private; 3748 + struct btrfs_fs_info *fs_info; 3748 3749 3749 3750 SetPageError(page); 3750 3751 if (test_and_set_bit(EXTENT_BUFFER_WRITE_ERR, &eb->bflags)) 3751 3752 return; 3753 + 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); 3752 3761 3753 3762 /* 3754 3763 * If writeback for a btree extent that doesn't belong to a log tree ··· 3995 3986 if (!ret) { 3996 3987 free_extent_buffer(eb); 3997 3988 continue; 3989 + } else if (ret < 0) { 3990 + done = 1; 3991 + free_extent_buffer(eb); 3992 + break; 3998 3993 } 3999 3994 4000 3995 ret = write_one_eb(eb, wbc, &epd);
+23 -15
fs/btrfs/qgroup.c
··· 3166 3166 btrfs_free_path(path); 3167 3167 3168 3168 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 - 3172 3169 if (err > 0 && 3173 3170 fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT) { 3174 3171 fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT; ··· 3181 3184 trans = btrfs_start_transaction(fs_info->quota_root, 1); 3182 3185 if (IS_ERR(trans)) { 3183 3186 err = PTR_ERR(trans); 3187 + trans = NULL; 3184 3188 btrfs_err(fs_info, 3185 3189 "fail to start transaction for status update: %d", 3186 3190 err); 3187 - goto done; 3188 3191 } 3189 - ret = update_qgroup_status_item(trans); 3190 - if (ret < 0) { 3191 - err = ret; 3192 - btrfs_err(fs_info, "fail to update qgroup status: %d", err); 3192 + 3193 + mutex_lock(&fs_info->qgroup_rescan_lock); 3194 + if (!btrfs_fs_closing(fs_info)) 3195 + fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN; 3196 + if (trans) { 3197 + ret = update_qgroup_status_item(trans); 3198 + if (ret < 0) { 3199 + err = ret; 3200 + btrfs_err(fs_info, "fail to update qgroup status: %d", 3201 + err); 3202 + } 3193 3203 } 3204 + fs_info->qgroup_rescan_running = false; 3205 + complete_all(&fs_info->qgroup_rescan_completion); 3206 + mutex_unlock(&fs_info->qgroup_rescan_lock); 3207 + 3208 + if (!trans) 3209 + return; 3210 + 3194 3211 btrfs_end_transaction(trans); 3195 3212 3196 3213 if (btrfs_fs_closing(fs_info)) { ··· 3215 3204 } else { 3216 3205 btrfs_err(fs_info, "qgroup scan failed with %d", err); 3217 3206 } 3218 - 3219 - done: 3220 - mutex_lock(&fs_info->qgroup_rescan_lock); 3221 - fs_info->qgroup_rescan_running = false; 3222 - mutex_unlock(&fs_info->qgroup_rescan_lock); 3223 - complete_all(&fs_info->qgroup_rescan_completion); 3224 3207 } 3225 3208 3226 3209 /* ··· 3442 3437 while ((unode = ulist_next(&reserved->range_changed, &uiter))) 3443 3438 clear_extent_bit(&BTRFS_I(inode)->io_tree, unode->val, 3444 3439 unode->aux, EXTENT_QGROUP_RESERVED, 0, 0, NULL); 3440 + /* Also free data bytes of already reserved one */ 3441 + btrfs_qgroup_free_refroot(root->fs_info, root->root_key.objectid, 3442 + orig_reserved, BTRFS_QGROUP_RSV_DATA); 3445 3443 extent_changeset_release(reserved); 3446 3444 return ret; 3447 3445 } ··· 3489 3481 * EXTENT_QGROUP_RESERVED, we won't double free. 3490 3482 * So not need to rush. 3491 3483 */ 3492 - ret = clear_record_extent_bits(&BTRFS_I(inode)->io_failure_tree, 3484 + ret = clear_record_extent_bits(&BTRFS_I(inode)->io_tree, 3493 3485 free_start, free_start + free_len - 1, 3494 3486 EXTENT_QGROUP_RESERVED, &changeset); 3495 3487 if (ret < 0)
+8 -1
fs/btrfs/relocation.c
··· 1435 1435 int clear_rsv = 0; 1436 1436 int ret; 1437 1437 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 + 1438 1445 if (root->reloc_root) { 1439 1446 reloc_root = root->reloc_root; 1440 1447 reloc_root->last_trans = trans->transid; ··· 2194 2187 /* Merged subvolume, cleanup its reloc root */ 2195 2188 struct btrfs_root *reloc_root = root->reloc_root; 2196 2189 2197 - clear_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state); 2198 2190 list_del_init(&root->reloc_dirty_list); 2199 2191 root->reloc_root = NULL; 2200 2192 if (reloc_root) { ··· 2202 2196 if (ret2 < 0 && !ret) 2203 2197 ret = ret2; 2204 2198 } 2199 + clear_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state); 2205 2200 btrfs_put_fs_root(root); 2206 2201 } else { 2207 2202 /* Orphan reloc tree, just clean it up */
+7 -1
fs/btrfs/tests/btrfs-tests.c
··· 52 52 53 53 struct inode *btrfs_new_test_inode(void) 54 54 { 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; 56 62 } 57 63 58 64 static int btrfs_init_test_fs(void)
+7 -1
fs/btrfs/volumes.c
··· 4063 4063 } 4064 4064 4065 4065 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; 4067 4073 for (i = 0; i < ARRAY_SIZE(btrfs_raid_array); i++) 4068 4074 if (num_devices >= btrfs_raid_array[i].devs_min) 4069 4075 allowed |= btrfs_raid_array[i].bg_flag;