| // SPDX-License-Identifier: GPL-2.0 |
| |
| #include "messages.h" |
| #include "ctree.h" |
| #include "fs.h" |
| #include "accessors.h" |
| |
| void __btrfs_set_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag, |
| const char *name) |
| { |
| struct btrfs_super_block *disk_super; |
| u64 features; |
| |
| disk_super = fs_info->super_copy; |
| features = btrfs_super_incompat_flags(disk_super); |
| if (!(features & flag)) { |
| spin_lock(&fs_info->super_lock); |
| features = btrfs_super_incompat_flags(disk_super); |
| if (!(features & flag)) { |
| features |= flag; |
| btrfs_set_super_incompat_flags(disk_super, features); |
| btrfs_info(fs_info, |
| "setting incompat feature flag for %s (0x%llx)", |
| name, flag); |
| } |
| spin_unlock(&fs_info->super_lock); |
| set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags); |
| } |
| } |
| |
| void __btrfs_clear_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag, |
| const char *name) |
| { |
| struct btrfs_super_block *disk_super; |
| u64 features; |
| |
| disk_super = fs_info->super_copy; |
| features = btrfs_super_incompat_flags(disk_super); |
| if (features & flag) { |
| spin_lock(&fs_info->super_lock); |
| features = btrfs_super_incompat_flags(disk_super); |
| if (features & flag) { |
| features &= ~flag; |
| btrfs_set_super_incompat_flags(disk_super, features); |
| btrfs_info(fs_info, |
| "clearing incompat feature flag for %s (0x%llx)", |
| name, flag); |
| } |
| spin_unlock(&fs_info->super_lock); |
| set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags); |
| } |
| } |
| |
| void __btrfs_set_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag, |
| const char *name) |
| { |
| struct btrfs_super_block *disk_super; |
| u64 features; |
| |
| disk_super = fs_info->super_copy; |
| features = btrfs_super_compat_ro_flags(disk_super); |
| if (!(features & flag)) { |
| spin_lock(&fs_info->super_lock); |
| features = btrfs_super_compat_ro_flags(disk_super); |
| if (!(features & flag)) { |
| features |= flag; |
| btrfs_set_super_compat_ro_flags(disk_super, features); |
| btrfs_info(fs_info, |
| "setting compat-ro feature flag for %s (0x%llx)", |
| name, flag); |
| } |
| spin_unlock(&fs_info->super_lock); |
| set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags); |
| } |
| } |
| |
| void __btrfs_clear_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag, |
| const char *name) |
| { |
| struct btrfs_super_block *disk_super; |
| u64 features; |
| |
| disk_super = fs_info->super_copy; |
| features = btrfs_super_compat_ro_flags(disk_super); |
| if (features & flag) { |
| spin_lock(&fs_info->super_lock); |
| features = btrfs_super_compat_ro_flags(disk_super); |
| if (features & flag) { |
| features &= ~flag; |
| btrfs_set_super_compat_ro_flags(disk_super, features); |
| btrfs_info(fs_info, |
| "clearing compat-ro feature flag for %s (0x%llx)", |
| name, flag); |
| } |
| spin_unlock(&fs_info->super_lock); |
| set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags); |
| } |
| } |