xref: /linux/fs/btrfs/fs.c (revision 58bb5081cba130f12c26d8e4d5e9416a0272f07e)
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  
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  
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  
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  
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