[1/2,v3] btrfs: label should not contain return char
diff mbox

Message ID 1400755272-22590-1-git-send-email-anand.jain@oracle.com
State Superseded
Headers show

Commit Message

Anand Jain May 22, 2014, 10:41 a.m. UTC
From: Anand Jain <Anand.Jain@oracle.com>

generally if you use
  echo "test" > /sys/fs/btrfs/<fsid>/label
it would introduce return char at the end and it can not
be part of the label. The correct command is
  echo -n "test" > /sys/fs/btrfs/<fsid>/label

This patch will check for this user error

Signed-off-by: Anand Jain <Anand.Jain@oracle.com>
---
 v3: accepts review comments. Thanks David and Eric again
 v2: accepts review comments. Thanks Eric and Roman

 fs/btrfs/sysfs.c |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

Comments

David Sterba May 22, 2014, 11:41 a.m. UTC | #1
On Thu, May 22, 2014 at 06:41:11PM +0800, Anand Jain wrote:
> @@ -385,7 +392,8 @@ static ssize_t btrfs_label_store(struct kobject *kobj,
>  		return PTR_ERR(trans);
>  
>  	spin_lock(&root->fs_info->super_lock);
> -	strcpy(fs_info->super_copy->label, buf);
> +	strncpy(fs_info->super_copy->label, buf, p_len);
> +	memset(fs_info->super_copy->label + p_len, '\0', 1);

This looks strange, memset of length 1?

Anyway, I think the label buffer should be zeroed at the empty space, so
the idea is

	memset(fs_info->super_copy->label, 0, BTRFS_LABEL_SIZE):
	memcpy(fs_info->super_copy->label, buf, p_len);

Not super efficient, but works.

>  	spin_unlock(&root->fs_info->super_lock);
>  	ret = btrfs_commit_transaction(trans, root);
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch
diff mbox

diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
index c5eb214..159df4f 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -373,8 +373,15 @@  static ssize_t btrfs_label_store(struct kobject *kobj,
 	struct btrfs_trans_handle *trans;
 	struct btrfs_root *root = fs_info->fs_root;
 	int ret;
+	size_t p_len;
 
-	if (len >= BTRFS_LABEL_SIZE) {
+	/*
+	 * p_len is the len until the first occurrence of either
+	 * '\n' or '\0'
+	 */
+	p_len = strcspn(buf, "\n");
+
+	if (p_len >= BTRFS_LABEL_SIZE) {
 		pr_err("BTRFS: unable to set label with more than %d bytes\n",
 		       BTRFS_LABEL_SIZE - 1);
 		return -EINVAL;
@@ -385,7 +392,8 @@  static ssize_t btrfs_label_store(struct kobject *kobj,
 		return PTR_ERR(trans);
 
 	spin_lock(&root->fs_info->super_lock);
-	strcpy(fs_info->super_copy->label, buf);
+	strncpy(fs_info->super_copy->label, buf, p_len);
+	memset(fs_info->super_copy->label + p_len, '\0', 1);
 	spin_unlock(&root->fs_info->super_lock);
 	ret = btrfs_commit_transaction(trans, root);