1 // SPDX-License-Identifier: GPL-2.0
9 static const struct btrfs_csums {
12 const char driver[12];
14 [BTRFS_CSUM_TYPE_CRC32] = { .size = 4, .name = "crc32c" },
15 [BTRFS_CSUM_TYPE_XXHASH] = { .size = 8, .name = "xxhash64" },
16 [BTRFS_CSUM_TYPE_SHA256] = { .size = 32, .name = "sha256" },
17 [BTRFS_CSUM_TYPE_BLAKE2] = { .size = 32, .name = "blake2b",
18 .driver = "blake2b-256" },
21 /* This exists for btrfs-progs usages. */
22 u16 btrfs_csum_type_size(u16 type)
24 return btrfs_csums[type].size;
27 int btrfs_super_csum_size(const struct btrfs_super_block *s)
29 u16 t = btrfs_super_csum_type(s);
31 /* csum type is validated at mount time. */
32 return btrfs_csum_type_size(t);
35 const char *btrfs_super_csum_name(u16 csum_type)
37 /* csum type is validated at mount time. */
38 return btrfs_csums[csum_type].name;
42 * Return driver name if defined, otherwise the name that's also a valid driver
45 const char *btrfs_super_csum_driver(u16 csum_type)
47 /* csum type is validated at mount time */
48 return btrfs_csums[csum_type].driver[0] ?
49 btrfs_csums[csum_type].driver :
50 btrfs_csums[csum_type].name;
53 size_t __attribute_const__ btrfs_get_num_csums(void)
55 return ARRAY_SIZE(btrfs_csums);
59 * Start exclusive operation @type, return true on success.
61 bool btrfs_exclop_start(struct btrfs_fs_info *fs_info,
62 enum btrfs_exclusive_operation type)
66 spin_lock(&fs_info->super_lock);
67 if (fs_info->exclusive_operation == BTRFS_EXCLOP_NONE) {
68 fs_info->exclusive_operation = type;
71 spin_unlock(&fs_info->super_lock);
77 * Conditionally allow to enter the exclusive operation in case it's compatible
78 * with the running one. This must be paired with btrfs_exclop_start_unlock()
79 * and btrfs_exclop_finish().
82 * - the same type is already running
83 * - when trying to add a device and balance has been paused
84 * - not BTRFS_EXCLOP_NONE - this is intentionally incompatible and the caller
85 * must check the condition first that would allow none -> @type
87 bool btrfs_exclop_start_try_lock(struct btrfs_fs_info *fs_info,
88 enum btrfs_exclusive_operation type)
90 spin_lock(&fs_info->super_lock);
91 if (fs_info->exclusive_operation == type ||
92 (fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE_PAUSED &&
93 type == BTRFS_EXCLOP_DEV_ADD))
96 spin_unlock(&fs_info->super_lock);
100 void btrfs_exclop_start_unlock(struct btrfs_fs_info *fs_info)
102 spin_unlock(&fs_info->super_lock);
105 void btrfs_exclop_finish(struct btrfs_fs_info *fs_info)
107 spin_lock(&fs_info->super_lock);
108 WRITE_ONCE(fs_info->exclusive_operation, BTRFS_EXCLOP_NONE);
109 spin_unlock(&fs_info->super_lock);
110 sysfs_notify(&fs_info->fs_devices->fsid_kobj, NULL, "exclusive_operation");
113 void btrfs_exclop_balance(struct btrfs_fs_info *fs_info,
114 enum btrfs_exclusive_operation op)
117 case BTRFS_EXCLOP_BALANCE_PAUSED:
118 spin_lock(&fs_info->super_lock);
119 ASSERT(fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE ||
120 fs_info->exclusive_operation == BTRFS_EXCLOP_DEV_ADD ||
121 fs_info->exclusive_operation == BTRFS_EXCLOP_NONE ||
122 fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE_PAUSED);
123 fs_info->exclusive_operation = BTRFS_EXCLOP_BALANCE_PAUSED;
124 spin_unlock(&fs_info->super_lock);
126 case BTRFS_EXCLOP_BALANCE:
127 spin_lock(&fs_info->super_lock);
128 ASSERT(fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE_PAUSED);
129 fs_info->exclusive_operation = BTRFS_EXCLOP_BALANCE;
130 spin_unlock(&fs_info->super_lock);
134 "invalid exclop balance operation %d requested", op);
138 void __btrfs_set_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag,
141 struct btrfs_super_block *disk_super;
144 disk_super = fs_info->super_copy;
145 features = btrfs_super_incompat_flags(disk_super);
146 if (!(features & flag)) {
147 spin_lock(&fs_info->super_lock);
148 features = btrfs_super_incompat_flags(disk_super);
149 if (!(features & flag)) {
151 btrfs_set_super_incompat_flags(disk_super, features);
153 "setting incompat feature flag for %s (0x%llx)",
156 spin_unlock(&fs_info->super_lock);
157 set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags);
161 void __btrfs_clear_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag,
164 struct btrfs_super_block *disk_super;
167 disk_super = fs_info->super_copy;
168 features = btrfs_super_incompat_flags(disk_super);
169 if (features & flag) {
170 spin_lock(&fs_info->super_lock);
171 features = btrfs_super_incompat_flags(disk_super);
172 if (features & flag) {
174 btrfs_set_super_incompat_flags(disk_super, features);
176 "clearing incompat feature flag for %s (0x%llx)",
179 spin_unlock(&fs_info->super_lock);
180 set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags);
184 void __btrfs_set_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag,
187 struct btrfs_super_block *disk_super;
190 disk_super = fs_info->super_copy;
191 features = btrfs_super_compat_ro_flags(disk_super);
192 if (!(features & flag)) {
193 spin_lock(&fs_info->super_lock);
194 features = btrfs_super_compat_ro_flags(disk_super);
195 if (!(features & flag)) {
197 btrfs_set_super_compat_ro_flags(disk_super, features);
199 "setting compat-ro feature flag for %s (0x%llx)",
202 spin_unlock(&fs_info->super_lock);
203 set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags);
207 void __btrfs_clear_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag,
210 struct btrfs_super_block *disk_super;
213 disk_super = fs_info->super_copy;
214 features = btrfs_super_compat_ro_flags(disk_super);
215 if (features & flag) {
216 spin_lock(&fs_info->super_lock);
217 features = btrfs_super_compat_ro_flags(disk_super);
218 if (features & flag) {
220 btrfs_set_super_compat_ro_flags(disk_super, features);
222 "clearing compat-ro feature flag for %s (0x%llx)",
225 spin_unlock(&fs_info->super_lock);
226 set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags);