diff options
| author | Qu Wenruo <wqu@suse.com> | 2026-08-25 13:42:31 +0930 |
|---|---|---|
| committer | David Sterba <dsterba@suse.com> | 2026-09-14 13:23:36 +0200 |
| commit | f5e60e8d7080d29739a4f056d5dbc28eafd4578e (patch) | |
| tree | 5ede7e9e5dea4e711b3e2a88868cf690c1b75b70 /fs/btrfs/sysfs.c | |
| parent | 90bb57315c3949bebc0d793f25949b1391970ae4 (diff) | |
| download | linux-next-f5e60e8d7080d29739a4f056d5dbc28eafd4578e.tar.gz linux-next-f5e60e8d7080d29739a4f056d5dbc28eafd4578e.zip | |
btrfs: qgroup: use atomic operations for btrfs_fs_info::qgroup_flags
Currently we define btrfs_fs_info::qgroup_flags as u64, to match the
on-disk qgroup status item's flag.
But for now we have only 4 bits utilized for that flag, and since it's
u64 we have no way to properly use the existing atomic bit operations
(requires an unsigned long pointer).
This results in a lot of non-atomic operations inside qgroup code. Some
maybe fine as other locks are involved, but still it's not a good
practice.
Remove those non-atomic operations by:
- Re-define btrfs_fs_info::qgroup_flags as unsigned long
- Define BTRFS_QGROUP_STATUS_BIT_* and BTRFS_QGROUP_RUNTIME_BIT_*
Instead of the old value define the bit number.
- Use set_bit()/clear_bit()/test_bit() to replace open-coded bit
operations
- Add one extra check at qgroup status item read time
To make sure the on-disk flag is still inside ULONG_MAX.
Otherwise reject the status item and disable qgroup.
- Get rid of unnecessary spinlock when checking a single bit
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/sysfs.c')
| -rw-r--r-- | fs/btrfs/sysfs.c | 8 |
1 files changed, 2 insertions, 6 deletions
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index 39cb01ee441a..1df6340a7123 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -2359,9 +2359,7 @@ static ssize_t qgroup_enabled_show(struct kobject *qgroups_kobj, struct btrfs_fs_info *fs_info = to_fs_info(qgroups_kobj->parent); bool enabled; - spin_lock(&fs_info->qgroup_lock); - enabled = fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_ON; - spin_unlock(&fs_info->qgroup_lock); + enabled = test_bit(BTRFS_QGROUP_STATUS_BIT_ON, &fs_info->qgroup_flags); return sysfs_emit(buf, "%d\n", enabled); } @@ -2401,9 +2399,7 @@ static ssize_t qgroup_inconsistent_show(struct kobject *qgroups_kobj, struct btrfs_fs_info *fs_info = to_fs_info(qgroups_kobj->parent); bool inconsistent; - spin_lock(&fs_info->qgroup_lock); - inconsistent = (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT); - spin_unlock(&fs_info->qgroup_lock); + inconsistent = test_bit(BTRFS_QGROUP_STATUS_BIT_INCONSISTENT, &fs_info->qgroup_flags); return sysfs_emit(buf, "%d\n", inconsistent); } |
