1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/crc32.h> 4 #include "messages.h" 5 #include "fs.h" 6 #include "accessors.h" 7 #include "volumes.h" 8 9 static const struct btrfs_csums { 10 u16 size; 11 const char name[10]; 12 } btrfs_csums[] = { 13 [BTRFS_CSUM_TYPE_CRC32] = { .size = 4, .name = "crc32c" }, 14 [BTRFS_CSUM_TYPE_XXHASH] = { .size = 8, .name = "xxhash64" }, 15 [BTRFS_CSUM_TYPE_SHA256] = { .size = 32, .name = "sha256" }, 16 [BTRFS_CSUM_TYPE_BLAKE2] = { .size = 32, .name = "blake2b" }, 17 }; 18 19 /* This exists for btrfs-progs usages. */ 20 u16 btrfs_csum_type_size(u16 type) 21 { 22 return btrfs_csums[type].size; 23 } 24 25 int btrfs_super_csum_size(const struct btrfs_super_block *s) 26 { 27 u16 t = btrfs_super_csum_type(s); 28 29 /* csum type is validated at mount time. */ 30 return btrfs_csum_type_size(t); 31 } 32 33 const char *btrfs_super_csum_name(u16 csum_type) 34 { 35 /* csum type is validated at mount time. */ 36 return btrfs_csums[csum_type].name; 37 } 38 39 size_t __attribute_const__ btrfs_get_num_csums(void) 40 { 41 return ARRAY_SIZE(btrfs_csums); 42 } 43 44 void btrfs_csum(u16 csum_type, const u8 *data, size_t len, u8 *out) 45 { 46 switch (csum_type) { 47 case BTRFS_CSUM_TYPE_CRC32: 48 put_unaligned_le32(~crc32c(~0, data, len), out); 49 break; 50 case BTRFS_CSUM_TYPE_XXHASH: 51 put_unaligned_le64(xxh64(data, len, 0), out); 52 break; 53 case BTRFS_CSUM_TYPE_SHA256: 54 sha256(data, len, out); 55 break; 56 case BTRFS_CSUM_TYPE_BLAKE2: 57 blake2b(NULL, 0, data, len, out, 32); 58 break; 59 default: 60 /* Checksum type is validated at mount time. */ 61 BUG(); 62 } 63 } 64 65 void btrfs_csum_init(struct btrfs_csum_ctx *ctx, u16 csum_type) 66 { 67 ctx->csum_type = csum_type; 68 switch (ctx->csum_type) { 69 case BTRFS_CSUM_TYPE_CRC32: 70 ctx->crc32 = ~0; 71 break; 72 case BTRFS_CSUM_TYPE_XXHASH: 73 xxh64_reset(&ctx->xxh64, 0); 74 break; 75 case BTRFS_CSUM_TYPE_SHA256: 76 sha256_init(&ctx->sha256); 77 break; 78 case BTRFS_CSUM_TYPE_BLAKE2: 79 blake2b_init(&ctx->blake2b, 32); 80 break; 81 default: 82 /* Checksume type is validated at mount time. */ 83 BUG(); 84 } 85 } 86 87 void btrfs_csum_update(struct btrfs_csum_ctx *ctx, const u8 *data, size_t len) 88 { 89 switch (ctx->csum_type) { 90 case BTRFS_CSUM_TYPE_CRC32: 91 ctx->crc32 = crc32c(ctx->crc32, data, len); 92 break; 93 case BTRFS_CSUM_TYPE_XXHASH: 94 xxh64_update(&ctx->xxh64, data, len); 95 break; 96 case BTRFS_CSUM_TYPE_SHA256: 97 sha256_update(&ctx->sha256, data, len); 98 break; 99 case BTRFS_CSUM_TYPE_BLAKE2: 100 blake2b_update(&ctx->blake2b, data, len); 101 break; 102 default: 103 /* Checksum type is validated at mount time. */ 104 BUG(); 105 } 106 } 107 108 void btrfs_csum_final(struct btrfs_csum_ctx *ctx, u8 *out) 109 { 110 switch (ctx->csum_type) { 111 case BTRFS_CSUM_TYPE_CRC32: 112 put_unaligned_le32(~ctx->crc32, out); 113 break; 114 case BTRFS_CSUM_TYPE_XXHASH: 115 put_unaligned_le64(xxh64_digest(&ctx->xxh64), out); 116 break; 117 case BTRFS_CSUM_TYPE_SHA256: 118 sha256_final(&ctx->sha256, out); 119 break; 120 case BTRFS_CSUM_TYPE_BLAKE2: 121 blake2b_final(&ctx->blake2b, out); 122 break; 123 default: 124 /* Checksum type is validated at mount time. */ 125 BUG(); 126 } 127 } 128 129 /* 130 * For regular builds, any block size <= page size is supported. 131 * For experimental builds, any block size between BTRFS_MIN_BLOCKSIZE 132 * and BTRFS_MAX_BLOCKSIZE (inclusive) is supported. 133 */ 134 bool __attribute_const__ btrfs_supported_blocksize(u32 blocksize) 135 { 136 /* @blocksize should be validated first. */ 137 ASSERT(is_power_of_2(blocksize) && blocksize >= BTRFS_MIN_BLOCKSIZE && 138 blocksize <= BTRFS_MAX_BLOCKSIZE); 139 140 if (blocksize <= PAGE_SIZE) 141 return true; 142 #ifdef CONFIG_BTRFS_EXPERIMENTAL 143 /* 144 * For bs > ps support it's done by specifying a minimal folio order 145 * for filemap, thus implying large data folios. 146 * For HIGHMEM systems, we can not always access the content of a (large) 147 * folio in one go, but go through them page by page. 148 * 149 * A lot of features don't implement a proper PAGE sized loop for large 150 * folios, this includes: 151 * 152 * - compression 153 * - verity 154 * - encoded write 155 * 156 * Considering HIGHMEM is such a pain to deal with and it's going 157 * to be deprecated eventually, just reject HIGHMEM && bs > ps cases. 158 * 159 * Finally, for bs > ps cases, we need to set the minimal folio order, 160 * which requires transparent hugepage. 161 */ 162 if (blocksize > PAGE_SIZE) { 163 if (IS_ENABLED(CONFIG_HIGHMEM)) 164 return false; 165 166 if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) 167 return false; 168 } 169 return true; 170 #endif 171 return false; 172 } 173 174 /* 175 * Start exclusive operation @type, return true on success. 176 */ 177 bool btrfs_exclop_start(struct btrfs_fs_info *fs_info, 178 enum btrfs_exclusive_operation type) 179 { 180 bool ret = false; 181 182 spin_lock(&fs_info->super_lock); 183 if (fs_info->exclusive_operation == BTRFS_EXCLOP_NONE) { 184 fs_info->exclusive_operation = type; 185 ret = true; 186 } 187 spin_unlock(&fs_info->super_lock); 188 189 return ret; 190 } 191 192 /* 193 * Conditionally allow to enter the exclusive operation in case it's compatible 194 * with the running one. This must be paired with btrfs_exclop_start_unlock() 195 * and btrfs_exclop_finish(). 196 * 197 * Compatibility: 198 * - the same type is already running 199 * - when trying to add a device and balance has been paused 200 * - not BTRFS_EXCLOP_NONE - this is intentionally incompatible and the caller 201 * must check the condition first that would allow none -> @type 202 */ 203 bool btrfs_exclop_start_try_lock(struct btrfs_fs_info *fs_info, 204 enum btrfs_exclusive_operation type) 205 { 206 spin_lock(&fs_info->super_lock); 207 if (fs_info->exclusive_operation == type || 208 (fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE_PAUSED && 209 type == BTRFS_EXCLOP_DEV_ADD)) 210 return true; 211 212 spin_unlock(&fs_info->super_lock); 213 return false; 214 } 215 216 void btrfs_exclop_start_unlock(struct btrfs_fs_info *fs_info) 217 { 218 spin_unlock(&fs_info->super_lock); 219 } 220 221 void btrfs_exclop_finish(struct btrfs_fs_info *fs_info) 222 { 223 spin_lock(&fs_info->super_lock); 224 WRITE_ONCE(fs_info->exclusive_operation, BTRFS_EXCLOP_NONE); 225 spin_unlock(&fs_info->super_lock); 226 sysfs_notify(&fs_info->fs_devices->fsid_kobj, NULL, "exclusive_operation"); 227 } 228 229 void btrfs_exclop_balance(struct btrfs_fs_info *fs_info, 230 enum btrfs_exclusive_operation op) 231 { 232 switch (op) { 233 case BTRFS_EXCLOP_BALANCE_PAUSED: 234 spin_lock(&fs_info->super_lock); 235 ASSERT(fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE || 236 fs_info->exclusive_operation == BTRFS_EXCLOP_DEV_ADD || 237 fs_info->exclusive_operation == BTRFS_EXCLOP_NONE || 238 fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE_PAUSED); 239 fs_info->exclusive_operation = BTRFS_EXCLOP_BALANCE_PAUSED; 240 spin_unlock(&fs_info->super_lock); 241 break; 242 case BTRFS_EXCLOP_BALANCE: 243 spin_lock(&fs_info->super_lock); 244 ASSERT(fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE_PAUSED); 245 fs_info->exclusive_operation = BTRFS_EXCLOP_BALANCE; 246 spin_unlock(&fs_info->super_lock); 247 break; 248 default: 249 btrfs_warn(fs_info, 250 "invalid exclop balance operation %d requested", op); 251 } 252 } 253 254 void __btrfs_set_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag, 255 const char *name) 256 { 257 struct btrfs_super_block *disk_super; 258 u64 features; 259 260 disk_super = fs_info->super_copy; 261 features = btrfs_super_incompat_flags(disk_super); 262 if (!(features & flag)) { 263 spin_lock(&fs_info->super_lock); 264 features = btrfs_super_incompat_flags(disk_super); 265 if (!(features & flag)) { 266 features |= flag; 267 btrfs_set_super_incompat_flags(disk_super, features); 268 btrfs_info(fs_info, 269 "setting incompat feature flag for %s (0x%llx)", 270 name, flag); 271 } 272 spin_unlock(&fs_info->super_lock); 273 set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags); 274 } 275 } 276 277 void __btrfs_clear_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag, 278 const char *name) 279 { 280 struct btrfs_super_block *disk_super; 281 u64 features; 282 283 disk_super = fs_info->super_copy; 284 features = btrfs_super_incompat_flags(disk_super); 285 if (features & flag) { 286 spin_lock(&fs_info->super_lock); 287 features = btrfs_super_incompat_flags(disk_super); 288 if (features & flag) { 289 features &= ~flag; 290 btrfs_set_super_incompat_flags(disk_super, features); 291 btrfs_info(fs_info, 292 "clearing incompat feature flag for %s (0x%llx)", 293 name, flag); 294 } 295 spin_unlock(&fs_info->super_lock); 296 set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags); 297 } 298 } 299 300 void __btrfs_set_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag, 301 const char *name) 302 { 303 struct btrfs_super_block *disk_super; 304 u64 features; 305 306 disk_super = fs_info->super_copy; 307 features = btrfs_super_compat_ro_flags(disk_super); 308 if (!(features & flag)) { 309 spin_lock(&fs_info->super_lock); 310 features = btrfs_super_compat_ro_flags(disk_super); 311 if (!(features & flag)) { 312 features |= flag; 313 btrfs_set_super_compat_ro_flags(disk_super, features); 314 btrfs_info(fs_info, 315 "setting compat-ro feature flag for %s (0x%llx)", 316 name, flag); 317 } 318 spin_unlock(&fs_info->super_lock); 319 set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags); 320 } 321 } 322 323 void __btrfs_clear_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag, 324 const char *name) 325 { 326 struct btrfs_super_block *disk_super; 327 u64 features; 328 329 disk_super = fs_info->super_copy; 330 features = btrfs_super_compat_ro_flags(disk_super); 331 if (features & flag) { 332 spin_lock(&fs_info->super_lock); 333 features = btrfs_super_compat_ro_flags(disk_super); 334 if (features & flag) { 335 features &= ~flag; 336 btrfs_set_super_compat_ro_flags(disk_super, features); 337 btrfs_info(fs_info, 338 "clearing compat-ro feature flag for %s (0x%llx)", 339 name, flag); 340 } 341 spin_unlock(&fs_info->super_lock); 342 set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags); 343 } 344 } 345