Package: btrfs-progs
Version: 6.6.3-1
Severity: normal
Tags: patch
Forwarded: https://github.com/kdave/btrfs-progs/issues/730

Hi,

the latest release 6.6.2 introduced a regression when creating
subvolumes.
This causes the libblockdev test suite to fail [1].
The upstream issue references a commit which addresses this issue [2]
and I can confirm that  this commit fixes the libblockdev autopkgtest
failure.
Would be great if the Debian package could cherry-pick this commit.
If you are busy, I can offer to NMU.

Michael


[1] https://ci.debian.net/packages/libb/libblockdev/unstable/amd64/41650426/
[2] 
https://github.com/kdave/btrfs-progs/commit/3f988c91763682afc1242de844a901837ab4863a

-- System Information:
Debian Release: trixie/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)

Kernel: Linux 6.6.9-amd64 (SMP w/16 CPU threads; PREEMPT)
Kernel taint flags: TAINT_WARN
Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages btrfs-progs depends on:
ii  libblkid1         2.39.3-6
ii  libc6             2.37-13
ii  libcom-err2       1.47.0-2+b1
ii  libext2fs2        1.47.0-2+b1
ii  liblzo2-2         2.10-2
ii  libreiserfscore0  1:3.6.27-7
ii  libudev1          255.2-4
ii  libuuid1          2.39.3-6
ii  libzstd1          1.5.5+dfsg2-2
ii  zlib1g            1:1.3.dfsg-3

btrfs-progs recommends no packages.

Versions of packages btrfs-progs suggests:
pn  duperemove  <none>

-- no debconf information
>From 3f988c91763682afc1242de844a901837ab4863a Mon Sep 17 00:00:00 2001
From: Qu Wenruo <w...@suse.com>
Date: Wed, 10 Jan 2024 13:23:31 +1030
Subject: [PATCH] btrfs-progs: subvolume: fix return value when the target
 exists

[BUG]
When try to create a subvolume where the target path already exists, the
"btrfs" command doesn't return error code correctly.

  # mkfs.btrfs -f $dev
  # mount $dev $mnt
  # touch $mnt/subv1
  # btrfs subvolume create $mnt/subv1
  ERROR: target path already exists: $mnt/subv1
  # echo $?
  0

[CAUSE]
The check on whether target exists is done by path_is_dir(), if it
returns 0 or 1, it means there is something in that path already.

But unfortunately commit 5aa959fb3440 ("btrfs-progs: subvolume create:
accept multiple arguments") only changed the out label, which would
directly return @ret, not updating the return value correctly.

[FIX]
Make sure all error out branch has their @ret manually updated.

Fixes: 5aa959fb3440 ("btrfs-progs: subvolume create: accept multiple arguments")
Issue: #730
Signed-off-by: Qu Wenruo <w...@suse.com>
Signed-off-by: David Sterba <dste...@suse.com>
---
 cmds/subvolume.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/cmds/subvolume.c b/cmds/subvolume.c
index 57be9eac5..b01d5c80f 100644
--- a/cmds/subvolume.c
+++ b/cmds/subvolume.c
@@ -160,12 +160,14 @@ static int create_one_subvolume(const char *dst, struct 
btrfs_qgroup_inherit *in
        }
        if (ret >= 0) {
                error("target path already exists: %s", dst);
+               ret = -EEXIST;
                goto out;
        }
 
        dupname = strdup(dst);
        if (!dupname) {
                error_msg(ERROR_MSG_MEMORY, "duplicating %s", dst);
+               ret = -ENOMEM;
                goto out;
        }
        newname = basename(dupname);
@@ -173,18 +175,21 @@ static int create_one_subvolume(const char *dst, struct 
btrfs_qgroup_inherit *in
        dupdir = strdup(dst);
        if (!dupdir) {
                error_msg(ERROR_MSG_MEMORY, "duplicating %s", dst);
+               ret = -ENOMEM;
                goto out;
        }
        dstdir = dirname(dupdir);
 
        if (!test_issubvolname(newname)) {
                error("invalid subvolume name: %s", newname);
+               ret = -EINVAL;
                goto out;
        }
 
        len = strlen(newname);
        if (len > BTRFS_VOL_NAME_MAX) {
                error("subvolume name too long: %s", newname);
+               ret = -EINVAL;
                goto out;
        }
 
@@ -208,6 +213,8 @@ static int create_one_subvolume(const char *dst, struct 
btrfs_qgroup_inherit *in
                                        goto out;
                                }
                        } else if (ret <= 0) {
+                               if (ret == 0)
+                                       ret = -EEXIST;
                                errno = ret ;
                                error("failed to check directory %s before 
creation: %m", p);
                                goto out;
@@ -218,8 +225,10 @@ static int create_one_subvolume(const char *dst, struct 
btrfs_qgroup_inherit *in
        }
 
        fddst = btrfs_open_dir(dstdir, &dirstream, 1);
-       if (fddst < 0)
+       if (fddst < 0) {
+               ret = fddst;
                goto out;
+       }
 
        pr_verbose(LOG_DEFAULT, "Create subvolume '%s/%s'\n", dstdir, newname);
        if (inherit) {

Reply via email to