aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ioctl.c42
-rw-r--r--include/uapi/linux/btrfs.h2
2 files changed, 44 insertions, 0 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index fcc15a6804a9..0f68729f261e 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3936,6 +3936,46 @@ static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg)
3936 return ret ? -EFAULT : 0; 3936 return ret ? -EFAULT : 0;
3937} 3937}
3938 3938
3939static int btrfs_ioctl_set_fslabel(struct file *file, void __user *arg)
3940{
3941 struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root;
3942 struct btrfs_super_block *super_block = root->fs_info->super_copy;
3943 struct btrfs_trans_handle *trans;
3944 char label[BTRFS_LABEL_SIZE];
3945 int ret;
3946
3947 if (!capable(CAP_SYS_ADMIN))
3948 return -EPERM;
3949
3950 if (copy_from_user(label, arg, sizeof(label)))
3951 return -EFAULT;
3952
3953 if (strnlen(label, BTRFS_LABEL_SIZE) == BTRFS_LABEL_SIZE) {
3954 pr_err("btrfs: unable to set label with more than %d bytes\n",
3955 BTRFS_LABEL_SIZE - 1);
3956 return -EINVAL;
3957 }
3958
3959 ret = mnt_want_write_file(file);
3960 if (ret)
3961 return ret;
3962
3963 mutex_lock(&root->fs_info->volume_mutex);
3964 trans = btrfs_start_transaction(root, 0);
3965 if (IS_ERR(trans)) {
3966 ret = PTR_ERR(trans);
3967 goto out_unlock;
3968 }
3969
3970 strcpy(super_block->label, label);
3971 ret = btrfs_end_transaction(trans, root);
3972
3973out_unlock:
3974 mutex_unlock(&root->fs_info->volume_mutex);
3975 mnt_drop_write_file(file);
3976 return ret;
3977}
3978
3939long btrfs_ioctl(struct file *file, unsigned int 3979long btrfs_ioctl(struct file *file, unsigned int
3940 cmd, unsigned long arg) 3980 cmd, unsigned long arg)
3941{ 3981{
@@ -4038,6 +4078,8 @@ long btrfs_ioctl(struct file *file, unsigned int
4038 return btrfs_ioctl_dev_replace(root, argp); 4078 return btrfs_ioctl_dev_replace(root, argp);
4039 case BTRFS_IOC_GET_FSLABEL: 4079 case BTRFS_IOC_GET_FSLABEL:
4040 return btrfs_ioctl_get_fslabel(file, argp); 4080 return btrfs_ioctl_get_fslabel(file, argp);
4081 case BTRFS_IOC_SET_FSLABEL:
4082 return btrfs_ioctl_set_fslabel(file, argp);
4041 } 4083 }
4042 4084
4043 return -ENOTTY; 4085 return -ENOTTY;
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index 51c0b335e0c8..fa3a5f9338fc 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -504,6 +504,8 @@ struct btrfs_ioctl_send_args {
504 struct btrfs_ioctl_qgroup_limit_args) 504 struct btrfs_ioctl_qgroup_limit_args)
505#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \ 505#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \
506 char[BTRFS_LABEL_SIZE]) 506 char[BTRFS_LABEL_SIZE])
507#define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 50, \
508 char[BTRFS_LABEL_SIZE])
507#define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \ 509#define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \
508 struct btrfs_ioctl_get_dev_stats) 510 struct btrfs_ioctl_get_dev_stats)
509#define BTRFS_IOC_DEV_REPLACE _IOWR(BTRFS_IOCTL_MAGIC, 53, \ 511#define BTRFS_IOC_DEV_REPLACE _IOWR(BTRFS_IOCTL_MAGIC, 53, \