summaryrefslogtreecommitdiff
path: root/fs/btrfs/sysfs.c
diff options
context:
space:
mode:
authorQu Wenruo <wqu@suse.com>2026-08-25 13:42:31 +0930
committerDavid Sterba <dsterba@suse.com>2026-09-14 13:23:36 +0200
commitf5e60e8d7080d29739a4f056d5dbc28eafd4578e (patch)
tree5ede7e9e5dea4e711b3e2a88868cf690c1b75b70 /fs/btrfs/sysfs.c
parent90bb57315c3949bebc0d793f25949b1391970ae4 (diff)
downloadlinux-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.c8
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);
}