|  | // 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); | 
|  | } | 
|  | } |