1// SPDX-License-Identifier: GPL-2.0
2
3#include "messages.h"
4#include "ctree.h"
5#include "fs.h"
6#include "accessors.h"
7
8void __btrfs_set_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag,
9			     const char *name)
10{
11	struct btrfs_super_block *disk_super;
12	u64 features;
13
14	disk_super = fs_info->super_copy;
15	features = btrfs_super_incompat_flags(disk_super);
16	if (!(features & flag)) {
17		spin_lock(&fs_info->super_lock);
18		features = btrfs_super_incompat_flags(disk_super);
19		if (!(features & flag)) {
20			features |= flag;
21			btrfs_set_super_incompat_flags(disk_super, features);
22			btrfs_info(fs_info,
23				"setting incompat feature flag for %s (0x%llx)",
24				name, flag);
25		}
26		spin_unlock(&fs_info->super_lock);
27		set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags);
28	}
29}
30
31void __btrfs_clear_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag,
32			       const char *name)
33{
34	struct btrfs_super_block *disk_super;
35	u64 features;
36
37	disk_super = fs_info->super_copy;
38	features = btrfs_super_incompat_flags(disk_super);
39	if (features & flag) {
40		spin_lock(&fs_info->super_lock);
41		features = btrfs_super_incompat_flags(disk_super);
42		if (features & flag) {
43			features &= ~flag;
44			btrfs_set_super_incompat_flags(disk_super, features);
45			btrfs_info(fs_info,
46				"clearing incompat feature flag for %s (0x%llx)",
47				name, flag);
48		}
49		spin_unlock(&fs_info->super_lock);
50		set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags);
51	}
52}
53
54void __btrfs_set_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag,
55			      const char *name)
56{
57	struct btrfs_super_block *disk_super;
58	u64 features;
59
60	disk_super = fs_info->super_copy;
61	features = btrfs_super_compat_ro_flags(disk_super);
62	if (!(features & flag)) {
63		spin_lock(&fs_info->super_lock);
64		features = btrfs_super_compat_ro_flags(disk_super);
65		if (!(features & flag)) {
66			features |= flag;
67			btrfs_set_super_compat_ro_flags(disk_super, features);
68			btrfs_info(fs_info,
69				"setting compat-ro feature flag for %s (0x%llx)",
70				name, flag);
71		}
72		spin_unlock(&fs_info->super_lock);
73		set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags);
74	}
75}
76
77void __btrfs_clear_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag,
78				const char *name)
79{
80	struct btrfs_super_block *disk_super;
81	u64 features;
82
83	disk_super = fs_info->super_copy;
84	features = btrfs_super_compat_ro_flags(disk_super);
85	if (features & flag) {
86		spin_lock(&fs_info->super_lock);
87		features = btrfs_super_compat_ro_flags(disk_super);
88		if (features & flag) {
89			features &= ~flag;
90			btrfs_set_super_compat_ro_flags(disk_super, features);
91			btrfs_info(fs_info,
92				"clearing compat-ro feature flag for %s (0x%llx)",
93				name, flag);
94		}
95		spin_unlock(&fs_info->super_lock);
96		set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags);
97	}
98}
99