Skip to contentSkip to conversation

Btrfs: get/set label for a mounted file system

RFC PATCH In review Jeff Liu 3 participants 8 messages Jan 5, 2013 – Jan 8, 2013 Btrfs file system

lore
Share & tools
lore

Jeff Liu

author
#0 lore raw

v9 cover Btrfs: get/set label for a mounted file system

Hello,

There have a couple of changes in this version which were shown as following:

- Don't reserve an unit of transactions for set filesystem label.

- Replace the old warning message to "btrfs: label is too long, return the first %zu bytes" in btrfs_ioc_get_fslabel() is the existing label length is longer than than BTRFS_LABEL_SIZE - 1. Otherwise, checkpatch.pl would give a warning as:
"WARNING: quoted string split across lines".

- btrfs_ioc_set_fslabel(): drop an error message if the input label length is too long for debugging purpose.

The old versions can be found at:
v8:
http://permalink.gmane.org/gmane.comp.file-systems.btrfs/21906

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

author
#1 lore raw

RFC PATCH v9 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 filesystem.

Cc Miao Xie <[email protected]>
Cc Goffredo Baroncelli <[email protected]>
Cc David Sterba <[email protected]>
---
 fs/btrfs/ioctl.c |   21 +++++++++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 23 insertions(+)
fs/btrfs/ioctl.c +21 -0
index 8fcf9a5..ef2f55a 100644
@@ -3699,6 +3699,25 @@ 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) {
+		pr_warn("btrfs: label is too long, return the first %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 +3816,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(file, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +2 -0
index 731e287..5b2cbef 100644
@@ -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
#2 lore raw

Re: [RFC PATCH v9 1/2] Btrfs: Add a new ioctl to get the label of a mounted file system

Hi Jeff,

Quoted 18 lines · Jeff Liu

Add a new ioctl(2) BTRFS_IOC_GET_FSLABLE, so that we can get the label upon a mounted filesystem.

Cc Miao Xie <[email protected]>
Cc Goffredo Baroncelli <[email protected]>
Cc David Sterba <[email protected]>
---
 fs/btrfs/ioctl.c |   21 +++++++++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 23 insertions(+)
fs/btrfs/ioctl.c +0 -0
index 8fcf9a5..ef2f55a 100644

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

Quoted 3 lines
fs/btrfs/ioctl.c +0 -0
@@ -3699,6 +3699,25 @@ out:
 	return ret;
 }
 

May be that it was already discussed, and I am missing something, but if we check the label length we should terminate the string with a zero in case this is too long...

However this is a minor bug, please push this patch forward..

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

Quoted 6 lines
fs/btrfs/ioctl.c +6 -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;

+ int label_is_too_long = 0;

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

Quoted 4 lines
fs/btrfs/ioctl.c +4 -0
+
+	if (len == BTRFS_LABEL_SIZE) {
+		pr_warn("btrfs: label is too long, return the first %zu bytes\n",
+			--len);

+ label_is_too_long = 1;

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

Quoted 4 lines
fs/btrfs/ioctl.c +4 -0
+	}
+
+	mutex_lock(&root->fs_info->volume_mutex);
+	ret = copy_to_user(arg, label, len);

+ if (!ret && label_is_too_long)
+ ret = copy_to_user(arg+BTRFS_LABEL_SIZE, "", 1);

Quoted 30 lines
fs/btrfs/ioctl.c +7 -0
+	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 +3816,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(file, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +2 -0
index 731e287..5b2cbef 100644
@@ -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 · 2 lines
gpg @keyserver.linux.it: Goffredo Baroncelli (kreijackATinwind.it>
Key fingerprint BBF5 1610 0B64 DAC6 5F7D  17B2 0EDA 9B37 8B82 E0B5
author
#3 lore raw

Re: [RFC PATCH v9 1/2] Btrfs: Add a new ioctl to get the label of a mounted file system

Hi,

Quoted 29 lines · Goffredo Baroncelli

Hi Jeff,

Quoted 18 lines · Jeff Liu

Add a new ioctl(2) BTRFS_IOC_GET_FSLABLE, so that we can get the label upon a mounted filesystem.

Cc Miao Xie <[email protected]>
Cc Goffredo Baroncelli <[email protected]>
Cc David Sterba <[email protected]>
---
 fs/btrfs/ioctl.c |   21 +++++++++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 23 insertions(+)
fs/btrfs/ioctl.c +0 -0
index 8fcf9a5..ef2f55a 100644

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

Quoted 3 lines
fs/btrfs/ioctl.c +0 -0
@@ -3699,6 +3699,25 @@ out:
 	return ret;
 }
 

May be that it was already discussed, and I am missing something, but if we check the label length we should terminate the string with a zero in case this is too long...

Quoted 1 line

However this is a minor bug, please push this patch forward..

I don't think so.
Why we need to terminate the string with a zero?
We have already truncated the label string up to maximum 255 bytes if it was too long.

Consider the normal conditions, i.e. the label string is less than 256, we just copy it back to the user without a terminated NUL.

Quoted 9 lines

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

Quoted 8 lines
fs/btrfs/ioctl.c +6 -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;

+ int label_is_too_long = 0;

	  bool label_is_too_long = false;
Quoted 6 lines

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

Quoted 4 lines
fs/btrfs/ioctl.c +4 -0
+
+	if (len == BTRFS_LABEL_SIZE) {
+		pr_warn("btrfs: label is too long, return the first %zu bytes\n",
+			--len);

+ label_is_too_long = 1;

		  label_is_too_long = true;

Review

Quoted 6 lines
Quoted 4 lines
fs/btrfs/ioctl.c +4 -0
+	}
+
+	mutex_lock(&root->fs_info->volume_mutex);
+	ret = copy_to_user(arg, label, len);
(quoted diff) +2 -0
+	if (!ret && label_is_too_long)
+     		ret = copy_to_user(arg+BTRFS_LABEL_SIZE, "", 1);

Hmm? ret = copy_to_user(arg + len, "", 1);

Quoted 1 line

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

Quoted 1 line
fs/btrfs/ioctl.c +1 -0
+	mutex_unlock(&root->fs_info->volume_mutex);

If you or anyone has objection to this patch, please just post yours, I won't follow it up again.

Quoted 31 lines
Quoted 29 lines
fs/btrfs/ioctl.c +6 -0
+
+	return ret ? -EFAULT : 0;
+}
+
 long btrfs_ioctl(struct file *file, unsigned int
 		cmd, unsigned long arg)
 {
@@ -3797,6 +3816,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(file, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +2 -0
index 731e287..5b2cbef 100644
@@ -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
#4 lore raw

Re: [RFC PATCH v9 1/2] Btrfs: Add a new ioctl to get the label of a mounted file system

Hi Jeff,

Quoted 31 lines · Jeff Liu

Hi,

Quoted 29 lines · Goffredo Baroncelli

Hi Jeff,

Quoted 18 lines · Jeff Liu

Add a new ioctl(2) BTRFS_IOC_GET_FSLABLE, so that we can get the label upon a mounted filesystem.

Cc Miao Xie <[email protected]>
Cc Goffredo Baroncelli <[email protected]>
Cc David Sterba <[email protected]>
---
 fs/btrfs/ioctl.c |   21 +++++++++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 23 insertions(+)
fs/btrfs/ioctl.c +0 -0
index 8fcf9a5..ef2f55a 100644

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

Quoted 3 lines
fs/btrfs/ioctl.c +0 -0
@@ -3699,6 +3699,25 @@ out:
 	return ret;
 }
 

May be that it was already discussed, and I am missing something, but if we check the label length we should terminate the string with a zero in case this is too long...

Quoted 8 lines
Quoted 1 line

However this is a minor bug, please push this patch forward..

I don't think so.
Why we need to terminate the string with a zero?
We have already truncated the label string up to maximum 255 bytes if it was too long.

Consider the normal conditions, i.e. the label string is less than 256, we just copy it back to the user without a terminated NUL.

Sorry I don't understand the reason to terminate the string up to 255 chars without adding a zero. Or we copy all the buffer (BTRFS_LABEL_SIZE characters without furthers checks) or we copy BTRFS_LABEL_SIZE-1 characters, adding a zero at the end.

Quoted 16 lines
Quoted 9 lines

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

Quoted 8 lines
fs/btrfs/ioctl.c +6 -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;

+ int label_is_too_long = 0;

	  bool label_is_too_long = false;
Quoted 6 lines

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

Quoted 4 lines
fs/btrfs/ioctl.c +4 -0
+
+	if (len == BTRFS_LABEL_SIZE) {
+		pr_warn("btrfs: label is too long, return the first %zu bytes\n",
+			--len);

+ label_is_too_long = 1;

Quoted 9 lines
		  label_is_too_long = true;

Review

Quoted 6 lines
Quoted 4 lines
fs/btrfs/ioctl.c +4 -0
+	}
+
+	mutex_lock(&root->fs_info->volume_mutex);
+	ret = copy_to_user(arg, label, len);
(quoted diff) +2 -0
+	if (!ret && label_is_too_long)
+     		ret = copy_to_user(arg+BTRFS_LABEL_SIZE, "", 1);

Hmm? ret = copy_to_user(arg + len, "", 1);

My idea was to put a zero at the end of the string, but I did a mistake with the cut&paste.. sorry :-)

Quoted 3 lines
Quoted 1 line

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

Quoted 1 line
fs/btrfs/ioctl.c +1 -0
+	mutex_unlock(&root->fs_info->volume_mutex);

If you or anyone has objection to this patch, please just post yours, I won't follow it up again.

Sorry I don't want to bother anybody, I know that reviewing a patch nine times is a very havvy work. I (and I think more other peoples) really appreciate your efforts.

BR
G.Baroncelli

Quoted 33 lines
Quoted 31 lines
Quoted 29 lines
fs/btrfs/ioctl.c +6 -0
+
+	return ret ? -EFAULT : 0;
+}
+
 long btrfs_ioctl(struct file *file, unsigned int
 		cmd, unsigned long arg)
 {
@@ -3797,6 +3816,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(file, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +2 -0
index 731e287..5b2cbef 100644
@@ -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 · 2 lines
gpg @keyserver.linux.it: Goffredo Baroncelli (kreijackATinwind.it>
Key fingerprint BBF5 1610 0B64 DAC6 5F7D  17B2 0EDA 9B37 8B82 E0B5
author
#5 lore raw

Re: [RFC PATCH v9 1/2] Btrfs: Add a new ioctl to get the label of a mounted file system

Hi Goffredo,

Quoted 40 lines · Goffredo Baroncelli

Hi Jeff,

Quoted 37 lines · Jeff Liu

Hi,

Quoted 29 lines · Goffredo Baroncelli

Hi Jeff,

Quoted 18 lines · Jeff Liu

Add a new ioctl(2) BTRFS_IOC_GET_FSLABLE, so that we can get the label upon a mounted filesystem.

Cc Miao Xie <[email protected]>
Cc Goffredo Baroncelli <[email protected]>
Cc David Sterba <[email protected]>
---
 fs/btrfs/ioctl.c |   21 +++++++++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 23 insertions(+)
fs/btrfs/ioctl.c +0 -0
index 8fcf9a5..ef2f55a 100644

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

Quoted 3 lines
fs/btrfs/ioctl.c +0 -0
@@ -3699,6 +3699,25 @@ out:
 	return ret;
 }
 

May be that it was already discussed, and I am missing something, but if we check the label length we should terminate the string with a zero in case this is too long...

Quoted 1 line

However this is a minor bug, please push this patch forward..

I don't think so.
Why we need to terminate the string with a zero?
We have already truncated the label string up to maximum 255 bytes if it was too long.

Quoted 7 lines
Quoted 2 lines

Consider the normal conditions, i.e. the label string is less than 256, we just copy it back to the user without a terminated NUL.

Sorry I don't understand the reason to terminate the string up to 255 chars without adding a zero. Or we copy all the buffer (BTRFS_LABEL_SIZE characters without furthers checks) or we copy BTRFS_LABEL_SIZE-1 characters, adding a zero at the end.

For normal cases, there should already has a NUL at the end of the input label string when performing btrfs_ioc_set_fslabel(), and we have also added a NUL for unmounted label set in btrfs-progs. In both cases, put it again on btrfs_ioc_get_fslabel() is redundant IMO.

If we ran into a too long label, return the first 255 bytes is fine for both mounted and unmounted get_label() routines in btrfs-progs since I did memset(label, 0, sizeof(label)) at first for fetching mounted fs label.

Also, I have not found any existing kernel code does similar things by adding a NUL to end up a char array, could you show me an example?

"""Or we copy all the buffer(BTRFS_LABEL_SIZE) characters without furthers checks"""

If an array is capable of N chars, we can only full it with N - 1 chars.

Thanks,
-Jeff

Quoted 74 lines
Quoted 16 lines
Quoted 9 lines

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

Quoted 8 lines
fs/btrfs/ioctl.c +6 -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;

+ int label_is_too_long = 0;

	  bool label_is_too_long = false;
Quoted 6 lines

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

Quoted 4 lines
fs/btrfs/ioctl.c +4 -0
+
+	if (len == BTRFS_LABEL_SIZE) {
+		pr_warn("btrfs: label is too long, return the first %zu bytes\n",
+			--len);

+ label_is_too_long = 1;

Quoted 9 lines
		  label_is_too_long = true;

Review

Quoted 6 lines
Quoted 4 lines
fs/btrfs/ioctl.c +4 -0
+	}
+
+	mutex_lock(&root->fs_info->volume_mutex);
+	ret = copy_to_user(arg, label, len);
(quoted diff) +2 -0
+	if (!ret && label_is_too_long)
+     		ret = copy_to_user(arg+BTRFS_LABEL_SIZE, "", 1);

Hmm? ret = copy_to_user(arg + len, "", 1);

My idea was to put a zero at the end of the string, but I did a mistake with the cut&paste.. sorry :-)

Quoted 3 lines
Quoted 1 line

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

Quoted 1 line
fs/btrfs/ioctl.c +1 -0
+	mutex_unlock(&root->fs_info->volume_mutex);

If you or anyone has objection to this patch, please just post yours, I won't follow it up again.

Sorry I don't want to bother anybody, I know that reviewing a patch nine times is a very havvy work. I (and I think more other peoples) really appreciate your efforts.

BR
G.Baroncelli

Quoted 33 lines
Quoted 31 lines
Quoted 29 lines
fs/btrfs/ioctl.c +6 -0
+
+	return ret ? -EFAULT : 0;
+}
+
 long btrfs_ioctl(struct file *file, unsigned int
 		cmd, unsigned long arg)
 {
@@ -3797,6 +3816,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(file, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +2 -0
index 731e287..5b2cbef 100644
@@ -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
author
#6 lore raw

RFC PATCH v9 2/2 Btrfs: set/change the label of a mounted file system

In reply to Jeff Liu

With this new ioctl(2) BTRFS_IOC_SET_FSLABEL, we can set/change the label of a mounted file system.

---
 fs/btrfs/ioctl.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 44 insertions(+)
fs/btrfs/ioctl.c +42 -0
index ef2f55a..8e676c3 100644
@@ -3718,6 +3718,46 @@ 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) {
+		pr_err("btrfs: unable to set label with more than %d bytes\n",
+		       BTRFS_LABEL_SIZE - 1);
+		return -EINVAL;
+	}
+
+	ret = mnt_want_write_file(file);
+	if (ret)
+		return ret;
+
+	mutex_lock(&root->fs_info->volume_mutex);
+	trans = btrfs_start_transaction(root, 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;
+}
+
 long btrfs_ioctl(struct file *file, unsigned int
 		cmd, unsigned long arg)
 {
@@ -3818,6 +3858,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(file, argp);
+	case BTRFS_IOC_SET_FSLABEL:
+		return btrfs_ioctl_set_fslabel(file, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +2 -0
index 5b2cbef..2abe239 100644
@@ -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
Reviewed-by on v9 2/2
#7 lore raw

Re: [RFC PATCH v9 2/2] Btrfs: set/change the label of a mounted file system

Quoted 86 lines · Jeff Liu

With this new ioctl(2) BTRFS_IOC_SET_FSLABEL, we can set/change the label of a mounted file system.

---
 fs/btrfs/ioctl.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 fs/btrfs/ioctl.h |    2 ++
 2 files changed, 44 insertions(+)
fs/btrfs/ioctl.c +42 -0
index ef2f55a..8e676c3 100644
@@ -3718,6 +3718,46 @@ 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) {
+		pr_err("btrfs: unable to set label with more than %d bytes\n",
+		       BTRFS_LABEL_SIZE - 1);
+		return -EINVAL;
+	}
+
+	ret = mnt_want_write_file(file);
+	if (ret)
+		return ret;
+
+	mutex_lock(&root->fs_info->volume_mutex);
+	trans = btrfs_start_transaction(root, 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;
+}
+
 long btrfs_ioctl(struct file *file, unsigned int
 		cmd, unsigned long arg)
 {
@@ -3818,6 +3858,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(file, argp);
+	case BTRFS_IOC_SET_FSLABEL:
+		return btrfs_ioctl_set_fslabel(file, argp);
 	}
 
 	return -ENOTTY;
fs/btrfs/ioctl.h +2 -0
index 5b2cbef..2abe239 100644
@@ -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 · 2 lines
gpg @keyserver.linux.it: Goffredo Baroncelli (kreijackATinwind.it>
Key fingerprint BBF5 1610 0B64 DAC6 5F7D  17B2 0EDA 9B37 8B82 E0B5