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.16-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba:
"A few more fixes, almost all error handling one-liners and for stable.

- regression fix in directory logging items

- regression fix of extent buffer status bits handling after an error

- fix memory leak in error handling path in tree-log

- fix freeing invalid anon device number when handling errors during
subvolume creation

- fix warning when freeing leaf after subvolume creation failure

- fix missing blkdev put in device scan error handling

- fix invalid delayed ref after subvolume creation failure"

* tag 'for-5.16-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
btrfs: fix missing blkdev_put() call in btrfs_scan_one_device()
btrfs: fix warning when freeing leaf after subvolume creation failure
btrfs: fix invalid delayed ref after subvolume creation failure
btrfs: check WRITE_ERR when trying to read an extent buffer
btrfs: fix missing last dir item offset update when logging directory
btrfs: fix double free of anon_dev after failure to create subvolume
btrfs: fix memory leak in __add_inode_ref()

+54 -24
+9 -8
fs/btrfs/ctree.c
··· 463 463 BUG_ON(ret < 0); 464 464 rcu_assign_pointer(root->node, cow); 465 465 466 - btrfs_free_tree_block(trans, root, buf, parent_start, 467 - last_ref); 466 + btrfs_free_tree_block(trans, btrfs_root_id(root), buf, 467 + parent_start, last_ref); 468 468 free_extent_buffer(buf); 469 469 add_root_to_dirty_list(root); 470 470 } else { ··· 485 485 return ret; 486 486 } 487 487 } 488 - btrfs_free_tree_block(trans, root, buf, parent_start, 489 - last_ref); 488 + btrfs_free_tree_block(trans, btrfs_root_id(root), buf, 489 + parent_start, last_ref); 490 490 } 491 491 if (unlock_orig) 492 492 btrfs_tree_unlock(buf); ··· 927 927 free_extent_buffer(mid); 928 928 929 929 root_sub_used(root, mid->len); 930 - btrfs_free_tree_block(trans, root, mid, 0, 1); 930 + btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1); 931 931 /* once for the root ptr */ 932 932 free_extent_buffer_stale(mid); 933 933 return 0; ··· 986 986 btrfs_tree_unlock(right); 987 987 del_ptr(root, path, level + 1, pslot + 1); 988 988 root_sub_used(root, right->len); 989 - btrfs_free_tree_block(trans, root, right, 0, 1); 989 + btrfs_free_tree_block(trans, btrfs_root_id(root), right, 990 + 0, 1); 990 991 free_extent_buffer_stale(right); 991 992 right = NULL; 992 993 } else { ··· 1032 1031 btrfs_tree_unlock(mid); 1033 1032 del_ptr(root, path, level + 1, pslot); 1034 1033 root_sub_used(root, mid->len); 1035 - btrfs_free_tree_block(trans, root, mid, 0, 1); 1034 + btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1); 1036 1035 free_extent_buffer_stale(mid); 1037 1036 mid = NULL; 1038 1037 } else { ··· 4033 4032 root_sub_used(root, leaf->len); 4034 4033 4035 4034 atomic_inc(&leaf->refs); 4036 - btrfs_free_tree_block(trans, root, leaf, 0, 1); 4035 + btrfs_free_tree_block(trans, btrfs_root_id(root), leaf, 0, 1); 4037 4036 free_extent_buffer_stale(leaf); 4038 4037 } 4039 4038 /*
+6 -1
fs/btrfs/ctree.h
··· 2257 2257 return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_DEAD)) != 0; 2258 2258 } 2259 2259 2260 + static inline u64 btrfs_root_id(const struct btrfs_root *root) 2261 + { 2262 + return root->root_key.objectid; 2263 + } 2264 + 2260 2265 /* struct btrfs_root_backup */ 2261 2266 BTRFS_SETGET_STACK_FUNCS(backup_tree_root, struct btrfs_root_backup, 2262 2267 tree_root, 64); ··· 2724 2719 u64 empty_size, 2725 2720 enum btrfs_lock_nesting nest); 2726 2721 void btrfs_free_tree_block(struct btrfs_trans_handle *trans, 2727 - struct btrfs_root *root, 2722 + u64 root_id, 2728 2723 struct extent_buffer *buf, 2729 2724 u64 parent, int last_ref); 2730 2725 int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
+8
fs/btrfs/disk-io.c
··· 1732 1732 } 1733 1733 return root; 1734 1734 fail: 1735 + /* 1736 + * If our caller provided us an anonymous device, then it's his 1737 + * responsability to free it in case we fail. So we have to set our 1738 + * root's anon_dev to 0 to avoid a double free, once by btrfs_put_root() 1739 + * and once again by our caller. 1740 + */ 1741 + if (anon_dev) 1742 + root->anon_dev = 0; 1735 1743 btrfs_put_root(root); 1736 1744 return ERR_PTR(ret); 1737 1745 }
+7 -6
fs/btrfs/extent-tree.c
··· 3275 3275 } 3276 3276 3277 3277 void btrfs_free_tree_block(struct btrfs_trans_handle *trans, 3278 - struct btrfs_root *root, 3278 + u64 root_id, 3279 3279 struct extent_buffer *buf, 3280 3280 u64 parent, int last_ref) 3281 3281 { 3282 - struct btrfs_fs_info *fs_info = root->fs_info; 3282 + struct btrfs_fs_info *fs_info = trans->fs_info; 3283 3283 struct btrfs_ref generic_ref = { 0 }; 3284 3284 int ret; 3285 3285 3286 3286 btrfs_init_generic_ref(&generic_ref, BTRFS_DROP_DELAYED_REF, 3287 3287 buf->start, buf->len, parent); 3288 3288 btrfs_init_tree_ref(&generic_ref, btrfs_header_level(buf), 3289 - root->root_key.objectid, 0, false); 3289 + root_id, 0, false); 3290 3290 3291 - if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { 3291 + if (root_id != BTRFS_TREE_LOG_OBJECTID) { 3292 3292 btrfs_ref_tree_mod(fs_info, &generic_ref); 3293 3293 ret = btrfs_add_delayed_tree_ref(trans, &generic_ref, NULL); 3294 3294 BUG_ON(ret); /* -ENOMEM */ ··· 3298 3298 struct btrfs_block_group *cache; 3299 3299 bool must_pin = false; 3300 3300 3301 - if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { 3301 + if (root_id != BTRFS_TREE_LOG_OBJECTID) { 3302 3302 ret = check_ref_cleanup(trans, buf->start); 3303 3303 if (!ret) { 3304 3304 btrfs_redirty_list_add(trans->transaction, buf); ··· 5472 5472 goto owner_mismatch; 5473 5473 } 5474 5474 5475 - btrfs_free_tree_block(trans, root, eb, parent, wc->refs[level] == 1); 5475 + btrfs_free_tree_block(trans, btrfs_root_id(root), eb, parent, 5476 + wc->refs[level] == 1); 5476 5477 out: 5477 5478 wc->refs[level] = 0; 5478 5479 wc->flags[level] = 0;
+8
fs/btrfs/extent_io.c
··· 6611 6611 if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags)) 6612 6612 return 0; 6613 6613 6614 + /* 6615 + * We could have had EXTENT_BUFFER_UPTODATE cleared by the write 6616 + * operation, which could potentially still be in flight. In this case 6617 + * we simply want to return an error. 6618 + */ 6619 + if (unlikely(test_bit(EXTENT_BUFFER_WRITE_ERR, &eb->bflags))) 6620 + return -EIO; 6621 + 6614 6622 if (eb->fs_info->sectorsize < PAGE_SIZE) 6615 6623 return read_extent_buffer_subpage(eb, wait, mirror_num); 6616 6624
+2 -2
fs/btrfs/free-space-tree.c
··· 1256 1256 btrfs_tree_lock(free_space_root->node); 1257 1257 btrfs_clean_tree_block(free_space_root->node); 1258 1258 btrfs_tree_unlock(free_space_root->node); 1259 - btrfs_free_tree_block(trans, free_space_root, free_space_root->node, 1260 - 0, 1); 1259 + btrfs_free_tree_block(trans, btrfs_root_id(free_space_root), 1260 + free_space_root->node, 0, 1); 1261 1261 1262 1262 btrfs_put_root(free_space_root); 1263 1263
+6 -4
fs/btrfs/ioctl.c
··· 617 617 * Since we don't abort the transaction in this case, free the 618 618 * tree block so that we don't leak space and leave the 619 619 * filesystem in an inconsistent state (an extent item in the 620 - * extent tree without backreferences). Also no need to have 621 - * the tree block locked since it is not in any tree at this 622 - * point, so no other task can find it and use it. 620 + * extent tree with a backreference for a root that does not 621 + * exists). 623 622 */ 624 - btrfs_free_tree_block(trans, root, leaf, 0, 1); 623 + btrfs_tree_lock(leaf); 624 + btrfs_clean_tree_block(leaf); 625 + btrfs_tree_unlock(leaf); 626 + btrfs_free_tree_block(trans, objectid, leaf, 0, 1); 625 627 free_extent_buffer(leaf); 626 628 goto fail; 627 629 }
+2 -1
fs/btrfs/qgroup.c
··· 1219 1219 btrfs_tree_lock(quota_root->node); 1220 1220 btrfs_clean_tree_block(quota_root->node); 1221 1221 btrfs_tree_unlock(quota_root->node); 1222 - btrfs_free_tree_block(trans, quota_root, quota_root->node, 0, 1); 1222 + btrfs_free_tree_block(trans, btrfs_root_id(quota_root), 1223 + quota_root->node, 0, 1); 1223 1224 1224 1225 btrfs_put_root(quota_root); 1225 1226
+2
fs/btrfs/tree-log.c
··· 1181 1181 parent_objectid, victim_name, 1182 1182 victim_name_len); 1183 1183 if (ret < 0) { 1184 + kfree(victim_name); 1184 1185 return ret; 1185 1186 } else if (!ret) { 1186 1187 ret = -ENOENT; ··· 3978 3977 goto done; 3979 3978 } 3980 3979 if (btrfs_header_generation(path->nodes[0]) != trans->transid) { 3980 + ctx->last_dir_item_offset = min_key.offset; 3981 3981 ret = overwrite_item(trans, log, dst_path, 3982 3982 path->nodes[0], path->slots[0], 3983 3983 &min_key);
+4 -2
fs/btrfs/volumes.c
··· 1370 1370 1371 1371 bytenr_orig = btrfs_sb_offset(0); 1372 1372 ret = btrfs_sb_log_location_bdev(bdev, 0, READ, &bytenr); 1373 - if (ret) 1374 - return ERR_PTR(ret); 1373 + if (ret) { 1374 + device = ERR_PTR(ret); 1375 + goto error_bdev_put; 1376 + } 1375 1377 1376 1378 disk_super = btrfs_read_disk_super(bdev, bytenr, bytenr_orig); 1377 1379 if (IS_ERR(disk_super)) {