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

Pull btrfs fixes from David Sterba:

- fix missing btrfs_path release after printing a relocation error
message

- fix extent changeset leak on mmap write after failure to reserve
metadata

- fix fs devices list structure freeing, it could be potentially leaked
under some circumstances

- tree log fixes:
- fix incremental directory logging where inodes for new dentries
were incorrectly skipped
- don't log conflicting inode if it's a directory moved in the
current transaction

- regression fixes:
- fix incorrect btrfs_path freeing when it's auto-cleaned
- revert commit simplifying preallocation of temporary structures
in qgroup functions, some cases were not handled properly

* tag 'for-6.19-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
btrfs: fix changeset leak on mmap write after failure to reserve metadata
btrfs: fix memory leak of fs_devices in degraded seed device path
btrfs: fix a potential path leak in print_data_reloc_error()
Revert "btrfs: add ASSERTs on prealloc in qgroup functions"
btrfs: do not skip logging new dentries when logging a new name
btrfs: don't log conflicting inode if it's a dir moved in the current transaction
btrfs: tests: fix double btrfs_path free in remove_extent_ref()

+46 -33
+2 -1
fs/btrfs/file.c
··· 2019 2019 else 2020 2020 btrfs_delalloc_release_space(inode, data_reserved, page_start, 2021 2021 reserved_space, true); 2022 - extent_changeset_free(data_reserved); 2023 2022 out_noreserve: 2024 2023 if (only_release_metadata) 2025 2024 btrfs_check_nocow_unlock(inode); 2026 2025 2027 2026 sb_end_pagefault(inode->vfs_inode.i_sb); 2027 + 2028 + extent_changeset_free(data_reserved); 2028 2029 2029 2030 if (ret < 0) 2030 2031 return vmf_error(ret);
+1
fs/btrfs/inode.c
··· 256 256 if (ret < 0) { 257 257 btrfs_err_rl(fs_info, "failed to lookup extent item for logical %llu: %d", 258 258 logical, ret); 259 + btrfs_release_path(&path); 259 260 return; 260 261 } 261 262 eb = path.nodes[0];
+4 -23
fs/btrfs/qgroup.c
··· 1243 1243 btrfs_end_transaction(trans); 1244 1244 else if (trans) 1245 1245 ret = btrfs_end_transaction(trans); 1246 - 1247 - /* 1248 - * At this point we either failed at allocating prealloc, or we 1249 - * succeeded and passed the ownership to it to add_qgroup_rb(). In any 1250 - * case, this needs to be NULL or there is something wrong. 1251 - */ 1252 - ASSERT(prealloc == NULL); 1253 - 1246 + kfree(prealloc); 1254 1247 return ret; 1255 1248 } 1256 1249 ··· 1675 1682 ret = btrfs_sysfs_add_one_qgroup(fs_info, qgroup); 1676 1683 out: 1677 1684 mutex_unlock(&fs_info->qgroup_ioctl_lock); 1678 - /* 1679 - * At this point we either failed at allocating prealloc, or we 1680 - * succeeded and passed the ownership to it to add_qgroup_rb(). In any 1681 - * case, this needs to be NULL or there is something wrong. 1682 - */ 1683 - ASSERT(prealloc == NULL); 1685 + kfree(prealloc); 1684 1686 return ret; 1685 1687 } 1686 1688 ··· 3267 3279 struct btrfs_root *quota_root; 3268 3280 struct btrfs_qgroup *srcgroup; 3269 3281 struct btrfs_qgroup *dstgroup; 3270 - struct btrfs_qgroup *prealloc = NULL; 3282 + struct btrfs_qgroup *prealloc; 3271 3283 struct btrfs_qgroup_list **qlist_prealloc = NULL; 3272 3284 bool free_inherit = false; 3273 3285 bool need_rescan = false; ··· 3508 3520 } 3509 3521 if (free_inherit) 3510 3522 kfree(inherit); 3511 - 3512 - /* 3513 - * At this point we either failed at allocating prealloc, or we 3514 - * succeeded and passed the ownership to it to add_qgroup_rb(). In any 3515 - * case, this needs to be NULL or there is something wrong. 3516 - */ 3517 - ASSERT(prealloc == NULL); 3518 - 3523 + kfree(prealloc); 3519 3524 return ret; 3520 3525 } 3521 3526
-1
fs/btrfs/tests/qgroup-tests.c
··· 187 187 ret = btrfs_search_slot(&trans, root, &key, path, -1, 1); 188 188 if (ret) { 189 189 test_err("couldn't find backref %d", ret); 190 - btrfs_free_path(path); 191 190 return ret; 192 191 } 193 192 btrfs_del_item(&trans, root, path);
+38 -8
fs/btrfs/tree-log.c
··· 5865 5865 struct btrfs_inode *curr_inode = start_inode; 5866 5866 int ret = 0; 5867 5867 5868 - /* 5869 - * If we are logging a new name, as part of a link or rename operation, 5870 - * don't bother logging new dentries, as we just want to log the names 5871 - * of an inode and that any new parents exist. 5872 - */ 5873 - if (ctx->logging_new_name) 5874 - return 0; 5875 - 5876 5868 path = btrfs_alloc_path(); 5877 5869 if (!path) 5878 5870 return -ENOMEM; ··· 6043 6051 return ret; 6044 6052 } 6045 6053 6054 + static bool can_log_conflicting_inode(const struct btrfs_trans_handle *trans, 6055 + const struct btrfs_inode *inode) 6056 + { 6057 + if (!S_ISDIR(inode->vfs_inode.i_mode)) 6058 + return true; 6059 + 6060 + if (inode->last_unlink_trans < trans->transid) 6061 + return true; 6062 + 6063 + /* 6064 + * If this is a directory and its unlink_trans is not from a past 6065 + * transaction then we must fallback to a transaction commit in order 6066 + * to avoid getting a directory with 2 hard links after log replay. 6067 + * 6068 + * This happens if a directory A is renamed, moved from one parent 6069 + * directory to another one, a new file is created in the old parent 6070 + * directory with the old name of our directory A, the new file is 6071 + * fsynced, then we moved the new file to some other parent directory 6072 + * and fsync again the new file. This results in a log tree where we 6073 + * logged that directory A existed, with the INODE_REF item for the 6074 + * new location but without having logged its old parent inode, so 6075 + * that on log replay we add a new link for the new location but the 6076 + * old link remains, resulting in a link count of 2. 6077 + */ 6078 + return false; 6079 + } 6080 + 6046 6081 static int add_conflicting_inode(struct btrfs_trans_handle *trans, 6047 6082 struct btrfs_root *root, 6048 6083 struct btrfs_path *path, ··· 6173 6154 return 0; 6174 6155 } 6175 6156 6157 + if (!can_log_conflicting_inode(trans, inode)) { 6158 + btrfs_add_delayed_iput(inode); 6159 + return BTRFS_LOG_FORCE_COMMIT; 6160 + } 6161 + 6176 6162 btrfs_add_delayed_iput(inode); 6177 6163 6178 6164 ino_elem = kmalloc(sizeof(*ino_elem), GFP_NOFS); ··· 6239 6215 inode = btrfs_iget_logging(parent, root); 6240 6216 if (IS_ERR(inode)) { 6241 6217 ret = PTR_ERR(inode); 6218 + break; 6219 + } 6220 + 6221 + if (!can_log_conflicting_inode(trans, inode)) { 6222 + btrfs_add_delayed_iput(inode); 6223 + ret = BTRFS_LOG_FORCE_COMMIT; 6242 6224 break; 6243 6225 } 6244 6226
+1
fs/btrfs/volumes.c
··· 7128 7128 7129 7129 fs_devices->seeding = true; 7130 7130 fs_devices->opened = 1; 7131 + list_add(&fs_devices->seed_list, &fs_info->fs_devices->seed_list); 7131 7132 return fs_devices; 7132 7133 } 7133 7134