btrfs: label should not contain return char
authorSatoru Takeuchi <takeuchi_satoru@jp.fujitsu.com>
Tue, 1 Jul 2014 08:00:07 +0000 (17:00 +0900)
committerChris Mason <clm@fb.com>
Wed, 17 Sep 2014 20:37:25 +0000 (13:37 -0700)
Rediffed remaining parts of original patch from Anand Jain.  This makes
sure to avoid trailing newlines in the btrfs label output

reproducer.sh:

===============================================================================

TEST_DEV=/dev/vdb
TEST_DIR=/home/sat/mnt

umount /home/sat/mnt

mkfs.btrfs -f $TEST_DEV
UUID=$(btrfs fi show $TEST_DEV | head -1 | sed -e 's/.*uuid: \([-0-9a-z]*\)$/\1/')
mount $TEST_DEV $TEST_DIR
LABELFILE=/sys/fs/btrfs/$UUID/label

echo "Test for empty label..." >&2
LINES="$(cat $LABELFILE | wc -l | awk '{print $1}')"
RET=0

if [ $LINES -eq 0 ] ; then
    echo '[PASS] Trailing \n is removed correctly.' >&2
else
    echo '[FAIL] Trailing \n still exists.' >&2
    RET=1
fi

echo "Test for non-empty label..." >&2

echo testlabel >$LABELFILE
LINES="$(cat $LABELFILE | wc -l | awk '{print $1}')"

if [ $LINES -eq 1 ] ; then
    echo '[PASS] Trailing \n is removed correctly.' >&2
else
    echo '[FAIL] Trailing \n still exists.' >&2
    RET=1
fi

exit $RET
===============================================================================

Signed-off-by: Satoru Takeuchi <takeuchi_satoru@jp.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
fs/btrfs/sysfs.c

index 12e53556e214c2c26f0a67aadf63b53637178822..82a968fdfd8059a0c819fc0625915bd5f8f6a727 100644 (file)
@@ -363,7 +363,8 @@ static ssize_t btrfs_label_show(struct kobject *kobj,
                                struct kobj_attribute *a, char *buf)
 {
        struct btrfs_fs_info *fs_info = to_fs_info(kobj);
-       return snprintf(buf, PAGE_SIZE, "%s\n", fs_info->super_copy->label);
+       char *label = fs_info->super_copy->label;
+       return snprintf(buf, PAGE_SIZE, label[0] ? "%s\n" : "%s", label);
 }
 
 static ssize_t btrfs_label_store(struct kobject *kobj,
@@ -374,8 +375,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)
                return -EINVAL;
 
        trans = btrfs_start_transaction(root, 0);
@@ -383,7 +391,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);
+       memset(fs_info->super_copy->label, 0, BTRFS_LABEL_SIZE);
+       memcpy(fs_info->super_copy->label, buf, p_len);
        spin_unlock(&root->fs_info->super_lock);
        ret = btrfs_commit_transaction(trans, root);