btrfs: add ability to query/change feature bits online
PATCH 1/1 btrfs: add ability to query/change feature bits online
There are some feature bits that require no offline setup and can be enabled online. I've only reviewed extended irefs, but there will probably be more.
We introduce three new ioctls:
- BTRFS_IOC_GET_SUPPORTED_FEATURES: query the kernel for supported features
- BTRFS_IOC_GET_FEATURES: query the kernel for enabled features on a per-fs basis.
- BTRFS_IOC_ADD_FEATURES: enable new features on a per-fs basis.
We introduce a new mask _SAFE_ONLINE that allows us to define which features are safe to enable at runtime.
The failure modes for BTRFS_IOC_ADD_FEATURES are as follows:
- Enabling a completely unsupported feature: warns and returns -ENOTSUPP
- Enabling a feature that can only be done offline: warns and returns -EPERM
The structure passed in is not modified on return since it is possible to isolate which features would bounce a -EPERM by subtracting the features provided by a GET_SUPPORTED_FEATURES call.
--- fs/btrfs/ctree.h | 6 ++ fs/btrfs/ioctl.c | 127 +++++++++++++++++++++++++++++++++++++++++++++ include/uapi/linux/btrfs.h | 12 ++++ 3 files changed, 145 insertions(+)
fs/btrfs/ctree.h +6 -0
@@ -512,7 +512,10 @@ struct btrfs_super_block {#define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL << 8)#define BTRFS_FEATURE_COMPAT_SUPP 0ULL +#define BTRFS_FEATURE_COMPAT_ONLINE_SAFE 0ULL#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL +#define BTRFS_FEATURE_COMPAT_RO_ONLINE_SAFE 0ULL +#define BTRFS_FEATURE_INCOMPAT_SUPP \ (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \ BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL | \
@@ -523,6 +526,9 @@ struct btrfs_super_block { BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF | \ BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA) +#define BTRFS_FEATURE_INCOMPAT_ONLINE_SAFE \ + (BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF) +/* * A leaf is full of items. offset and size tell us where to find * the item in the leaf (relative to the start of the data area)
fs/btrfs/ioctl.c +127 -0
139 lines not on this page · raw message
include/uapi/linux/btrfs.h +12 -0
@@ -184,6 +184,12 @@ struct btrfs_ioctl_fs_info_args {__u64 reserved[124 ];/* pad to 1k */ }; +struct btrfs_ioctl_feature_flags { +__u64 compat_flags; +__u64 compat_ro_flags; +__u64 incompat_flags; +}; +/* balance control ioctl modes */ #define BTRFS_BALANCE_CTL_PAUSE 1#define BTRFS_BALANCE_CTL_CANCEL 2
@@ -579,4 +585,10 @@ static inline char *btrfs_err_str(enum b struct btrfs_ioctl_get_dev_stats)#define BTRFS_IOC_DEV_REPLACE _IOWR(BTRFS_IOCTL_MAGIC, 53, \ struct btrfs_ioctl_dev_replace_args) +#define BTRFS_IOC_GET_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 54, \ + struct btrfs_ioctl_feature_flags) +#define BTRFS_IOC_ADD_FEATURES _IOW(BTRFS_IOCTL_MAGIC, 55, \ + struct btrfs_ioctl_feature_flags) +#define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 56, \ + struct btrfs_ioctl_feature_flags[2])#endif /* _UAPI_LINUX_BTRFS_H */
Signature · 2 lines
Jeff Mahoney SUSE Labs
Quoted 22 lines · Jeff Mahoney
There are some feature bits that require no offline setup and can be enabled online. I've only reviewed extended irefs, but there will probably be more.
We introduce three new ioctls:
-BTRFS_IOC_GET_SUPPORTED_FEATURES: query the kernel for supported features
-BTRFS_IOC_GET_FEATURES: query the kernel for enabled features on a per-fs basis.
-BTRFS_IOC_ADD_FEATURES: enable new features on a per-fs basis.We introduce a new mask
_SAFE_ONLINEthat allows us to define which features are safe to enable at runtime.The failure modes for
BTRFS_IOC_ADD_FEATURESare as follows:
- Enabling a completely unsupported feature: warns and returns-ENOTSUPP
- Enabling a feature that can only be done offline: warns and returns-EPERMThe structure passed in is not modified on return since it is possible to isolate which features would bounce a
-EPERMby subtracting the features provided by aGET_SUPPORTED_FEATUREScall.Signed-off-by Jeff Mahoney <[email protected]>
[...]
Quoted 16 lines
include/uapi/linux/btrfs.h +6
-0@@ -184,6 +184,12 @@ struct btrfs_ioctl_fs_info_args {__u64 reserved[124 ];/* pad to 1k */ }; +struct btrfs_ioctl_feature_flags { +__u64 compat_flags; +__u64 compat_ro_flags; +__u64 incompat_flags; +}; +/* balance control ioctl modes */ #define BTRFS_BALANCE_CTL_PAUSE 1#define BTRFS_BALANCE_CTL_CANCEL 2
include/uapi/linux/btrfs.h static inline char *btrfs_err_str(enum b · line 591
Quoted 7 lines
include/uapi/linux/btrfs.h +4
-0@@ -579,4 +585,10 @@ static inline char *btrfs_err_str(enum b struct btrfs_ioctl_get_dev_stats)#define BTRFS_IOC_DEV_REPLACE _IOWR(BTRFS_IOCTL_MAGIC, 53, \ struct btrfs_ioctl_dev_replace_args) +#define BTRFS_IOC_GET_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 54, \ + struct btrfs_ioctl_feature_flags) +#define BTRFS_IOC_ADD_FEATURES _IOW(BTRFS_IOCTL_MAGIC, 55, \ + struct btrfs_ioctl_feature_flags)
#define BTRFS_IOC_ADD_FEATURES _IOW(BTRFS_IOCTL_MAGIC, 54, \
struct btrfs_ioctl_feature_flags)
Using 54 for both would also be possible since the directions are different. _IOR(54) for the get ioctl and _IOW(54) for the set/add ioctl.
include/uapi/linux/btrfs.h static inline char *btrfs_err_str(enum b · line 593
Quoted 2 lines
include/uapi/linux/btrfs.h +2
-0+#define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 56, \ + struct btrfs_ioctl_feature_flags[2])
This could share the type value 54 too, since the parameter size is different. There are only 8 bits for the type field.
And in order to support clearing feature bits you could replace the add ioctl with a set ioctl and use a mask + value scheme.
#define BTRFS_IOC_SET_FEATURES _IOW(BTRFS_IOCTL_MAGIC, 54, \
struct btrfs_ioctl_feature_flags[2])
btrfs_ioctl_feature_flags[0] is the mask and btrfs_ioctl_feature_flags[1] is the value. Only bits that are set to one in the mask are taken from the value and modified in the filesystem flags.
Quoted 55 lines · Stefan Behrens
Quoted 22 lines · Jeff Mahoney
There are some feature bits that require no offline setup and can be enabled online. I've only reviewed extended irefs, but there will probably be more.
We introduce three new ioctls:
-BTRFS_IOC_GET_SUPPORTED_FEATURES: query the kernel for supported features
-BTRFS_IOC_GET_FEATURES: query the kernel for enabled features on a per-fs basis.
-BTRFS_IOC_ADD_FEATURES: enable new features on a per-fs basis.We introduce a new mask
_SAFE_ONLINEthat allows us to define which features are safe to enable at runtime.The failure modes for
BTRFS_IOC_ADD_FEATURESare as follows:
- Enabling a completely unsupported feature: warns and returns-ENOTSUPP
- Enabling a feature that can only be done offline: warns and returns-EPERMThe structure passed in is not modified on return since it is possible to isolate which features would bounce a
-EPERMby subtracting the features provided by aGET_SUPPORTED_FEATUREScall.Signed-off-by Jeff Mahoney <[email protected]>[...]
Quoted 16 lines
include/uapi/linux/btrfs.h +6
-0@@ -184,6 +184,12 @@ struct btrfs_ioctl_fs_info_args {__u64 reserved[124 ];/* pad to 1k */ }; +struct btrfs_ioctl_feature_flags { +__u64 compat_flags; +__u64 compat_ro_flags; +__u64 incompat_flags; +}; +/* balance control ioctl modes */ #define BTRFS_BALANCE_CTL_PAUSE 1#define BTRFS_BALANCE_CTL_CANCEL 2include/uapi/linux/btrfs.h static inline char *btrfs_err_str(enum b · line 591
Quoted 7 lines
include/uapi/linux/btrfs.h +4
-0@@ -579,4 +585,10 @@ static inline char *btrfs_err_str(enum b struct btrfs_ioctl_get_dev_stats)#define BTRFS_IOC_DEV_REPLACE _IOWR(BTRFS_IOCTL_MAGIC, 53, \ struct btrfs_ioctl_dev_replace_args) +#define BTRFS_IOC_GET_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 54, \ + struct btrfs_ioctl_feature_flags) +#define BTRFS_IOC_ADD_FEATURES _IOW(BTRFS_IOCTL_MAGIC, 55, \ + struct btrfs_ioctl_feature_flags)#define
BTRFS_IOC_ADD_FEATURES_IOW(BTRFS_IOCTL_MAGIC, 54, \
structbtrfs_ioctl_feature_flags)Using 54 for both would also be possible since the directions are different.
_IOR(54)for the get ioctl and_IOW(54)for the set/add ioctl.
Quoted 5 lines
include/uapi/linux/btrfs.h static inline char *btrfs_err_str(enum b · line 593
Quoted 2 lines
include/uapi/linux/btrfs.h +2
-0+#define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 56, \ + struct btrfs_ioctl_feature_flags[2])This could share the type value 54 too, since the parameter size is different. There are only 8 bits for the type field.
Ah, yep. You're right.
Quoted 7 lines
And in order to support clearing feature bits you could replace the add ioctl with a set ioctl and use a mask + value scheme.
#defineBTRFS_IOC_SET_FEATURES_IOW(BTRFS_IOCTL_MAGIC, 54, \
struct btrfs_ioctl_feature_flags[2])
btrfs_ioctl_feature_flags[0] is the mask and btrfs_ioctl_feature_flags[1] is the value. Only bits that are set to one in the mask are taken from the value and modified in the filesystem flags.
Yep. Though for now I think I'd implement the clear as an EOPNOTSUPP.
-Jeff
Signature · 2 lines
Jeff Mahoney SUSE Labs
Quoted 2 lines · Jeff Mahoney
fs/btrfs/ioctl.c +2
-0+static int btrfs_ioctl_add_features (struct file *file,void __user *arg) +{
...
spin_lock(&fs_info->super_lock);
fs/btrfs/ioctl.c out_unlock: · line 4215
Quoted 11 lines
fs/btrfs/ioctl.c +11
-0+ flags =btrfs_super_compat_flags (super_block); + flags |= features.compat_flags; +btrfs_set_super_compat_flags (super_block, flags); + + flags =btrfs_super_compat_ro_flags (super_block); + flags |= features.compat_ro_flags; +btrfs_set_super_compat_ro_flags (super_block, flags); + + flags =btrfs_super_incompat_flags (super_block); + flags |= features.incompat_flags; +btrfs_set_super_incompat_flags (super_block, flags);
spin_unlock(&fs_info->super_lock);
Quoted 5 lines
fs/btrfs/ioctl.c +5
-0+return btrfs_end_transaction (trans, root); + } + +return 0 ; +}