Skip to content

Commit 115fada

Browse files
committed
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()
2 parents dbf8932 + 3734352 commit 115fada

6 files changed

Lines changed: 46 additions & 33 deletions

File tree

fs/btrfs/file.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2019,13 +2019,14 @@ static vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf)
20192019
else
20202020
btrfs_delalloc_release_space(inode, data_reserved, page_start,
20212021
reserved_space, true);
2022-
extent_changeset_free(data_reserved);
20232022
out_noreserve:
20242023
if (only_release_metadata)
20252024
btrfs_check_nocow_unlock(inode);
20262025

20272026
sb_end_pagefault(inode->vfs_inode.i_sb);
20282027

2028+
extent_changeset_free(data_reserved);
2029+
20292030
if (ret < 0)
20302031
return vmf_error(ret);
20312032

fs/btrfs/inode.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off
256256
if (ret < 0) {
257257
btrfs_err_rl(fs_info, "failed to lookup extent item for logical %llu: %d",
258258
logical, ret);
259+
btrfs_release_path(&path);
259260
return;
260261
}
261262
eb = path.nodes[0];

fs/btrfs/qgroup.c

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,14 +1243,7 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info,
12431243
btrfs_end_transaction(trans);
12441244
else if (trans)
12451245
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);
12541247
return ret;
12551248
}
12561249

@@ -1682,12 +1675,7 @@ int btrfs_create_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid)
16821675
ret = btrfs_sysfs_add_one_qgroup(fs_info, qgroup);
16831676
out:
16841677
mutex_unlock(&fs_info->qgroup_ioctl_lock);
1685-
/*
1686-
* At this point we either failed at allocating prealloc, or we
1687-
* succeeded and passed the ownership to it to add_qgroup_rb(). In any
1688-
* case, this needs to be NULL or there is something wrong.
1689-
*/
1690-
ASSERT(prealloc == NULL);
1678+
kfree(prealloc);
16911679
return ret;
16921680
}
16931681

@@ -3279,7 +3267,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
32793267
struct btrfs_root *quota_root;
32803268
struct btrfs_qgroup *srcgroup;
32813269
struct btrfs_qgroup *dstgroup;
3282-
struct btrfs_qgroup *prealloc = NULL;
3270+
struct btrfs_qgroup *prealloc;
32833271
struct btrfs_qgroup_list **qlist_prealloc = NULL;
32843272
bool free_inherit = false;
32853273
bool need_rescan = false;
@@ -3520,14 +3508,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
35203508
}
35213509
if (free_inherit)
35223510
kfree(inherit);
3523-
3524-
/*
3525-
* At this point we either failed at allocating prealloc, or we
3526-
* succeeded and passed the ownership to it to add_qgroup_rb(). In any
3527-
* case, this needs to be NULL or there is something wrong.
3528-
*/
3529-
ASSERT(prealloc == NULL);
3530-
3511+
kfree(prealloc);
35313512
return ret;
35323513
}
35333514

fs/btrfs/tests/qgroup-tests.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,6 @@ static int remove_extent_ref(struct btrfs_root *root, u64 bytenr,
187187
ret = btrfs_search_slot(&trans, root, &key, path, -1, 1);
188188
if (ret) {
189189
test_err("couldn't find backref %d", ret);
190-
btrfs_free_path(path);
191190
return ret;
192191
}
193192
btrfs_del_item(&trans, root, path);

fs/btrfs/tree-log.c

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5865,14 +5865,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
58655865
struct btrfs_inode *curr_inode = start_inode;
58665866
int ret = 0;
58675867

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-
58765868
path = btrfs_alloc_path();
58775869
if (!path)
58785870
return -ENOMEM;
@@ -6051,6 +6043,33 @@ static int conflicting_inode_is_dir(struct btrfs_root *root, u64 ino,
60516043
return ret;
60526044
}
60536045

6046+
static bool can_log_conflicting_inode(const struct btrfs_trans_handle *trans,
6047+
const struct btrfs_inode *inode)
6048+
{
6049+
if (!S_ISDIR(inode->vfs_inode.i_mode))
6050+
return true;
6051+
6052+
if (inode->last_unlink_trans < trans->transid)
6053+
return true;
6054+
6055+
/*
6056+
* If this is a directory and its unlink_trans is not from a past
6057+
* transaction then we must fallback to a transaction commit in order
6058+
* to avoid getting a directory with 2 hard links after log replay.
6059+
*
6060+
* This happens if a directory A is renamed, moved from one parent
6061+
* directory to another one, a new file is created in the old parent
6062+
* directory with the old name of our directory A, the new file is
6063+
* fsynced, then we moved the new file to some other parent directory
6064+
* and fsync again the new file. This results in a log tree where we
6065+
* logged that directory A existed, with the INODE_REF item for the
6066+
* new location but without having logged its old parent inode, so
6067+
* that on log replay we add a new link for the new location but the
6068+
* old link remains, resulting in a link count of 2.
6069+
*/
6070+
return false;
6071+
}
6072+
60546073
static int add_conflicting_inode(struct btrfs_trans_handle *trans,
60556074
struct btrfs_root *root,
60566075
struct btrfs_path *path,
@@ -6154,6 +6173,11 @@ static int add_conflicting_inode(struct btrfs_trans_handle *trans,
61546173
return 0;
61556174
}
61566175

6176+
if (!can_log_conflicting_inode(trans, inode)) {
6177+
btrfs_add_delayed_iput(inode);
6178+
return BTRFS_LOG_FORCE_COMMIT;
6179+
}
6180+
61576181
btrfs_add_delayed_iput(inode);
61586182

61596183
ino_elem = kmalloc(sizeof(*ino_elem), GFP_NOFS);
@@ -6218,6 +6242,12 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
62186242
break;
62196243
}
62206244

6245+
if (!can_log_conflicting_inode(trans, inode)) {
6246+
btrfs_add_delayed_iput(inode);
6247+
ret = BTRFS_LOG_FORCE_COMMIT;
6248+
break;
6249+
}
6250+
62216251
/*
62226252
* Always log the directory, we cannot make this
62236253
* conditional on need_log_inode() because the directory

fs/btrfs/volumes.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7128,6 +7128,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_fs_info *fs_info,
71287128

71297129
fs_devices->seeding = true;
71307130
fs_devices->opened = 1;
7131+
list_add(&fs_devices->seed_list, &fs_info->fs_devices->seed_list);
71317132
return fs_devices;
71327133
}
71337134

0 commit comments

Comments
 (0)