From: David Sterba <dsterba@suse.cz>
To: Mark Harmstone <maharmstone@fb.com>
Cc: linux-btrfs@vger.kernel.org
Subject: Re: [PATCH v2] btrfs: use atomic64_t for free_objectid
Date: Tue, 4 Mar 2025 10:52:56 +0100 [thread overview]
Message-ID: <20250304095256.GX5777@twin.jikos.cz> (raw)
In-Reply-To: <20250303182139.256498-1-maharmstone@fb.com>
On Mon, Mar 03, 2025 at 06:21:16PM +0000, Mark Harmstone wrote:
> Currently btrfs_get_free_objectid() uses a mutex to protect
> free_objectid; I'm guessing this was because of the inode cache that we
> used to have. The inode cache is no more, so simplify things by
> replacing it with an atomic.
>
> There's no issues with ordering: free_objectid gets set to an initial
> value, then calls to btrfs_get_free_objectid() return a monotonically
> increasing value.
>
> This change means that btrfs_get_free_objectid() will no longer
> potentially sleep, which was a blocker for adding a non-blocking mode
> for inode and subvol creation.
>
> This change moves the warning in btrfs_get_free_objectid() out of the lock.
> Integer overflow isn't a plausible problem here; there's no way to create
> inodes with an arbitrary number, short of hex-editing the block device,
> and incrementing a uint64_t a billion times a second would take >500 years
> for overflow to happen.
>
> Signed-off-by: Mark Harmstone <maharmstone@fb.com>
> ---
> fs/btrfs/ctree.h | 4 +---
> fs/btrfs/disk-io.c | 43 ++++++++++++++++++-------------------------
> fs/btrfs/qgroup.c | 11 ++++++-----
> fs/btrfs/tree-log.c | 3 ---
> 4 files changed, 25 insertions(+), 36 deletions(-)
>
> diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
> index 075a06db43a1..23adbce4c516 100644
> --- a/fs/btrfs/ctree.h
> +++ b/fs/btrfs/ctree.h
> @@ -179,8 +179,6 @@ struct btrfs_root {
> struct btrfs_fs_info *fs_info;
> struct extent_io_tree dirty_log_pages;
>
> - struct mutex objectid_mutex;
> -
> spinlock_t accounting_lock;
> struct btrfs_block_rsv *block_rsv;
>
> @@ -214,7 +212,7 @@ struct btrfs_root {
>
> u64 last_trans;
>
> - u64 free_objectid;
> + atomic64_t free_objectid;
>
> struct btrfs_key defrag_progress;
> struct btrfs_key defrag_max;
> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
> index 52c2335ef62f..1597a8945f4c 100644
> --- a/fs/btrfs/disk-io.c
> +++ b/fs/btrfs/disk-io.c
> @@ -657,7 +657,7 @@ static void __setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info,
> RB_CLEAR_NODE(&root->rb_node);
>
> btrfs_set_root_last_trans(root, 0);
> - root->free_objectid = 0;
> + atomic64_set(&root->free_objectid, 0);
> root->nr_delalloc_inodes = 0;
> root->nr_ordered_extents = 0;
> xa_init(&root->inodes);
> @@ -676,7 +676,6 @@ static void __setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info,
> spin_lock_init(&root->ordered_extent_lock);
> spin_lock_init(&root->accounting_lock);
> spin_lock_init(&root->qgroup_meta_rsv_lock);
> - mutex_init(&root->objectid_mutex);
> mutex_init(&root->log_mutex);
> mutex_init(&root->ordered_extent_mutex);
> mutex_init(&root->delalloc_mutex);
> @@ -1132,16 +1131,12 @@ static int btrfs_init_fs_root(struct btrfs_root *root, dev_t anon_dev)
> }
> }
>
> - mutex_lock(&root->objectid_mutex);
> ret = btrfs_init_root_free_objectid(root);
> - if (ret) {
> - mutex_unlock(&root->objectid_mutex);
> + if (ret)
> return ret;
> - }
>
> - ASSERT(root->free_objectid <= BTRFS_LAST_FREE_OBJECTID);
> -
> - mutex_unlock(&root->objectid_mutex);
> + ASSERT((u64)atomic64_read(&root->free_objectid) <=
> + BTRFS_LAST_FREE_OBJECTID);
I'm not sure if this was mentioned in the previous discussion. This
assert will be always true, the atomic is signed 64 and cast to
unsigned. Under normal circumstances the atomic will not be negative so
it won't translate to a huge unsigned number by the cast.
What we need is an unsigned atomic type. The atomic64_t is a natural
choice and it probably has enough margin for the simple increment
allocation. But still I think we should make it a "u64".
The simplest implementation is to use spin lock around the updates,
seqlock_t is also possible but it effectively uses a spin lock too and
we don't need the read side protection.
Sorry, it's another change right before the code freeze so we may want
to postpone it to let us think it through. I'll prototype the idea and
do some tests, we can still target 6.15.
next prev parent reply other threads:[~2025-03-04 9:53 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-03 18:21 [PATCH v2] btrfs: use atomic64_t for free_objectid Mark Harmstone
2025-03-04 9:52 ` David Sterba [this message]
2025-03-05 10:33 ` David Sterba
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250304095256.GX5777@twin.jikos.cz \
--to=dsterba@suse.cz \
--cc=linux-btrfs@vger.kernel.org \
--cc=maharmstone@fb.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox