summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index d4e105b54091..93b01fe6c731 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -56,6 +56,7 @@
#include "rcu-string.h"
#include "send.h"
#include "dev-replace.h"
+#include "sysfs.h"
static int btrfs_clone(struct inode *src, struct inode *inode,
u64 off, u64 olen, u64 olen_aligned, u64 destoff);
@@ -4516,17 +4517,27 @@ static int btrfs_ioctl_get_features(struct file *file, void __user *arg)
return 0;
}
-static int check_feature_bits(struct btrfs_root *root, const char *type,
+static int check_feature_bits(struct btrfs_root *root,
+ enum btrfs_feature_set set,
u64 change_mask, u64 flags, u64 supported_flags,
u64 safe_set, u64 safe_clear)
{
+ const char *type = btrfs_feature_set_names[set];
+ char *names;
u64 disallowed, unsupported;
u64 set_mask = flags & change_mask;
u64 clear_mask = ~flags & change_mask;
unsupported = set_mask & ~supported_flags;
if (unsupported) {
- btrfs_warn(root->fs_info,
+ names = btrfs_printable_features(set, unsupported);
+ if (names) {
+ btrfs_warn(root->fs_info,
+ "this kernel does not support the %s feature bit%s",
+ names, strchr(names, ',') ? "s" : "");
+ kfree(names);
+ } else
+ btrfs_warn(root->fs_info,
"this kernel does not support %s bits 0x%llx",
type, unsupported);
return -EOPNOTSUPP;
@@ -4534,7 +4545,14 @@ static int check_feature_bits(struct btrfs_root *root, const char *type,
disallowed = set_mask & ~safe_set;
if (disallowed) {
- btrfs_warn(root->fs_info,
+ names = btrfs_printable_features(set, disallowed);
+ if (names) {
+ btrfs_warn(root->fs_info,
+ "can't set the %s feature bit%s while mounted",
+ names, strchr(names, ',') ? "s" : "");
+ kfree(names);
+ } else
+ btrfs_warn(root->fs_info,
"can't set %s bits 0x%llx while mounted",
type, disallowed);
return -EPERM;
@@ -4542,7 +4560,14 @@ static int check_feature_bits(struct btrfs_root *root, const char *type,
disallowed = clear_mask & ~safe_clear;
if (disallowed) {
- btrfs_warn(root->fs_info,
+ names = btrfs_printable_features(set, disallowed);
+ if (names) {
+ btrfs_warn(root->fs_info,
+ "can't clear the %s feature bit%s while mounted",
+ names, strchr(names, ',') ? "s" : "");
+ kfree(names);
+ } else
+ btrfs_warn(root->fs_info,
"can't clear %s bits 0x%llx while mounted",
type, disallowed);
return -EPERM;
@@ -4552,7 +4577,7 @@ static int check_feature_bits(struct btrfs_root *root, const char *type,
}
#define check_feature(root, change_mask, flags, mask_base) \
-check_feature_bits(root, # mask_base, change_mask, flags, \
+check_feature_bits(root, FEAT_##mask_base, change_mask, flags, \
BTRFS_FEATURE_ ## mask_base ## _SUPP, \
BTRFS_FEATURE_ ## mask_base ## _SAFE_SET, \
BTRFS_FEATURE_ ## mask_base ## _SAFE_CLEAR)