diff options
author | Filipe Manana <fdmanana@suse.com> | 2024-06-11 11:44:33 +0100 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2024-07-11 15:33:24 +0200 |
commit | 45c4102f0d827e00ce6ca107a7cb158265d706da (patch) | |
tree | 71fc8feb80a0722af9a719ad43f92d647921812f /fs/btrfs/ioctl.c | |
parent | ebc7c7678eb04b739544d9caaa0a4797adb24392 (diff) | |
download | lwn-45c4102f0d827e00ce6ca107a7cb158265d706da.tar.gz lwn-45c4102f0d827e00ce6ca107a7cb158265d706da.zip |
btrfs: avoid transaction commit on any fsync after subvolume creation
As of commit 1b53e51a4a8f ("btrfs: don't commit transaction for every
subvol create") we started to make any fsync after creating a subvolume
to fallback to a transaction commit if the fsync is performed in the
same transaction that was used to create the subvolume. This happens
with the following at ioctl.c:create_subvol():
$ cat fs/btrfs/ioctl.c
(...)
/* Tree log can't currently deal with an inode which is a new root. */
btrfs_set_log_full_commit(trans);
(...)
Note that the comment is misleading as the problem is not that fsync can
not deal with the root inode of a new root, but that we can not log any
inode that belongs to a root that was not yet persisted because that would
make log replay fail since the root doesn't exist at log replay time.
The above simply makes any fsync fallback to a full transaction commit if
it happens in the same transaction used to create the subvolume - even if
it's an inode that belongs to any other subvolume. This is a brute force
solution and it doesn't necessarily improve performance for every workload
out there - it just moves a full transaction commit from one place, the
subvolume creation, to another - an fsync for any inode.
Just improve on this by making the fallback to a transaction commit only
for an fsync against an inode of the new subvolume, or for the directory
that contains the dentry that points to the new subvolume (in case anyone
attempts to fsync the directory in the same transaction).
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index d00d49338ecb..1dca986943f0 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -662,8 +662,6 @@ static noinline int create_subvol(struct mnt_idmap *idmap, qgroup_reserved = 0; trans->block_rsv = &block_rsv; trans->bytes_reserved = block_rsv.size; - /* Tree log can't currently deal with an inode which is a new root. */ - btrfs_set_log_full_commit(trans); ret = btrfs_qgroup_inherit(trans, 0, objectid, btrfs_root_id(root), inherit); if (ret) @@ -764,6 +762,8 @@ static noinline int create_subvol(struct mnt_idmap *idmap, goto out; } + btrfs_record_new_subvolume(trans, BTRFS_I(dir)); + d_instantiate_new(dentry, new_inode_args.inode); new_inode_args.inode = NULL; |