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 
__btrfs_set_fs_incompat(struct btrfs_fs_info * fs_info,u64 flag,const char * name)8 void __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 
__btrfs_clear_fs_incompat(struct btrfs_fs_info * fs_info,u64 flag,const char * name)31 void __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 
__btrfs_set_fs_compat_ro(struct btrfs_fs_info * fs_info,u64 flag,const char * name)54 void __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 
__btrfs_clear_fs_compat_ro(struct btrfs_fs_info * fs_info,u64 flag,const char * name)77 void __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