for-6.19-rc1-tag
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmlATDcACgkQxWXV+ddt
WDvWIA/7BP1o+7bGSY/HIwnVIwNyEd1YCpUrLZAd61C7t2OEZKCO13HtM9cZSIRb
z++k8iCkNl5Z3uZH/cQfUcCuA2sip9HSGaVrfeQ3qVnB/s3DMGb/mu1yBCKUo9/f
nCxpsIC7BD6cTaiAzCJ6JgvCjOSieG111s0/LGjDcjlM7YQoA8p/Jan1nlvfc8It
sTQ+ZCsuO/xHViQnfmT/XIyy5bSuSABb5LR78wp8wumngTL3ooBXGwWifrNT/egi
E06Hhnqopg1PjBDtQtmInJ1gh1E0capQ5j1Z6TDeMYCPeUOuPpRqLVrRP3bIM4jN
vDu5dZpM9r542Wpj/vZvs/UqmhczUmbQfjLfWdr+KORrl6RA9pkHXyFTFIsTKhGi
vtAsmMnu5FwKSlnZU1i/EuvcF89KEPx4jKRGQWiKUPwAuBUAkVa4xhsI/mAUmwv5
+Z+hQxPuIAdmcbLblsI0mnhCGjMTx+qUQQdhY2r7U2bOKhEds+XekABb9KBrjOdj
k8UEQZJwwWkcPSunYsOpBYBI1SIV8UeHtp8d2xrat90+Ome7feL1VFEjV/rOKc6w
f7hUeYZPVNQMcXdfNRkoXHK/zqKxpMF5lz9Tq3mzfF6XoseC+gSW44dWQnHPnI8X
kCj0bpg7o2WgGuc3UWIXrVXZmSEWhn30Go6UfsGqHT7xiULQvSc=
=lAhb
-----END PGP SIGNATURE-----
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()
master
commit
115fada16b
|
|
@ -2019,13 +2019,14 @@ out:
|
|||
else
|
||||
btrfs_delalloc_release_space(inode, data_reserved, page_start,
|
||||
reserved_space, true);
|
||||
extent_changeset_free(data_reserved);
|
||||
out_noreserve:
|
||||
if (only_release_metadata)
|
||||
btrfs_check_nocow_unlock(inode);
|
||||
|
||||
sb_end_pagefault(inode->vfs_inode.i_sb);
|
||||
|
||||
extent_changeset_free(data_reserved);
|
||||
|
||||
if (ret < 0)
|
||||
return vmf_error(ret);
|
||||
|
||||
|
|
|
|||
|
|
@ -256,6 +256,7 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off
|
|||
if (ret < 0) {
|
||||
btrfs_err_rl(fs_info, "failed to lookup extent item for logical %llu: %d",
|
||||
logical, ret);
|
||||
btrfs_release_path(&path);
|
||||
return;
|
||||
}
|
||||
eb = path.nodes[0];
|
||||
|
|
|
|||
|
|
@ -1243,14 +1243,7 @@ out:
|
|||
btrfs_end_transaction(trans);
|
||||
else if (trans)
|
||||
ret = btrfs_end_transaction(trans);
|
||||
|
||||
/*
|
||||
* At this point we either failed at allocating prealloc, or we
|
||||
* succeeded and passed the ownership to it to add_qgroup_rb(). In any
|
||||
* case, this needs to be NULL or there is something wrong.
|
||||
*/
|
||||
ASSERT(prealloc == NULL);
|
||||
|
||||
kfree(prealloc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1682,12 +1675,7 @@ int btrfs_create_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid)
|
|||
ret = btrfs_sysfs_add_one_qgroup(fs_info, qgroup);
|
||||
out:
|
||||
mutex_unlock(&fs_info->qgroup_ioctl_lock);
|
||||
/*
|
||||
* At this point we either failed at allocating prealloc, or we
|
||||
* succeeded and passed the ownership to it to add_qgroup_rb(). In any
|
||||
* case, this needs to be NULL or there is something wrong.
|
||||
*/
|
||||
ASSERT(prealloc == NULL);
|
||||
kfree(prealloc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -3279,7 +3267,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
|
|||
struct btrfs_root *quota_root;
|
||||
struct btrfs_qgroup *srcgroup;
|
||||
struct btrfs_qgroup *dstgroup;
|
||||
struct btrfs_qgroup *prealloc = NULL;
|
||||
struct btrfs_qgroup *prealloc;
|
||||
struct btrfs_qgroup_list **qlist_prealloc = NULL;
|
||||
bool free_inherit = false;
|
||||
bool need_rescan = false;
|
||||
|
|
@ -3520,14 +3508,7 @@ out:
|
|||
}
|
||||
if (free_inherit)
|
||||
kfree(inherit);
|
||||
|
||||
/*
|
||||
* At this point we either failed at allocating prealloc, or we
|
||||
* succeeded and passed the ownership to it to add_qgroup_rb(). In any
|
||||
* case, this needs to be NULL or there is something wrong.
|
||||
*/
|
||||
ASSERT(prealloc == NULL);
|
||||
|
||||
kfree(prealloc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -187,7 +187,6 @@ static int remove_extent_ref(struct btrfs_root *root, u64 bytenr,
|
|||
ret = btrfs_search_slot(&trans, root, &key, path, -1, 1);
|
||||
if (ret) {
|
||||
test_err("couldn't find backref %d", ret);
|
||||
btrfs_free_path(path);
|
||||
return ret;
|
||||
}
|
||||
btrfs_del_item(&trans, root, path);
|
||||
|
|
|
|||
|
|
@ -5865,14 +5865,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
|
|||
struct btrfs_inode *curr_inode = start_inode;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* If we are logging a new name, as part of a link or rename operation,
|
||||
* don't bother logging new dentries, as we just want to log the names
|
||||
* of an inode and that any new parents exist.
|
||||
*/
|
||||
if (ctx->logging_new_name)
|
||||
return 0;
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
|
|
@ -6051,6 +6043,33 @@ static int conflicting_inode_is_dir(struct btrfs_root *root, u64 ino,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool can_log_conflicting_inode(const struct btrfs_trans_handle *trans,
|
||||
const struct btrfs_inode *inode)
|
||||
{
|
||||
if (!S_ISDIR(inode->vfs_inode.i_mode))
|
||||
return true;
|
||||
|
||||
if (inode->last_unlink_trans < trans->transid)
|
||||
return true;
|
||||
|
||||
/*
|
||||
* If this is a directory and its unlink_trans is not from a past
|
||||
* transaction then we must fallback to a transaction commit in order
|
||||
* to avoid getting a directory with 2 hard links after log replay.
|
||||
*
|
||||
* This happens if a directory A is renamed, moved from one parent
|
||||
* directory to another one, a new file is created in the old parent
|
||||
* directory with the old name of our directory A, the new file is
|
||||
* fsynced, then we moved the new file to some other parent directory
|
||||
* and fsync again the new file. This results in a log tree where we
|
||||
* logged that directory A existed, with the INODE_REF item for the
|
||||
* new location but without having logged its old parent inode, so
|
||||
* that on log replay we add a new link for the new location but the
|
||||
* old link remains, resulting in a link count of 2.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
static int add_conflicting_inode(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_path *path,
|
||||
|
|
@ -6154,6 +6173,11 @@ static int add_conflicting_inode(struct btrfs_trans_handle *trans,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!can_log_conflicting_inode(trans, inode)) {
|
||||
btrfs_add_delayed_iput(inode);
|
||||
return BTRFS_LOG_FORCE_COMMIT;
|
||||
}
|
||||
|
||||
btrfs_add_delayed_iput(inode);
|
||||
|
||||
ino_elem = kmalloc(sizeof(*ino_elem), GFP_NOFS);
|
||||
|
|
@ -6218,6 +6242,12 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
|
|||
break;
|
||||
}
|
||||
|
||||
if (!can_log_conflicting_inode(trans, inode)) {
|
||||
btrfs_add_delayed_iput(inode);
|
||||
ret = BTRFS_LOG_FORCE_COMMIT;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Always log the directory, we cannot make this
|
||||
* conditional on need_log_inode() because the directory
|
||||
|
|
|
|||
|
|
@ -7128,6 +7128,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_fs_info *fs_info,
|
|||
|
||||
fs_devices->seeding = true;
|
||||
fs_devices->opened = 1;
|
||||
list_add(&fs_devices->seed_list, &fs_info->fs_devices->seed_list);
|
||||
return fs_devices;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue