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

Pull btrfs fixes from David Sterba:

- fix potential deadlock due to mismatching transaction states when
waiting for the current transaction

- fix squota accounting with nested snapshots

- fix quota inheritance of qgroups with multiple parent qgroups

- fix NULL inode pointer in evict tracepoint

- fix writes beyond end of file on systems with 64K page size and 4K
block size

- fix logging of inodes after exchange rename

- fix use after free when using ref_tracker feature

- space reservation fixes

* tag 'for-6.19-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
btrfs: fix reservation leak in some error paths when inserting inline extent
btrfs: do not free data reservation in fallback from inline due to -ENOSPC
btrfs: fix use-after-free warning in btrfs_get_or_create_delayed_node()
btrfs: always detect conflicting inodes when logging inode refs
btrfs: fix beyond-EOF write handling
btrfs: fix deadlock in wait_current_trans() due to ignored transaction type
btrfs: fix NULL dereference on root when tracing inode eviction
btrfs: qgroup: update all parent qgroups when doing quick inherit
btrfs: fix qgroup_snapshot_quick_inherit() squota bug

+65 -38
+17 -15
fs/btrfs/delayed-inode.c
··· 152 152 return ERR_PTR(-ENOMEM); 153 153 btrfs_init_delayed_node(node, root, ino); 154 154 155 + /* Cached in the inode and can be accessed. */ 156 + refcount_set(&node->refs, 2); 157 + btrfs_delayed_node_ref_tracker_alloc(node, tracker, GFP_NOFS); 158 + btrfs_delayed_node_ref_tracker_alloc(node, &node->inode_cache_tracker, GFP_NOFS); 159 + 155 160 /* Allocate and reserve the slot, from now it can return a NULL from xa_load(). */ 156 161 ret = xa_reserve(&root->delayed_nodes, ino, GFP_NOFS); 157 - if (ret == -ENOMEM) { 158 - btrfs_delayed_node_ref_tracker_dir_exit(node); 159 - kmem_cache_free(delayed_node_cache, node); 160 - return ERR_PTR(-ENOMEM); 161 - } 162 + if (ret == -ENOMEM) 163 + goto cleanup; 164 + 162 165 xa_lock(&root->delayed_nodes); 163 166 ptr = xa_load(&root->delayed_nodes, ino); 164 167 if (ptr) { 165 168 /* Somebody inserted it, go back and read it. */ 166 169 xa_unlock(&root->delayed_nodes); 167 - btrfs_delayed_node_ref_tracker_dir_exit(node); 168 - kmem_cache_free(delayed_node_cache, node); 169 - node = NULL; 170 - goto again; 170 + goto cleanup; 171 171 } 172 172 ptr = __xa_store(&root->delayed_nodes, ino, node, GFP_ATOMIC); 173 173 ASSERT(xa_err(ptr) != -EINVAL); 174 174 ASSERT(xa_err(ptr) != -ENOMEM); 175 175 ASSERT(ptr == NULL); 176 - 177 - /* Cached in the inode and can be accessed. */ 178 - refcount_set(&node->refs, 2); 179 - btrfs_delayed_node_ref_tracker_alloc(node, tracker, GFP_ATOMIC); 180 - btrfs_delayed_node_ref_tracker_alloc(node, &node->inode_cache_tracker, GFP_ATOMIC); 181 - 182 176 btrfs_inode->delayed_node = node; 183 177 xa_unlock(&root->delayed_nodes); 184 178 185 179 return node; 180 + cleanup: 181 + btrfs_delayed_node_ref_tracker_free(node, tracker); 182 + btrfs_delayed_node_ref_tracker_free(node, &node->inode_cache_tracker); 183 + btrfs_delayed_node_ref_tracker_dir_exit(node); 184 + kmem_cache_free(delayed_node_cache, node); 185 + if (ret) 186 + return ERR_PTR(ret); 187 + goto again; 186 188 } 187 189 188 190 /*
+4 -4
fs/btrfs/extent_io.c
··· 1728 1728 struct btrfs_ordered_extent *ordered; 1729 1729 1730 1730 ordered = btrfs_lookup_first_ordered_range(inode, cur, 1731 - folio_end - cur); 1731 + fs_info->sectorsize); 1732 1732 /* 1733 1733 * We have just run delalloc before getting here, so 1734 1734 * there must be an ordered extent. ··· 1742 1742 btrfs_put_ordered_extent(ordered); 1743 1743 1744 1744 btrfs_mark_ordered_io_finished(inode, folio, cur, 1745 - end - cur, true); 1745 + fs_info->sectorsize, true); 1746 1746 /* 1747 1747 * This range is beyond i_size, thus we don't need to 1748 1748 * bother writing back. ··· 1751 1751 * writeback the sectors with subpage dirty bits, 1752 1752 * causing writeback without ordered extent. 1753 1753 */ 1754 - btrfs_folio_clear_dirty(fs_info, folio, cur, end - cur); 1755 - break; 1754 + btrfs_folio_clear_dirty(fs_info, folio, cur, fs_info->sectorsize); 1755 + continue; 1756 1756 } 1757 1757 ret = submit_one_sector(inode, folio, cur, bio_ctrl, i_size); 1758 1758 if (unlikely(ret < 0)) {
+15 -7
fs/btrfs/inode.c
··· 618 618 struct btrfs_drop_extents_args drop_args = { 0 }; 619 619 struct btrfs_root *root = inode->root; 620 620 struct btrfs_fs_info *fs_info = root->fs_info; 621 - struct btrfs_trans_handle *trans; 621 + struct btrfs_trans_handle *trans = NULL; 622 622 u64 data_len = (compressed_size ?: size); 623 623 int ret; 624 624 struct btrfs_path *path; 625 625 626 626 path = btrfs_alloc_path(); 627 - if (!path) 628 - return -ENOMEM; 627 + if (!path) { 628 + ret = -ENOMEM; 629 + goto out; 630 + } 629 631 630 632 trans = btrfs_join_transaction(root); 631 633 if (IS_ERR(trans)) { 632 - btrfs_free_path(path); 633 - return PTR_ERR(trans); 634 + ret = PTR_ERR(trans); 635 + trans = NULL; 636 + goto out; 634 637 } 635 638 trans->block_rsv = &inode->block_rsv; 636 639 ··· 677 674 * it won't count as data extent, free them directly here. 678 675 * And at reserve time, it's always aligned to page size, so 679 676 * just free one page here. 677 + * 678 + * If we fallback to non-inline (ret == 1) due to -ENOSPC, then we need 679 + * to keep the data reservation. 680 680 */ 681 - btrfs_qgroup_free_data(inode, NULL, 0, fs_info->sectorsize, NULL); 681 + if (ret <= 0) 682 + btrfs_qgroup_free_data(inode, NULL, 0, fs_info->sectorsize, NULL); 682 683 btrfs_free_path(path); 683 - btrfs_end_transaction(trans); 684 + if (trans) 685 + btrfs_end_transaction(trans); 684 686 return ret; 685 687 } 686 688
+19 -2
fs/btrfs/qgroup.c
··· 3208 3208 { 3209 3209 struct btrfs_qgroup *src; 3210 3210 struct btrfs_qgroup *parent; 3211 + struct btrfs_qgroup *qgroup; 3211 3212 struct btrfs_qgroup_list *list; 3213 + LIST_HEAD(qgroup_list); 3214 + const u32 nodesize = fs_info->nodesize; 3212 3215 int nr_parents = 0; 3216 + 3217 + if (btrfs_qgroup_mode(fs_info) != BTRFS_QGROUP_MODE_FULL) 3218 + return 0; 3213 3219 3214 3220 src = find_qgroup_rb(fs_info, srcid); 3215 3221 if (!src) ··· 3251 3245 if (parent->excl != parent->rfer) 3252 3246 return 1; 3253 3247 3254 - parent->excl += fs_info->nodesize; 3255 - parent->rfer += fs_info->nodesize; 3248 + qgroup_iterator_add(&qgroup_list, parent); 3249 + list_for_each_entry(qgroup, &qgroup_list, iterator) { 3250 + qgroup->rfer += nodesize; 3251 + qgroup->rfer_cmpr += nodesize; 3252 + qgroup->excl += nodesize; 3253 + qgroup->excl_cmpr += nodesize; 3254 + qgroup_dirty(fs_info, qgroup); 3255 + 3256 + /* Append parent qgroups to @qgroup_list. */ 3257 + list_for_each_entry(list, &qgroup->groups, next_group) 3258 + qgroup_iterator_add(&qgroup_list, list->group); 3259 + } 3260 + qgroup_iterator_clean(&qgroup_list); 3256 3261 return 0; 3257 3262 } 3258 3263
+6 -5
fs/btrfs/transaction.c
··· 520 520 * when this is done, it is safe to start a new transaction, but the current 521 521 * transaction might not be fully on disk. 522 522 */ 523 - static void wait_current_trans(struct btrfs_fs_info *fs_info) 523 + static void wait_current_trans(struct btrfs_fs_info *fs_info, unsigned int type) 524 524 { 525 525 struct btrfs_transaction *cur_trans; 526 526 527 527 spin_lock(&fs_info->trans_lock); 528 528 cur_trans = fs_info->running_transaction; 529 - if (cur_trans && is_transaction_blocked(cur_trans)) { 529 + if (cur_trans && is_transaction_blocked(cur_trans) && 530 + (btrfs_blocked_trans_types[cur_trans->state] & type)) { 530 531 refcount_inc(&cur_trans->use_count); 531 532 spin_unlock(&fs_info->trans_lock); 532 533 ··· 702 701 sb_start_intwrite(fs_info->sb); 703 702 704 703 if (may_wait_transaction(fs_info, type)) 705 - wait_current_trans(fs_info); 704 + wait_current_trans(fs_info, type); 706 705 707 706 do { 708 707 ret = join_transaction(fs_info, type); 709 708 if (ret == -EBUSY) { 710 - wait_current_trans(fs_info); 709 + wait_current_trans(fs_info, type); 711 710 if (unlikely(type == TRANS_ATTACH || 712 711 type == TRANS_JOIN_NOSTART)) 713 712 ret = -ENOENT; ··· 1004 1003 1005 1004 void btrfs_throttle(struct btrfs_fs_info *fs_info) 1006 1005 { 1007 - wait_current_trans(fs_info); 1006 + wait_current_trans(fs_info, TRANS_START); 1008 1007 } 1009 1008 1010 1009 bool btrfs_should_end_transaction(struct btrfs_trans_handle *trans)
+2 -4
fs/btrfs/tree-log.c
··· 6341 6341 * and no keys greater than that, so bail out. 6342 6342 */ 6343 6343 break; 6344 - } else if ((min_key->type == BTRFS_INODE_REF_KEY || 6345 - min_key->type == BTRFS_INODE_EXTREF_KEY) && 6346 - (inode->generation == trans->transid || 6347 - ctx->logging_conflict_inodes)) { 6344 + } else if (min_key->type == BTRFS_INODE_REF_KEY || 6345 + min_key->type == BTRFS_INODE_EXTREF_KEY) { 6348 6346 u64 other_ino = 0; 6349 6347 u64 other_parent = 0; 6350 6348
+2 -1
include/trace/events/btrfs.h
··· 224 224 __entry->generation = BTRFS_I(inode)->generation; 225 225 __entry->last_trans = BTRFS_I(inode)->last_trans; 226 226 __entry->logged_trans = BTRFS_I(inode)->logged_trans; 227 - __entry->root_objectid = btrfs_root_id(BTRFS_I(inode)->root); 227 + __entry->root_objectid = BTRFS_I(inode)->root ? 228 + btrfs_root_id(BTRFS_I(inode)->root) : 0; 228 229 ), 229 230 230 231 TP_printk_btrfs("root=%llu(%s) gen=%llu ino=%llu blocks=%llu "