Skip to contentSkip to conversation

Btrfs: get/set mounted filesystem label support

RFC PATCH In review Jeff Liu 2 participants 14 messages Dec 12, 2012 – Dec 17, 2012 Btrfs file system

lore
Share & tools
lore

Jeff Liu

author
#0 lore raw

v4 cover Btrfs: get/set mounted filesystem label support

Hello,

This is an improved tiny patch set to add get/set the label upon a mounted file system via ioctl(2).

I'd like to add the Signed-off-by with Anand for the credit since He has posted a similar patch set a few month ago.

Changes of V4->V3:
- Add a new ioctl to fetch the label of a mounted file system.
- Replace "struct btrfs_ioctl_fs_label_args" with "char label[BTRFS_LABEL_SIZE]".
- ioctl(2) number changed from 50 to 53/54. I'll update the btrfs wiki page with regard to the number allocation to reflect this change if it is ok.

The old versions can be found at:

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

author
#1 lore raw

PATCH v4 1/2 Btrfs: Add a new ioctl to get the label of a mounted filesystem

Introduce a new ioctl BTRFS_IOC_GET_FSLABEL, which would be used to fetch the label of a mounted filesystem.

---
 fs/btrfs/ioctl.c |   14 ++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 16 insertions(+)
fs/btrfs/ioctl.c +14 -0
index 8fcf9a5..b0a5e17 100644
@@ -3699,6 +3699,18 @@ out:
 	return ret;
 }
 
+static int btrfs_ioctl_get_fslabel(struct btrfs_root *root, void __user *arg)
+{
+	const char *label = root->fs_info->super_copy->label;
+	int ret;
+
+	mutex_lock(&root->fs_info->volume_mutex);
+	ret = copy_to_user(arg, label, strlen(label));
+	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 +3809,8 @@ long btrfs_ioctl(struct file *file, unsigned int
 		return 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(root, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +2 -0
index 731e287..98f896f 100644
@@ -453,4 +453,6 @@ struct btrfs_ioctl_send_args {
 			       struct btrfs_ioctl_qgroup_limit_args)
 #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \
 				      struct btrfs_ioctl_get_dev_stats)
+#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 53, \
+				   char[BTRFS_LABEL_SIZE])
 #endif
Signature · 1 line
1.7.9.5
author
#2 lore raw

PATCH RESEND v4 1/2 Btrfs: Add a new ioctl to get the label of a mounted filesystem

In reply to Jeff Liu
---
 fs/btrfs/ioctl.c |   14 ++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 16 insertions(+)
fs/btrfs/ioctl.c +14 -0
index 8fcf9a5..b0a5e17 100644
@@ -3699,6 +3699,18 @@ out:
 	return ret;
 }
 
+static int btrfs_ioctl_get_fslabel(struct btrfs_root *root, void __user *arg)
+{
+	const char *label = root->fs_info->super_copy->label;
+	int ret;
+
+	mutex_lock(&root->fs_info->volume_mutex);
+	ret = copy_to_user(arg, label, strlen(label));
+	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 +3809,8 @@ long btrfs_ioctl(struct file *file, unsigned int
 		return 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(root, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +2 -0
index 731e287..98f896f 100644
@@ -453,4 +453,6 @@ struct btrfs_ioctl_send_args {
 			       struct btrfs_ioctl_qgroup_limit_args)
 #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \
 				      struct btrfs_ioctl_get_dev_stats)
+#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 53, \
+				   char[BTRFS_LABEL_SIZE])
 #endif
Signature · 1 line
1.7.9.5
#3 lore raw

Re: [RESEND PATCH V4 1/2] Btrfs: Add a new ioctl to get the label of a mounted filesystem

Quoted 46 lines · Jeff Liu
---
 fs/btrfs/ioctl.c |   14 ++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 16 insertions(+)
fs/btrfs/ioctl.c +14 -0
index 8fcf9a5..b0a5e17 100644
@@ -3699,6 +3699,18 @@ out:
 	return ret;
 }
 
+static int btrfs_ioctl_get_fslabel(struct btrfs_root *root, void __user *arg)
+{
+	const char *label = root->fs_info->super_copy->label;
+	int ret;
+
+	mutex_lock(&root->fs_info->volume_mutex);
+	ret = copy_to_user(arg, label, strlen(label));
+	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 +3809,8 @@ long btrfs_ioctl(struct file *file, unsigned int
 		return 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(root, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +0 -0
index 731e287..98f896f 100644

fs/btrfs/ioctl.h struct btrfs_ioctl_send_args { · line 458

Quoted 6 lines
fs/btrfs/ioctl.h +2 -0
@@ -453,4 +453,6 @@ struct btrfs_ioctl_send_args {
 			       struct btrfs_ioctl_qgroup_limit_args)
 #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \
 				      struct btrfs_ioctl_get_dev_stats)
+#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 53, \
+				   char[BTRFS_LABEL_SIZE])
 #endif

According to the project idea web,
https://btrfs.wiki.kernel.org/index.php/Project_ideas#Development_notes.2C_please_read

number 53 has been used for the drive swapping commands, so I think we should choose another one. Maybe 49 is good since the above web says number 50 has been reserved for set/change label command.

author
#4 lore raw

Re: [RESEND PATCH V4 1/2] Btrfs: Add a new ioctl to get the label of a mounted filesystem

Quoted 57 lines · Miao Xie
Quoted 46 lines · Jeff Liu
---
 fs/btrfs/ioctl.c |   14 ++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 16 insertions(+)
fs/btrfs/ioctl.c +14 -0
index 8fcf9a5..b0a5e17 100644
@@ -3699,6 +3699,18 @@ out:
 	return ret;
 }
 
+static int btrfs_ioctl_get_fslabel(struct btrfs_root *root, void __user *arg)
+{
+	const char *label = root->fs_info->super_copy->label;
+	int ret;
+
+	mutex_lock(&root->fs_info->volume_mutex);
+	ret = copy_to_user(arg, label, strlen(label));
+	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 +3809,8 @@ long btrfs_ioctl(struct file *file, unsigned int
 		return 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(root, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +0 -0
index 731e287..98f896f 100644

fs/btrfs/ioctl.h struct btrfs_ioctl_send_args { · line 458

Quoted 6 lines
fs/btrfs/ioctl.h +2 -0
@@ -453,4 +453,6 @@ struct btrfs_ioctl_send_args {
 			       struct btrfs_ioctl_qgroup_limit_args)
 #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \
 				      struct btrfs_ioctl_get_dev_stats)
+#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 53, \
+				   char[BTRFS_LABEL_SIZE])
 #endif

According to the project idea web,
https://btrfs.wiki.kernel.org/index.php/Project_ideas#Development_notes.2C_please_read

Quoted 3 lines

number 53 has been used for the drive swapping commands, so I think we should choose another one. Maybe 49 is good since the above web says number 50 has been reserved for set/change label command.

Ok, let's waiting for others comments, I'll follow up the final confirmation.

Thanks,
-Jeff

Quoted 5 lines

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

author
#5 lore raw

PATCH v4 1/3 Btrfs-progs: get the label of a mounted filesystem

In reply to Jeff Liu

Get the label of a mounted filesystem through the new ioctl BTRFS_IOCTL_FS_GETLABEL.

---
 btrfslabel.c |   68 +++++++++++++++++++++++++++++++++++++---------------------
 ioctl.h      |    2 ++
 utils.c      |    2 +-
 utils.h      |    1 +
 4 files changed, 47 insertions(+), 26 deletions(-)
btrfslabel.c +43 -25
index cb142b0..761a312 100644
@@ -67,45 +67,63 @@ static void change_label_unmounted(char *dev, char *nLabel)
        close_ctree(root);
 }
 
-int get_label_unmounted(char *dev)
+static int get_label_unmounted(const char *dev)
 {
-       struct btrfs_root *root;
+	struct btrfs_root *root;
+	int ret;
 
-       /* Open the super_block at the default location
-        * and as read-only.
-        */
-       root = open_ctree(dev, 0, 0);
+	ret = check_mounted(dev);
+	if (ret < 0) {
+	       fprintf(stderr, "FATAL: error checking %s mount status\n", dev);
+	       return -1;
+	}
 
-       if(!root)
-         return -1;
+	/* Open the super_block at the default location
+	 * and as read-only.
+	 */
+	root = open_ctree(dev, 0, 0);
+	if(!root)
+		return -1;
 
-       fprintf(stdout, "%s\n", root->fs_info->super_copy.label);
+	fprintf(stdout, "%s\n", root->fs_info->super_copy.label);
 
-       /* Now we close it since we are done. */
-       close_ctree(root);
-       return 0;
+	/* Now we close it since we are done. */
+	close_ctree(root);
+	return 0;
 }
 
-int get_label(char *btrfs_dev)
+/*
+ * If a partition is mounted, try to get the filesystem label via its
+ * mounted path rather than device.  Return the corresponding error
+ * the user specified the device path.
+ */
+static int get_label_mounted(const char *mount_path)
 {
+	char label[BTRFS_LABEL_SIZE];
+	int fd;
 
-	int ret;
-	ret = check_mounted(btrfs_dev);
-	if (ret < 0)
-	{
-	       fprintf(stderr, "FATAL: error checking %s mount status\n", btrfs_dev);
-	       return -1;
+	fd = open(mount_path, O_RDONLY | O_NOATIME);
+	if (fd < 0) {
+		fprintf(stderr, "ERROR: unable access to '%s'\n", mount_path);
+		return -1;
 	}
 
-	if(ret != 0)
-	{
-	       fprintf(stderr, "FATAL: the filesystem has to be unmounted\n");
-	       return -2;
+	if (ioctl(fd, BTRFS_IOC_GET_FSLABEL, label) < 0) {
+		fprintf(stderr, "ERROR: unable get label %s\n", strerror(errno));
+		close(fd);
+		return -1;
 	}
-	ret = get_label_unmounted(btrfs_dev);
-	return ret;
+
+	fprintf(stdout, "%s\n", label);
+	return 0;
 }
 
+int get_label(const char *btrfs_dev)
+{
+	return is_existing_blk_or_reg_file(btrfs_dev) ?
+		get_label_unmounted(btrfs_dev) :
+		get_label_mounted(btrfs_dev);
+}
 
 int set_label(char *btrfs_dev, char *nLabel)
 {
ioctl.h +2 -0
index 6fda3a1..ed6784d 100644
@@ -432,4 +432,6 @@ struct btrfs_ioctl_clone_range_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, 53, \
+				   char[BTRFS_LABEL_SIZE])
 #endif
utils.c +1 -1
index 205e667..d59bca3 100644
@@ -811,7 +811,7 @@ int check_mounted(const char* file)
 		return -errno;
 	}
 
-	ret =  check_mounted_where(fd, file, NULL, 0, NULL);
+	ret = check_mounted_where(fd, file, NULL, 0, NULL);
 	close(fd);
 
 	return ret;
utils.h +1 -0
index 3a0368b..8750f28 100644
@@ -46,4 +46,5 @@ int check_label(char *input);
 int get_mountpt(char *dev, char *mntpt, size_t size);
 
 int btrfs_scan_block_devices(int run_ioctl);
+int is_existing_blk_or_reg_file(const char* filename);
 #endif
Signature · 1 line
1.7.9.5
author
#6 lore raw

PATCH v4 2/3 Btrfs-progs: change the label of a mounted filesystem

In reply to Jeff Liu

Change the label of a mounted file system through the new ioctl BTRFS_IOCTL_FS_SETLABEL.

---
 btrfslabel.c |   84 ++++++++++++++++++++++++++++++++++------------------------
 ioctl.h      |    2 ++
 2 files changed, 51 insertions(+), 35 deletions(-)
btrfslabel.c +49 -35
index 761a312..65388e5 100644
@@ -46,25 +46,52 @@
 #define GET_LABEL                      3
 #define SET_LABEL                      4
 
-static void change_label_unmounted(char *dev, char *nLabel)
+static int set_label_unmounted(const char *dev, const char *label)
 {
-       struct btrfs_root *root;
-       struct btrfs_trans_handle *trans;
-
-       /* Open the super_block at the default location
-        * and as read-write.
-        */
-       root = open_ctree(dev, 0, 1);
-       if (!root) /* errors are printed by open_ctree() */
-         return;
-
-       trans = btrfs_start_transaction(root, 1);
-       strncpy(root->fs_info->super_copy.label, nLabel, BTRFS_LABEL_SIZE);
-       root->fs_info->super_copy.label[BTRFS_LABEL_SIZE-1] = 0;
-       btrfs_commit_transaction(trans, root);
-
-       /* Now we close it since we are done. */
-       close_ctree(root);
+	struct btrfs_trans_handle *trans;
+	struct btrfs_root *root;
+	int ret;
+
+	ret = check_mounted(dev);
+	if (ret < 0) {
+	       fprintf(stderr, "FATAL: error checking %s mount status\n", dev);
+	       return -1;
+	}
+
+	/* Open the super_block at the default location
+	 * and as read-write.
+	 */
+	root = open_ctree(dev, 0, 1);
+	if (!root) /* errors are printed by open_ctree() */
+		return -1;
+
+	trans = btrfs_start_transaction(root, 1);
+	strncpy(root->fs_info->super_copy.label, label, BTRFS_LABEL_SIZE);
+	root->fs_info->super_copy.label[BTRFS_LABEL_SIZE-1] = 0;
+	btrfs_commit_transaction(trans, root);
+
+	/* Now we close it since we are done. */
+	close_ctree(root);
+	return 0;
+}
+
+static int set_label_mounted(const char *mount_path, const char *label)
+{
+	int fd;
+
+	fd = open(mount_path, O_RDONLY | O_NOATIME);
+	if (fd < 0) {
+		fprintf(stderr, "ERROR: unable access to '%s'\n", mount_path);
+		return -1;
+	}
+
+	if (ioctl(fd, BTRFS_IOC_SET_FSLABEL, label) < 0) {
+		fprintf(stderr, "ERROR: unable get label %s\n", strerror(errno));
+		close(fd);
+		return -1;
+	}
+
+	return 0;
 }
 
 static int get_label_unmounted(const char *dev)
@@ -125,22 +152,9 @@ int get_label(const char *btrfs_dev)
 		get_label_mounted(btrfs_dev);
 }
 
-int set_label(char *btrfs_dev, char *nLabel)
+int set_label(char *btrfs_dev, char *label)
 {
-
-	int ret;
-	ret = check_mounted(btrfs_dev);
-	if (ret < 0)
-	{
-	       fprintf(stderr, "FATAL: error checking %s mount status\n", btrfs_dev);
-	       return -1;
-	}
-
-	if(ret != 0)
-	{
-	       fprintf(stderr, "FATAL: the filesystem has to be unmounted\n");
-	       return -2;
-	}
-	change_label_unmounted(btrfs_dev, nLabel);
-	return 0;
+	return is_existing_blk_or_reg_file(btrfs_dev) ?
+		set_label_unmounted(btrfs_dev, label) :
+		set_label_mounted(btrfs_dev, label);
 }
ioctl.h +2 -0
index ed6784d..07259f9 100644
@@ -434,4 +434,6 @@ struct btrfs_ioctl_clone_range_args {
 					struct btrfs_ioctl_qgroup_limit_args)
 #define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 53, \
 				   char[BTRFS_LABEL_SIZE])
+#define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 54, \
+				   char[BTRFS_LABEL_SIZE])
 #endif
Signature · 1 line
1.7.9.5
author
#7 lore raw

PATCH v4 3/3 Btrfs-progs: fix cmd_label_usage to reflect this change.

In reply to Jeff Liu

Fix the command usage of "btrfs filesystem label" to reflect this change. i.e. so that we can get/set the label of a mounted filesystem against the mountpoint.

---
 cmds-filesystem.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
cmds-filesystem.c +2 -2
index 9c43d35..5770d8b 100644
@@ -517,8 +517,8 @@ static int cmd_resize(int argc, char **argv)
 }
 
 static const char * const cmd_label_usage[] = {
-	"btrfs filesystem label <device> [<newlabel>]",
-	"Get or change the label of an unmounted filesystem",
+	"btrfs filesystem label [<device>|<mountpoint>] [<newlabel>]",
+	"Get or change the label of a filesystem",
 	"With one argument, get the label of filesystem on <device>.",
 	"If <newlabel> is passed, set the filesystem label to <newlabel>.",
 	NULL
Signature · 1 line
1.7.9.5
author
#8 lore raw

PATCH v4 2/2 Btrfs: Add a new ioctl to change the label of a mounted filesystem

In reply to Jeff Liu

Add a new ioctl BTRFS_FS_SETLABEL to change the label of a mounted filesystem.

---
 fs/btrfs/ioctl.c |   14 ++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 16 insertions(+)
fs/btrfs/ioctl.c +14 -0
index 8fcf9a5..b0a5e17 100644
@@ -3699,6 +3699,18 @@ out:
 	return ret;
 }
 
+static int btrfs_ioctl_get_fslabel(struct btrfs_root *root, void __user *arg)
+{
+	const char *label = root->fs_info->super_copy->label;
+	int ret;
+
+	mutex_lock(&root->fs_info->volume_mutex);
+	ret = copy_to_user(arg, label, strlen(label));
+	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 +3809,8 @@ long btrfs_ioctl(struct file *file, unsigned int
 		return 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(root, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +2 -0
index 731e287..98f896f 100644
@@ -453,4 +453,6 @@ struct btrfs_ioctl_send_args {
 			       struct btrfs_ioctl_qgroup_limit_args)
 #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \
 				      struct btrfs_ioctl_get_dev_stats)
+#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 53, \
+				   char[BTRFS_LABEL_SIZE])
 #endif
Signature · 9 lines
1.7.9.5

jeff@koala:/usr/src/linux$ cat btrfs_label_v3/0002-set-label.patch 
Signed-off-by: Jie Liu <[email protected]>

---
 fs/btrfs/ioctl.c |   34 ++++++++++++++++++++++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 36 insertions(+)
fs/btrfs/ioctl.c +34 -0
index b0a5e17..ebbf634 100644
@@ -3711,6 +3711,38 @@ static int btrfs_ioctl_get_fslabel(struct btrfs_root *root, void __user *arg)
 	return ret ? -EFAULT : 0;
 }
 
+static int btrfs_ioctl_set_fslabel(struct btrfs_root *root, void __user *arg)
+{
+	struct btrfs_super_block *super_block = root->fs_info->super_copy;
+	struct btrfs_trans_handle *trans;
+	char label[BTRFS_LABEL_SIZE];
+	int ret = 0;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (btrfs_root_readonly(root))
+		return -EROFS;
+
+	if (copy_from_user(label, arg, sizeof(label)))
+		return -EFAULT;
+
+	label[BTRFS_LABEL_SIZE - 1] = '\0';
+
+	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);
+	btrfs_end_transaction(trans, root);
+
+out_unlock:
+	mutex_unlock(&root->fs_info->volume_mutex);
+	return ret;
+}
+
 long btrfs_ioctl(struct file *file, unsigned int
 		cmd, unsigned long arg)
 {
@@ -3811,6 +3843,8 @@ long btrfs_ioctl(struct file *file, unsigned int
 		return btrfs_ioctl_qgroup_limit(root, argp);
 	case BTRFS_IOC_GET_FSLABEL:
 		return btrfs_ioctl_get_fslabel(root, argp);
+	case BTRFS_IOC_SET_FSLABEL:
+		return btrfs_ioctl_set_fslabel(root, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +2 -0
index 98f896f..cc4e657 100644
@@ -455,4 +455,6 @@ struct btrfs_ioctl_send_args {
 				      struct btrfs_ioctl_get_dev_stats)
 #define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 53, \
 				   char[BTRFS_LABEL_SIZE])
+#define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 54, \
+				   char[BTRFS_LABEL_SIZE])
 #endif
Signature · 1 line
1.7.9.5
#9 lore raw

Re: [PATCH V4 2/2] Btrfs: Add a new ioctl to change the label of a mounted filesystem

Hi, Liu

Quoted 19 lines · Jeff Liu

Add a new ioctl BTRFS_FS_SETLABEL to change the label of a mounted filesystem.

---
 fs/btrfs/ioctl.c |   14 ++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 16 insertions(+)
fs/btrfs/ioctl.c +1 -0
index 8fcf9a5..b0a5e17 100644
@@ -3699,6 +3699,18 @@ out:
 	return ret;
 }
 
+static int btrfs_ioctl_get_fslabel(struct btrfs_root *root, void __user *arg)

fs/btrfs/ioctl.c out: · line 3712

Quoted 10 lines
fs/btrfs/ioctl.c +10 -0
+{
+	const char *label = root->fs_info->super_copy->label;
+	int ret;
+
+	mutex_lock(&root->fs_info->volume_mutex);
+	ret = copy_to_user(arg, label, strlen(label));
+	mutex_unlock(&root->fs_info->volume_mutex);
+
+	return ret ? -EFAULT : 0;
+}

You sent out a wrong patch.

Thanks
Miao

Quoted 25 lines
fs/btrfs/ioctl.c +3 -0
+
 long btrfs_ioctl(struct file *file, unsigned int
 		cmd, unsigned long arg)
 {
@@ -3797,6 +3809,8 @@ long btrfs_ioctl(struct file *file, unsigned int
 		return 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(root, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +2 -0
index 731e287..98f896f 100644
@@ -453,4 +453,6 @@ struct btrfs_ioctl_send_args {
 			       struct btrfs_ioctl_qgroup_limit_args)
 #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \
 				      struct btrfs_ioctl_get_dev_stats)
+#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 53, \
+				   char[BTRFS_LABEL_SIZE])
 #endif
author
#10 lore raw

Re: [PATCH V4 2/2] Btrfs: Add a new ioctl to change the label of a mounted filesystem

Hi Miao,

Quoted 21 lines · Miao Xie

Hi, Liu

Quoted 18 lines · Jeff Liu

Add a new ioctl BTRFS_FS_SETLABEL to change the label of a mounted filesystem.

---
 fs/btrfs/ioctl.c |   14 ++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 16 insertions(+)
fs/btrfs/ioctl.c +0 -0
index 8fcf9a5..b0a5e17 100644
@@ -3699,6 +3699,18 @@ out:
 	return ret;
 }
 
Quoted 14 lines

fs/btrfs/ioctl.c out: · line 3712

Quoted 11 lines
fs/btrfs/ioctl.c +11 -0
+static int btrfs_ioctl_get_fslabel(struct btrfs_root *root, void __user *arg)
+{
+	const char *label = root->fs_info->super_copy->label;
+	int ret;
+
+	mutex_lock(&root->fs_info->volume_mutex);
+	ret = copy_to_user(arg, label, strlen(label));
+	mutex_unlock(&root->fs_info->volume_mutex);
+
+	return ret ? -EFAULT : 0;
+}

You sent out a wrong patch.

Ah! I should not send patches out during my sleepy state, will re-send them a little while, thank you. :)

-Jeff

Quoted 30 lines

Thanks
Miao

Quoted 25 lines
fs/btrfs/ioctl.c +3 -0
+
 long btrfs_ioctl(struct file *file, unsigned int
 		cmd, unsigned long arg)
 {
@@ -3797,6 +3809,8 @@ long btrfs_ioctl(struct file *file, unsigned int
 		return 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(root, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +2 -0
index 731e287..98f896f 100644
@@ -453,4 +453,6 @@ struct btrfs_ioctl_send_args {
 			       struct btrfs_ioctl_qgroup_limit_args)
 #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \
 				      struct btrfs_ioctl_get_dev_stats)
+#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 53, \
+				   char[BTRFS_LABEL_SIZE])
 #endif
author
#11 lore raw

PATCH RESEND v4 2/2 Btrfs: Add a new ioctl to change the label of a mounted filesystem

In reply to Jeff Liu

Add a new ioctl BTRFS_FS_SETLABEL to change the label of a mounted filesystem.

---
 fs/btrfs/ioctl.c |   34 ++++++++++++++++++++++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 36 insertions(+)
fs/btrfs/ioctl.c +34 -0
index b0a5e17..ebbf634 100644
@@ -3711,6 +3711,38 @@ static int btrfs_ioctl_get_fslabel(struct btrfs_root *root, void __user *arg)
 	return ret ? -EFAULT : 0;
 }
 
+static int btrfs_ioctl_set_fslabel(struct btrfs_root *root, void __user *arg)
+{
+	struct btrfs_super_block *super_block = root->fs_info->super_copy;
+	struct btrfs_trans_handle *trans;
+	char label[BTRFS_LABEL_SIZE];
+	int ret = 0;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (btrfs_root_readonly(root))
+		return -EROFS;
+
+	if (copy_from_user(label, arg, sizeof(label)))
+		return -EFAULT;
+
+	label[BTRFS_LABEL_SIZE - 1] = '\0';
+
+	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);
+	btrfs_end_transaction(trans, root);
+
+out_unlock:
+	mutex_unlock(&root->fs_info->volume_mutex);
+	return ret;
+}
+
 long btrfs_ioctl(struct file *file, unsigned int
 		cmd, unsigned long arg)
 {
@@ -3811,6 +3843,8 @@ long btrfs_ioctl(struct file *file, unsigned int
 		return btrfs_ioctl_qgroup_limit(root, argp);
 	case BTRFS_IOC_GET_FSLABEL:
 		return btrfs_ioctl_get_fslabel(root, argp);
+	case BTRFS_IOC_SET_FSLABEL:
+		return btrfs_ioctl_set_fslabel(root, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +2 -0
index 98f896f..cc4e657 100644
@@ -455,4 +455,6 @@ struct btrfs_ioctl_send_args {
 				      struct btrfs_ioctl_get_dev_stats)
 #define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 53, \
 				   char[BTRFS_LABEL_SIZE])
+#define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 54, \
+				   char[BTRFS_LABEL_SIZE])
 #endif
Signature · 1 line
1.7.9.5
#12 lore raw

Re: [RESEND PATCH V4 2/2] Btrfs: Add a new ioctl to change the label of a mounted filesystem

Quoted 21 lines · Jeff Liu

Add a new ioctl BTRFS_FS_SETLABEL to change the label of a mounted filesystem.

---
 fs/btrfs/ioctl.c |   34 ++++++++++++++++++++++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 36 insertions(+)
fs/btrfs/ioctl.c +2 -0
index b0a5e17..ebbf634 100644
@@ -3711,6 +3711,38 @@ static int btrfs_ioctl_get_fslabel(struct btrfs_root *root, void __user *arg)
 	return ret ? -EFAULT : 0;
 }
 
+static int btrfs_ioctl_set_fslabel(struct btrfs_root *root, void __user *arg)
+{

fs/btrfs/ioctl.c static int btrfs_ioctl_get_fslabel(struct btrfs_root *root, void __user *arg) · line 3725

Quoted 10 lines
fs/btrfs/ioctl.c +10 -0
+	struct btrfs_super_block *super_block = root->fs_info->super_copy;
+	struct btrfs_trans_handle *trans;
+	char label[BTRFS_LABEL_SIZE];
+	int ret = 0;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (btrfs_root_readonly(root))
+		return -EROFS;

Since this label is a global parameter, we needn't check the root is R/O or not.

The check we need is the write access of the fs, so we need call
mnt_want_write_file()

fs/btrfs/ioctl.c static int btrfs_ioctl_get_fslabel(struct btrfs_root *root, void __user *arg) · line 3730

Quoted 5 lines
fs/btrfs/ioctl.c +5 -0
+
+	if (copy_from_user(label, arg, sizeof(label)))
+		return -EFAULT;
+
+	label[BTRFS_LABEL_SIZE - 1] = '\0';

I don't think setting the last byte to '\0' is a good way, because the user would be very strange that the new label is truncated, but the program told him that it was done successfully.

Quoted 32 lines
fs/btrfs/ioctl.c +17 -0
+
+	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);
+	btrfs_end_transaction(trans, root);
+
+out_unlock:
+	mutex_unlock(&root->fs_info->volume_mutex);
+	return ret;
+}
+
 long btrfs_ioctl(struct file *file, unsigned int
 		cmd, unsigned long arg)
 {
@@ -3811,6 +3843,8 @@ long btrfs_ioctl(struct file *file, unsigned int
 		return btrfs_ioctl_qgroup_limit(root, argp);
 	case BTRFS_IOC_GET_FSLABEL:
 		return btrfs_ioctl_get_fslabel(root, argp);
+	case BTRFS_IOC_SET_FSLABEL:
+		return btrfs_ioctl_set_fslabel(root, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +0 -0
index 98f896f..cc4e657 100644

fs/btrfs/ioctl.h struct btrfs_ioctl_send_args { · line 460

Quoted 6 lines
fs/btrfs/ioctl.h +2 -0
@@ -455,4 +455,6 @@ struct btrfs_ioctl_send_args {
 				      struct btrfs_ioctl_get_dev_stats)
 #define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 53, \
 				   char[BTRFS_LABEL_SIZE])
+#define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 54, \
+				   char[BTRFS_LABEL_SIZE])
 #endif

number 50 has been reserved for this feature.

Thanks
Miao

author
#13 lore raw

Re: [RESEND PATCH V4 2/2] Btrfs: Add a new ioctl to change the label of a mounted filesystem

Sorry for my late response, I missed your feedback somehow.

Quoted 36 lines · Miao Xie
Quoted 21 lines · Jeff Liu

Add a new ioctl BTRFS_FS_SETLABEL to change the label of a mounted filesystem.

---
 fs/btrfs/ioctl.c |   34 ++++++++++++++++++++++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 36 insertions(+)
fs/btrfs/ioctl.c +2 -0
index b0a5e17..ebbf634 100644
@@ -3711,6 +3711,38 @@ static int btrfs_ioctl_get_fslabel(struct btrfs_root *root, void __user *arg)
 	return ret ? -EFAULT : 0;
 }
 
+static int btrfs_ioctl_set_fslabel(struct btrfs_root *root, void __user *arg)
+{

fs/btrfs/ioctl.c static int btrfs_ioctl_get_fslabel(struct btrfs_root *root, void __user *arg) · line 3725

Quoted 10 lines
fs/btrfs/ioctl.c +10 -0
+	struct btrfs_super_block *super_block = root->fs_info->super_copy;
+	struct btrfs_trans_handle *trans;
+	char label[BTRFS_LABEL_SIZE];
+	int ret = 0;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (btrfs_root_readonly(root))
+		return -EROFS;

Since this label is a global parameter, we needn't check the root is R/O or not.

Quoted 2 lines

The check we need is the write access of the fs, so we need call
mnt_want_write_file()

Yes, you are right.

Quoted 10 lines

fs/btrfs/ioctl.c static int btrfs_ioctl_get_fslabel(struct btrfs_root *root, void __user *arg) · line 3730

Quoted 6 lines
fs/btrfs/ioctl.c +5 -0
+
+	if (copy_from_user(label, arg, sizeof(label)))
+		return -EFAULT;
+
+	label[BTRFS_LABEL_SIZE - 1] = '\0';

I don't think setting the last byte to '\0' is a good way, because the user would be very strange that the new label is truncated, but the program told him that it was done successfully.

Good point, will revise it later.

Thanks,
-Jeff

Quoted 45 lines
Quoted 33 lines
fs/btrfs/ioctl.c +17 -0
+
+	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);
+	btrfs_end_transaction(trans, root);
+
+out_unlock:
+	mutex_unlock(&root->fs_info->volume_mutex);
+	return ret;
+}
+
 long btrfs_ioctl(struct file *file, unsigned int
 		cmd, unsigned long arg)
 {
@@ -3811,6 +3843,8 @@ long btrfs_ioctl(struct file *file, unsigned int
 		return btrfs_ioctl_qgroup_limit(root, argp);
 	case BTRFS_IOC_GET_FSLABEL:
 		return btrfs_ioctl_get_fslabel(root, argp);
+	case BTRFS_IOC_SET_FSLABEL:
+		return btrfs_ioctl_set_fslabel(root, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +0 -0
index 98f896f..cc4e657 100644

fs/btrfs/ioctl.h struct btrfs_ioctl_send_args { · line 460

Quoted 6 lines
fs/btrfs/ioctl.h +2 -0
@@ -455,4 +455,6 @@ struct btrfs_ioctl_send_args {
 				      struct btrfs_ioctl_get_dev_stats)
 #define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 53, \
 				   char[BTRFS_LABEL_SIZE])
+#define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 54, \
+				   char[BTRFS_LABEL_SIZE])
 #endif

number 50 has been reserved for this feature.

Thanks
Miao