Btrfs: get/set label of a mounted file system
v8 cover Btrfs: get/set label of a mounted file system
Hello,
Here is the updated version of introduce get/set_or_change label upon a mounted filesystem.
v8->v7:btrfs_ioc_fs_getlabel():
- Examine the label length with strnlen().
- Tweak up warn() info if the label is not NUL terminated according to Goffredo's suggestions.
The old versions can be found at:
v7:
http://www.spinics.net/lists/linux-btrfs/msg20994.html
v6:
http://www.spinics.net/lists/linux-btrfs/msg20922.html
v5:
http://www.spinics.net/lists/linux-btrfs/msg20888.html
v4:
http://permalink.gmane.org/gmane.comp.file-systems.btrfs/21618
v3:
https://patchwork.kernel.org/patch/1124642/
v2:
http://permalink.gmane.org/gmane.comp.file-systems.btrfs/12877
v1:
http://permalink.gmane.org/gmane.comp.file-systems.btrfs/12872
Thanks,
-Jeff
RFC PATCH v8 1/2 Btrfs: Add a new ioctl to get the label of a mounted file system
Add a new ioctl(2) BTRFS_IOC_GET_FSLABLE, so that we can get the label upon a mounted file system.
--- fs/btrfs/ioctl.c | 22 ++++++++++++++++++++++ fs/btrfs/ioctl.h | 2 ++ 2 files changed, 24 insertions(+)
fs/btrfs/ioctl.c +22 -0
@@ -3699,6 +3699,26 @@ out:return ret; } +static int btrfs_ioctl_get_fslabel (struct file *file,void __user *arg) +{ +struct btrfs_root *root =BTRFS_I (fdentry (file)->d_inode)->root; +const char *label = root->fs_info->super_copy->label; +size_t len =strnlen (label,BTRFS_LABEL_SIZE ); +int ret; + +if (len ==BTRFS_LABEL_SIZE ) { + len--; +WARN (1 ,"btrfs: device label is not zero terminated, " +"it will be truncated to %zu bytes.\n" , len); + } + +mutex_lock (&root->fs_info->volume_mutex); + ret =copy_to_user (arg, label, len); +mutex_unlock (&root->fs_info->volume_mutex); + +return ret ? -EFAULT :0 ; +} +long btrfs_ioctl (struct file *file,unsigned int cmd,unsigned long arg) {
@@ -3797,6 +3817,8 @@ long btrfs_ioctl(struct file *file, unsigned intreturn btrfs_ioctl_qgroup_create (root, argp);case BTRFS_IOC_QGROUP_LIMIT :return btrfs_ioctl_qgroup_limit (root, argp); +case BTRFS_IOC_GET_FSLABEL : +return btrfs_ioctl_get_fslabel (file, argp); }return -ENOTTY ;
fs/btrfs/ioctl.h +2 -0
@@ -451,6 +451,8 @@ struct btrfs_ioctl_send_args { struct btrfs_ioctl_qgroup_create_args)#define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, \ struct btrfs_ioctl_qgroup_limit_args) +#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \ + char[BTRFS_LABEL_SIZE])#define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \ struct btrfs_ioctl_get_dev_stats)#endif
Signature · 1 line
1.7.9.5
Re: [RFC PATCH v8 1/2] Btrfs: Add a new ioctl to get the label of a mounted file system
fs/btrfs/ioctl.c out: · line 3712
Quoted 11 lines · Jeff Liu
fs/btrfs/ioctl.c +11
-0+static int btrfs_ioctl_get_fslabel (struct file *file,void __user *arg) +{ +struct btrfs_root *root =BTRFS_I (fdentry (file)->d_inode)->root; +const char *label = root->fs_info->super_copy->label; +size_t len =strnlen (label,BTRFS_LABEL_SIZE ); +int ret; + +if (len ==BTRFS_LABEL_SIZE ) { + len--; +WARN (1 ,"btrfs: device label is not zero terminated, " +"it will be truncated to %zu bytes.\n" , len);
This will print a stacktrace, it's not needed in this context, the warning is enough.
printk(KERN_WARNING "...");
Quoted 8 lines
fs/btrfs/ioctl.c +8
-0+ } + +mutex_lock (&root->fs_info->volume_mutex); + ret =copy_to_user (arg, label, len); +mutex_unlock (&root->fs_info->volume_mutex); + +return ret ? -EFAULT :0 ; +}
RFC PATCH v8 2/2 Btrfs: Add a new ioctl to set/change the label of a mounted file system
In reply to Jeff LiuWith this new ioctl(2) BTRFS_IOC_SET_FSLABEL, we can set/change the label of a mounted file system.
--- fs/btrfs/ioctl.c | 39 +++++++++++++++++++++++++++++++++++++++ fs/btrfs/ioctl.h | 2 ++ 2 files changed, 41 insertions(+)
fs/btrfs/ioctl.c +39 -0
@@ -3719,6 +3719,43 @@ static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg)return ret ? -EFAULT :0 ; } +static int btrfs_ioctl_set_fslabel (struct file *file,void __user *arg) +{ +struct btrfs_root *root =BTRFS_I (fdentry (file)->d_inode)->root; +struct btrfs_super_block *super_block = root->fs_info->super_copy; +struct btrfs_trans_handle *trans; +char label[BTRFS_LABEL_SIZE ]; +int ret; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; + +if (copy_from_user (label, arg,sizeof (label))) +return -EFAULT ; + +if (strnlen (label,BTRFS_LABEL_SIZE ) ==BTRFS_LABEL_SIZE ) +return -EINVAL ; + + ret =mnt_want_write_file (file); +if (ret) +return ret; + +mutex_lock (&root->fs_info->volume_mutex); + trans =btrfs_start_transaction (root,1 ); +if (IS_ERR (trans)) { + ret =PTR_ERR (trans); + goto out_unlock; + } + +strcpy (super_block->label, label); + ret =btrfs_end_transaction (trans, root); + +out_unlock: +mutex_unlock (&root->fs_info->volume_mutex); +mnt_drop_write_file (file); +return ret; +} +long btrfs_ioctl (struct file *file,unsigned int cmd,unsigned long arg) {
@@ -3819,6 +3856,8 @@ long btrfs_ioctl(struct file *file, unsigned intreturn btrfs_ioctl_qgroup_limit (root, argp);case BTRFS_IOC_GET_FSLABEL :return btrfs_ioctl_get_fslabel (file, argp); +case BTRFS_IOC_SET_FSLABEL : +return btrfs_ioctl_set_fslabel (file, argp); }return -ENOTTY ;
fs/btrfs/ioctl.h +2 -0
@@ -453,6 +453,8 @@ struct btrfs_ioctl_send_args { struct btrfs_ioctl_qgroup_limit_args)#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \ char[BTRFS_LABEL_SIZE]) +#define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 50, \ + char[BTRFS_LABEL_SIZE])#define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \ struct btrfs_ioctl_get_dev_stats)#endif
Signature · 1 line
1.7.9.5
Re: [RFC PATCH v8 2/2] Btrfs: Add a new ioctl to set/change the label of a mounted file system
Quoted 5 lines · Jeff Liu
fs/btrfs/ioctl.c +5
-0+static int btrfs_ioctl_set_fslabel (struct file *file,void __user *arg) +{ +struct btrfs_root *root =BTRFS_I (fdentry (file)->d_inode)->root; +struct btrfs_super_block *super_block = root->fs_info->super_copy; +struct btrfs_trans_handle *trans;
fs/btrfs/ioctl.c static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) · line 3736
Quoted 10 lines
fs/btrfs/ioctl.c +10
-0+char label[BTRFS_LABEL_SIZE ]; +int ret; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; + +if (copy_from_user (label, arg,sizeof (label))) +return -EFAULT ; + +if (strnlen (label,BTRFS_LABEL_SIZE ) ==BTRFS_LABEL_SIZE )
I would expect a message if this happens, similar to the 'get_fslabel' one, otherwise it's difficult to find out the reason.
fs/btrfs/ioctl.c static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) · line 3744
Quoted 8 lines
fs/btrfs/ioctl.c +8
-0+return -EINVAL ; + + ret =mnt_want_write_file (file); +if (ret) +return ret; + +mutex_lock (&root->fs_info->volume_mutex); + trans =btrfs_start_transaction (root,1 );
Do we need to reserve 1 unit here? This does not touch any non-superblock metadata, modifies superblock in place. This could lead to an ENOSPC (changing label on a full fs), altghouh it need not happen.
Quoted 13 lines
fs/btrfs/ioctl.c +13
-0+if (IS_ERR (trans)) { + ret =PTR_ERR (trans); + goto out_unlock; + } + +strcpy (super_block->label, label); + ret =btrfs_end_transaction (trans, root); + +out_unlock: +mutex_unlock (&root->fs_info->volume_mutex); +mnt_drop_write_file (file); +return ret; +}
Re: [RFC PATCH v8 2/2] Btrfs: Add a new ioctl to set/change the label of a mounted file system
Quoted 11 lines · David Sterba
Quoted 10 lines · Jeff Liu
fs/btrfs/ioctl.c +10
-0+static int btrfs_ioctl_set_fslabel (struct file *file,void __user *arg) +{ +struct btrfs_root *root =BTRFS_I (fdentry (file)->d_inode)->root; +struct btrfs_super_block *super_block = root->fs_info->super_copy; +struct btrfs_trans_handle *trans; +char label[BTRFS_LABEL_SIZE ]; +int ret; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ;
Quoted 8 lines
fs/btrfs/ioctl.c static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) · line 3736
Quoted 5 lines
fs/btrfs/ioctl.c +5
-0+ +if (copy_from_user (label, arg,sizeof (label))) +return -EFAULT ; + +if (strnlen (label,BTRFS_LABEL_SIZE ) ==BTRFS_LABEL_SIZE )I would expect a message if this happens, similar to the '
get_fslabel' one, otherwise it's difficult to find out the reason.
That's sounds make sense.
Quoted 13 lines
fs/btrfs/ioctl.c static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) · line 3744
Quoted 9 lines
fs/btrfs/ioctl.c +8
-0+return -EINVAL ; + + ret =mnt_want_write_file (file); +if (ret) +return ret; + +mutex_lock (&root->fs_info->volume_mutex); + trans =btrfs_start_transaction (root,1 );Do we need to reserve 1 unit here? This does not touch any non-superblock metadata, modifies superblock in place. This could lead to an ENOSPC (changing label on a full fs), altghouh it need not happen.
Don't need, I can not recalled why I did that before, will fix it.
Thanks,
-Jeff
Quoted 14 lines
Quoted 14 lines
fs/btrfs/ioctl.c +13
-0+if (IS_ERR (trans)) { + ret =PTR_ERR (trans); + goto out_unlock; + } + +strcpy (super_block->label, label); + ret =btrfs_end_transaction (trans, root); + +out_unlock: +mutex_unlock (&root->fs_info->volume_mutex); +mnt_drop_write_file (file); +return ret; +}