diff mbox series

[1/2] btrfs: convert to spinlock guards in btrfs_update_ioctl_balance_args()

Message ID 20250409125724.145597-1-frank.li@vivo.com (mailing list archive)
State New
Headers show
Series [1/2] btrfs: convert to spinlock guards in btrfs_update_ioctl_balance_args() | expand

Commit Message

李扬韬 April 9, 2025, 12:57 p.m. UTC
To simplify handling, use the guard helper to let the compiler care for
unlocking.

Signed-off-by: Yangtao Li <frank.li@vivo.com>
---
 fs/btrfs/ioctl.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

Comments

David Sterba April 9, 2025, 6:30 p.m. UTC | #1
On Wed, Apr 09, 2025 at 06:57:22AM -0600, Yangtao Li wrote:
> To simplify handling, use the guard helper to let the compiler care for
> unlocking.
> 
> Signed-off-by: Yangtao Li <frank.li@vivo.com>
> ---
>  fs/btrfs/ioctl.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
> index 63aeacc54945..7cec105a4cb0 100644
> --- a/fs/btrfs/ioctl.c
> +++ b/fs/btrfs/ioctl.c
> @@ -3438,9 +3438,8 @@ void btrfs_update_ioctl_balance_args(struct btrfs_fs_info *fs_info,
>  	memcpy(&bargs->meta, &bctl->meta, sizeof(bargs->meta));
>  	memcpy(&bargs->sys, &bctl->sys, sizeof(bargs->sys));
>  
> -	spin_lock(&fs_info->balance_lock);
> +	guard(spinlock)(&fs_info->balance_lock);

Please don't do the guard() conversions in fs/btrfs/, the explicit
locking is the preferred style. If other subsystems use the scoped
locking guards then let them do it.

I personally hate it as it totally disrupts the perception of visibly
demarcated critical sections. I don't see the benefit comparing saved
lines of code vs clear and understandable code.

We rarely have a clear case for the guards, I found a few where it
could be used but then this means we have 2 styles of locking, yet
another code pattern to learn.
李扬韬 April 10, 2025, 11:11 a.m. UTC | #2
> Please don't do the guard() conversions in fs/btrfs/, the explicit locking is the preferred style. If other subsystems use the scoped locking guards then let them do it.

OK, is there anything we can do quickly in the btrfs code currently?

Thx,
Yangtao
David Sterba April 15, 2025, 5:53 p.m. UTC | #3
On Thu, Apr 10, 2025 at 11:11:11AM +0000, 李扬韬 wrote:
> > Please don't do the guard() conversions in fs/btrfs/, the explicit locking is the preferred style. If other subsystems use the scoped locking guards then let them do it.
> 
> OK, is there anything we can do quickly in the btrfs code currently?

Yeah, there always is. The open coded rb_tree searches can be converted
to the rb_find() helpers. It ends up as the same asm code due to
inlining and reads a bit better when there's just one rb_find instead of
the while loop and left/right tree moves.

I have some WIP for that but I havent't tested it at all, but it should
give a good idea:

--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -160,23 +160,27 @@ qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
 		   int init_flags);
 static void qgroup_rescan_zero_tracking(struct btrfs_fs_info *fs_info);
 
+static int qgroup_qgroupid_cmp(const void *key, const struct rb_node *node)
+{
+	const u64 *qgroupid = key;
+	const struct btrfs_qgroup *qgroup = rb_entry(n, struct btrfs_qgroup, node);
+
+	if (qgroup->qgroupid < qgroupid)
+		return -1;
+	else if (qgroup->qgroupid > qgroupid)
+		return 1;
+	return 0;
+}
+
 /* must be called with qgroup_ioctl_lock held */
 static struct btrfs_qgroup *find_qgroup_rb(const struct btrfs_fs_info *fs_info,
 					   u64 qgroupid)
 {
-	struct rb_node *n = fs_info->qgroup_tree.rb_node;
-	struct btrfs_qgroup *qgroup;
+	struct rb_node *node;
 
-	while (n) {
-		qgroup = rb_entry(n, struct btrfs_qgroup, node);
-		if (qgroup->qgroupid < qgroupid)
-			n = n->rb_left;
-		else if (qgroup->qgroupid > qgroupid)
-			n = n->rb_right;
-		else
-			return qgroup;
-	}
-	return NULL;
+	node = rb_find(&qgroupid, fs_info->qgroup_tree, qgroup_qgroupid_cmp);
+
+	return rb_entry_safe(n, struct btrfs_qgroup, node);
 }
 
 /*
---

So basically:
- add a comparator function
- replace the while loop with rb_find
- make sure it is equivalent and test it

There are easy conversions like __btrfs_lookup_delayed_item(),
potentially convertible too but with a comparator that takes an extra
parameter like prelim_ref_compare() or compare_inode_defrag(). There are
many more that do some additional things like remembering the last
parent pointer and for that the rb-tree API is not convenient so you can
skip that and do the straigtforward cases first.

If you decide not to take it then it's also fine, it's a cleanup and the
code will work as-is.
diff mbox series

Patch

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 63aeacc54945..7cec105a4cb0 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3438,9 +3438,8 @@  void btrfs_update_ioctl_balance_args(struct btrfs_fs_info *fs_info,
 	memcpy(&bargs->meta, &bctl->meta, sizeof(bargs->meta));
 	memcpy(&bargs->sys, &bctl->sys, sizeof(bargs->sys));
 
-	spin_lock(&fs_info->balance_lock);
+	guard(spinlock)(&fs_info->balance_lock);
 	memcpy(&bargs->stat, &bctl->stat, sizeof(bargs->stat));
-	spin_unlock(&fs_info->balance_lock);
 }
 
 /*