From: David Sterba <dsterba@suse.cz>
To: David Sterba <dsterba@suse.cz>
Cc: Mark Harmstone <maharmstone@fb.com>, linux-btrfs@vger.kernel.org
Subject: Re: [PATCH v2] btrfs: use atomic64_t for free_objectid
Date: Wed, 5 Mar 2025 11:33:39 +0100 [thread overview]
Message-ID: <20250305103339.GD5777@twin.jikos.cz> (raw)
In-Reply-To: <20250304095256.GX5777@twin.jikos.cz>
On Tue, Mar 04, 2025 at 10:52:56AM +0100, David Sterba wrote:
> > - 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.
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 075a06db43a1..2620403fd4c9 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,9 @@ struct btrfs_root {
u64 last_trans;
+ /* Locking is done only when incremented, read size relies on u64. */
u64 free_objectid;
+ spinlock_t objectid_lock;
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 0cb559448933..e5569cec0547 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -676,7 +676,7 @@ 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);
+ spin_lock_init(&root->objectid_lock);
mutex_init(&root->log_mutex);
mutex_init(&root->ordered_extent_mutex);
mutex_init(&root->delalloc_mutex);
@@ -1132,17 +1132,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);
-
return 0;
}
@@ -2725,8 +2720,8 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
}
/*
- * No need to hold btrfs_root::objectid_mutex since the fs
- * hasn't been fully initialised and we are the only user
+ * No need to lock btrfs_root::free_objectid since the fs
+ * hasn't been fully initialised and we are the only user.
*/
ret = btrfs_init_root_free_objectid(tree_root);
if (ret < 0) {
@@ -4930,20 +4925,21 @@ int btrfs_init_root_free_objectid(struct btrfs_root *root)
int btrfs_get_free_objectid(struct btrfs_root *root, u64 *objectid)
{
- int ret;
- mutex_lock(&root->objectid_mutex);
+ u64 val;
- if (unlikely(root->free_objectid >= BTRFS_LAST_FREE_OBJECTID)) {
+ spin_lock(&root->objectid_lock);
+ val = root->free_objectid;
+ if (unlikely(val >= BTRFS_LAST_FREE_OBJECTID)) {
+ spin_unlock(&root->objectid_lock);
btrfs_warn(root->fs_info,
"the objectid of root %llu reaches its highest value",
btrfs_root_id(root));
- ret = -ENOSPC;
- goto out;
+ return -ENOSPC;
}
+ root->free_objectid = val + 1;
+ spin_unlock(&root->objectid_lock);
- *objectid = root->free_objectid++;
- ret = 0;
-out:
- mutex_unlock(&root->objectid_mutex);
- return ret;
+ *objectid = val;
+
+ return 0;
}
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index d6fa36674270..1ce84bf59a09 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -472,9 +472,9 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
*
* Ensure that we skip any such subvol ids.
*
- * We don't need to lock because this is only called
- * during mount before we start doing things like creating
- * subvolumes.
+ * We don't need to worry about updates to free_objectid,
+ * this is only called during mount before we start
+ * doing things like creating subvolumes.
*/
if (is_fstree(qgroup->qgroupid) &&
qgroup->qgroupid > tree_root->free_objectid)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index fc5c761181eb..97e608b251fa 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -7325,9 +7325,6 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
* We have just replayed everything, and the highest
* objectid of fs roots probably has changed in case
* some inode_item's got replayed.
- *
- * root->objectid_mutex is not acquired as log replay
- * could only happen during mount.
*/
ret = btrfs_init_root_free_objectid(root);
if (ret)
--
2.47.1
prev parent reply other threads:[~2025-03-05 10:33 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
2025-03-05 10:33 ` David Sterba [this message]
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=20250305103339.GD5777@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