diff mbox series

[v3] btrfs-progs: fix btrfs resize failed.

Message ID 1658666627-27889-1-git-send-email-zhanglikernel@gmail.com (mailing list archive)
State New, archived
Headers show
Series [v3] btrfs-progs: fix btrfs resize failed. | expand

Commit Message

Li Zhang July 24, 2022, 12:43 p.m. UTC
related issuse:
https://github.com/kdave/btrfs-progs/issues/470

V1 link:
https://www.spinics.net/lists/linux-btrfs/msg126661.html

V2 link:
https://www.spinics.net/lists/linux-btrfs/msg126853.html

[BUG]
1. If there is no devid=1, when the user uses the btrfs file system tool,
the following error will be reported,

$ sudo btrfs filesystem show /mnt/1
Label: none  uuid: 64dc0f68-9afa-4465-9ea1-2bbebfdb6cec
    Total devices 2 FS bytes used 704.00KiB
    devid    2 size 15.00GiB used 1.16GiB path /dev/loop2
    devid    3 size 15.00GiB used 1.16GiB path /dev/loop3
$ sudo btrfs filesystem resize -1G /mnt/1
ERROR: cannot find devid: 1
ERROR: unable to resize '/mnt/1': No such device

2. Function check_resize_args, if get_fs_info is successful,
check_resize_args always returns 0, Even if the parameter
passed to kernel space is longer than the size allowed to
be passed to kernel space (BTRFS_VOL_NAME_MAX).

[CAUSE]
1. If the user does not specify the devid id explicitly,
btrfs will use the default devid 1, so it will report an error when dev 1 is missing.

2. The last line of the function check_resize_args is return 0.

[FIX]
1. If the file system contains multiple devices, output an error message to the user.
If the filesystem has only one device, resize should automatically add the unique devid.

2. The function check_resize_args should not return 0 on the last line,
it should return ret representing the return value.

3. Update the "btrfs-filesystem" man page

[RESULT]

$ sudo btrfs filesystem resize --help
usage: btrfs filesystem resize [options] [devid:][+/-]<newsize>[kKmMgGtTpPeE]|[devid:]max <path>

    Resize a filesystem

    If the filesystem contains only one device, devid can be ignored.
    If 'max' is passed, the filesystem will occupy all available space
    on the device 'devid'.
    [kK] means KiB, which denotes 1KiB = 1024B, 1MiB = 1024KiB, etc.

    --enqueue         wait if there's another exclusive operation running,
                      otherwise continue

$ sudo btrfs filesystem show /mnt/1/
Label: none  uuid: 2025e6ae-0b6d-40b4-8685-3e7e9fc9b2c2
        Total devices 2 FS bytes used 144.00KiB
        devid    2 size 15.00GiB used 1.16GiB path /dev/loop2
        devid    3 size 15.00GiB used 1.16GiB path /dev/loop3

$ sudo btrfs filesystem resize -1G /mnt/1
ERROR: The file system has multiple devices, please specify devid exactly.
ERROR: The device information list is as follows.
        devid    2 size 15.00GiB used 1.16GiB path /dev/loop2
        devid    3 size 15.00GiB used 1.16GiB path /dev/loop3

$ sudo btrfs device delete 2 /mnt/1/

$ sudo btrfs filesystem show /mnt/1/
Label: none  uuid: 2025e6ae-0b6d-40b4-8685-3e7e9fc9b2c2
        Total devices 1 FS bytes used 144.00KiB
        devid    3 size 15.00GiB used 1.28GiB path /dev/loop3

$ sudo btrfs filesystem resize -1G /mnt/1
Resize device id 3 (/dev/loop3) from 15.00GiB to 14.00GiB

$ sudo btrfs filesystem show /mnt/1/
Label: none  uuid: cc6e1beb-255b-431f-baf5-02e8056fd0b6
	Total devices 1 FS bytes used 144.00KiB
	devid    3 size 14.00GiB used 1.28GiB path /dev/loop3

Signed-off-by: Li Zhang <zhanglikernel@gmail.com>
---
 cmds/filesystem.c | 47 ++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 40 insertions(+), 7 deletions(-)

Comments

Qu Wenruo July 25, 2022, 12:34 a.m. UTC | #1
On 2022/7/24 20:43, Li Zhang wrote:
> related issuse:
> https://github.com/kdave/btrfs-progs/issues/470

Something I forgot to mention is related to the changelog part.

This can be replaced by the following tag before SOB line:

Issue: 470

>
> V1 link:
> https://www.spinics.net/lists/linux-btrfs/msg126661.html
>
> V2 link:
> https://www.spinics.net/lists/linux-btrfs/msg126853.html

Changelog for single patch can be put after all the tags, and with a
line of "---", so at apply time git will discard the extra info.

One example can be found here:

https://lore.kernel.org/linux-btrfs/20220617151133.GO20633@twin.jikos.cz/T/

>
> [BUG]
> 1. If there is no devid=1, when the user uses the btrfs file system tool,
> the following error will be reported,
>
> $ sudo btrfs filesystem show /mnt/1
> Label: none  uuid: 64dc0f68-9afa-4465-9ea1-2bbebfdb6cec
>      Total devices 2 FS bytes used 704.00KiB
>      devid    2 size 15.00GiB used 1.16GiB path /dev/loop2
>      devid    3 size 15.00GiB used 1.16GiB path /dev/loop3
> $ sudo btrfs filesystem resize -1G /mnt/1
> ERROR: cannot find devid: 1
> ERROR: unable to resize '/mnt/1': No such device
>
> 2. Function check_resize_args, if get_fs_info is successful,
> check_resize_args always returns 0, Even if the parameter
> passed to kernel space is longer than the size allowed to
> be passed to kernel space (BTRFS_VOL_NAME_MAX).
>
> [CAUSE]
> 1. If the user does not specify the devid id explicitly,
> btrfs will use the default devid 1, so it will report an error when dev 1 is missing.
>
> 2. The last line of the function check_resize_args is return 0.
>
> [FIX]
> 1. If the file system contains multiple devices, output an error message to the user.
> If the filesystem has only one device, resize should automatically add the unique devid.
>
> 2. The function check_resize_args should not return 0 on the last line,
> it should return ret representing the return value.
>
> 3. Update the "btrfs-filesystem" man page
>
> [RESULT]
>
> $ sudo btrfs filesystem resize --help
> usage: btrfs filesystem resize [options] [devid:][+/-]<newsize>[kKmMgGtTpPeE]|[devid:]max <path>
>
>      Resize a filesystem
>
>      If the filesystem contains only one device, devid can be ignored.
>      If 'max' is passed, the filesystem will occupy all available space
>      on the device 'devid'.
>      [kK] means KiB, which denotes 1KiB = 1024B, 1MiB = 1024KiB, etc.
>
>      --enqueue         wait if there's another exclusive operation running,
>                        otherwise continue

Although help string is updated, the manpage is still not updated.

Thanks,
Qu

>
> $ sudo btrfs filesystem show /mnt/1/
> Label: none  uuid: 2025e6ae-0b6d-40b4-8685-3e7e9fc9b2c2
>          Total devices 2 FS bytes used 144.00KiB
>          devid    2 size 15.00GiB used 1.16GiB path /dev/loop2
>          devid    3 size 15.00GiB used 1.16GiB path /dev/loop3
>
> $ sudo btrfs filesystem resize -1G /mnt/1
> ERROR: The file system has multiple devices, please specify devid exactly.
> ERROR: The device information list is as follows.
>          devid    2 size 15.00GiB used 1.16GiB path /dev/loop2
>          devid    3 size 15.00GiB used 1.16GiB path /dev/loop3
>
> $ sudo btrfs device delete 2 /mnt/1/
>
> $ sudo btrfs filesystem show /mnt/1/
> Label: none  uuid: 2025e6ae-0b6d-40b4-8685-3e7e9fc9b2c2
>          Total devices 1 FS bytes used 144.00KiB
>          devid    3 size 15.00GiB used 1.28GiB path /dev/loop3
>
> $ sudo btrfs filesystem resize -1G /mnt/1
> Resize device id 3 (/dev/loop3) from 15.00GiB to 14.00GiB
>
> $ sudo btrfs filesystem show /mnt/1/
> Label: none  uuid: cc6e1beb-255b-431f-baf5-02e8056fd0b6
> 	Total devices 1 FS bytes used 144.00KiB
> 	devid    3 size 14.00GiB used 1.28GiB path /dev/loop3
>
> Signed-off-by: Li Zhang <zhanglikernel@gmail.com>
> ---
>   cmds/filesystem.c | 47 ++++++++++++++++++++++++++++++++++++++++-------
>   1 file changed, 40 insertions(+), 7 deletions(-)
>
> diff --git a/cmds/filesystem.c b/cmds/filesystem.c
> index 7cd08fc..e641fcb 100644
> --- a/cmds/filesystem.c
> +++ b/cmds/filesystem.c
> @@ -1078,6 +1078,7 @@ static DEFINE_SIMPLE_COMMAND(filesystem_defrag, "defragment");
>   static const char * const cmd_filesystem_resize_usage[] = {
>   	"btrfs filesystem resize [options] [devid:][+/-]<newsize>[kKmMgGtTpPeE]|[devid:]max <path>",
>   	"Resize a filesystem",
> +	"If the filesystem contains only one device, devid can be ignored.",
>   	"If 'max' is passed, the filesystem will occupy all available space",
>   	"on the device 'devid'.",
>   	"[kK] means KiB, which denotes 1KiB = 1024B, 1MiB = 1024KiB, etc.",
> @@ -1087,7 +1088,8 @@ static const char * const cmd_filesystem_resize_usage[] = {
>   	NULL
>   };
>
> -static int check_resize_args(const char *amount, const char *path) {
> +static int check_resize_args(char * const amount, const char *path)
> +{
>   	struct btrfs_ioctl_fs_info_args fi_args;
>   	struct btrfs_ioctl_dev_info_args *di_args = NULL;
>   	int ret, i, dev_idx = -1;
> @@ -1112,11 +1114,14 @@ static int check_resize_args(const char *amount, const char *path) {
>   	}
>
>   	ret = snprintf(amount_dup, BTRFS_VOL_NAME_MAX, "%s", amount);
> +check:
>   	if (strlen(amount) != ret) {
>   		error("newsize argument is too long");
>   		ret = 1;
>   		goto out;
>   	}
> +	if (strcmp(amount, amount_dup) != 0)
> +		strcpy(amount, amount_dup);
>
>   	sizestr = amount_dup;
>   	devstr = strchr(sizestr, ':');
> @@ -1133,6 +1138,24 @@ static int check_resize_args(const char *amount, const char *path) {
>   			ret = 1;
>   			goto out;
>   		}
> +	} else if (fi_args.num_devices != 1) {
> +		error("The file system has multiple devices, please specify devid exactly.");
> +		error("The device information list is as follows.");
> +		for (i = 0; i < fi_args.num_devices; i++) {
> +			fprintf(stderr, "\tdevid %4llu size %s used %s path %s\n",
> +				di_args[i].devid,
> +				pretty_size_mode(di_args[i].total_bytes, UNITS_DEFAULT),
> +				pretty_size_mode(di_args[i].bytes_used, UNITS_DEFAULT),
> +				di_args[i].path);
> +		}
> +		ret = 1;
> +		goto out;
> +	} else {
> +		memset(amount_dup, 0, BTRFS_VOL_NAME_MAX);
> +		ret = snprintf(amount_dup, BTRFS_VOL_NAME_MAX, "%llu:", di_args[0].devid);
> +		ret = snprintf(amount_dup + strlen(amount_dup),
> +			BTRFS_VOL_NAME_MAX - strlen(amount_dup), "%s", amount);
> +		goto check;
>   	}
>
>   	dev_idx = -1;
> @@ -1200,10 +1223,11 @@ static int check_resize_args(const char *amount, const char *path) {
>   		di_args[dev_idx].path,
>   		pretty_size_mode(di_args[dev_idx].total_bytes, UNITS_DEFAULT),
>   		res_str);
> +	ret = 0;
>
>   out:
>   	free(di_args);
> -	return 0;
> +	return ret;
>   }
>
>   static int cmd_filesystem_resize(const struct cmd_struct *cmd,
> @@ -1213,7 +1237,7 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
>   	int	fd, res, len, e;
>   	char	*amount, *path;
>   	DIR	*dirstream = NULL;
> -	int ret;
> +	int ret = 0;
>   	bool enqueue = false;
>   	bool cancel = false;
>
> @@ -1277,10 +1301,17 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
>   		}
>   	}
>
> +	amount = (char *)malloc(BTRFS_VOL_NAME_MAX);
> +	if (!amount)
> +		return -ENOMEM;
> +
> +	strcpy(amount, argv[optind]);
> +
>   	ret = check_resize_args(amount, path);
>   	if (ret != 0) {
>   		close_file_or_dir(fd, dirstream);
> -		return 1;
> +		ret = 1;
> +		goto free_amount;
>   	}
>
>   	memset(&args, 0, sizeof(args));
> @@ -1298,7 +1329,7 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
>   			error("unable to resize '%s': %m", path);
>   			break;
>   		}
> -		return 1;
> +		ret = 1;
>   	} else if (res > 0) {
>   		const char *err_str = btrfs_err_str(res);
>
> @@ -1308,9 +1339,11 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
>   			error("resizing of '%s' failed: unknown error %d",
>   				path, res);
>   		}
> -		return 1;
> +		ret = 1;
>   	}
> -	return 0;
> +free_amount:
> +	free(amount);
> +	return ret;
>   }
>   static DEFINE_SIMPLE_COMMAND(filesystem_resize, "resize");
>
Li Zhang July 26, 2022, 1:38 a.m. UTC | #2
Sorry, I'm a little confused, does the SOB line mean the "--" line?

Thanks,
Li

Qu Wenruo <quwenruo.btrfs@gmx.com> 于2022年7月25日周一 08:34写道:
>
>
>
> On 2022/7/24 20:43, Li Zhang wrote:
> > related issuse:
> > https://github.com/kdave/btrfs-progs/issues/470
>
> Something I forgot to mention is related to the changelog part.
>
> This can be replaced by the following tag before SOB line:
>
> Issue: 470
>
> >
> > V1 link:
> > https://www.spinics.net/lists/linux-btrfs/msg126661.html
> >
> > V2 link:
> > https://www.spinics.net/lists/linux-btrfs/msg126853.html
>
> Changelog for single patch can be put after all the tags, and with a
> line of "---", so at apply time git will discard the extra info.
>
> One example can be found here:
>
> https://lore.kernel.org/linux-btrfs/20220617151133.GO20633@twin.jikos.cz/T/
>
> >
> > [BUG]
> > 1. If there is no devid=1, when the user uses the btrfs file system tool,
> > the following error will be reported,
> >
> > $ sudo btrfs filesystem show /mnt/1
> > Label: none  uuid: 64dc0f68-9afa-4465-9ea1-2bbebfdb6cec
> >      Total devices 2 FS bytes used 704.00KiB
> >      devid    2 size 15.00GiB used 1.16GiB path /dev/loop2
> >      devid    3 size 15.00GiB used 1.16GiB path /dev/loop3
> > $ sudo btrfs filesystem resize -1G /mnt/1
> > ERROR: cannot find devid: 1
> > ERROR: unable to resize '/mnt/1': No such device
> >
> > 2. Function check_resize_args, if get_fs_info is successful,
> > check_resize_args always returns 0, Even if the parameter
> > passed to kernel space is longer than the size allowed to
> > be passed to kernel space (BTRFS_VOL_NAME_MAX).
> >
> > [CAUSE]
> > 1. If the user does not specify the devid id explicitly,
> > btrfs will use the default devid 1, so it will report an error when dev 1 is missing.
> >
> > 2. The last line of the function check_resize_args is return 0.
> >
> > [FIX]
> > 1. If the file system contains multiple devices, output an error message to the user.
> > If the filesystem has only one device, resize should automatically add the unique devid.
> >
> > 2. The function check_resize_args should not return 0 on the last line,
> > it should return ret representing the return value.
> >
> > 3. Update the "btrfs-filesystem" man page
> >
> > [RESULT]
> >
> > $ sudo btrfs filesystem resize --help
> > usage: btrfs filesystem resize [options] [devid:][+/-]<newsize>[kKmMgGtTpPeE]|[devid:]max <path>
> >
> >      Resize a filesystem
> >
> >      If the filesystem contains only one device, devid can be ignored.
> >      If 'max' is passed, the filesystem will occupy all available space
> >      on the device 'devid'.
> >      [kK] means KiB, which denotes 1KiB = 1024B, 1MiB = 1024KiB, etc.
> >
> >      --enqueue         wait if there's another exclusive operation running,
> >                        otherwise continue
>
> Although help string is updated, the manpage is still not updated.
>
> Thanks,
> Qu
>
> >
> > $ sudo btrfs filesystem show /mnt/1/
> > Label: none  uuid: 2025e6ae-0b6d-40b4-8685-3e7e9fc9b2c2
> >          Total devices 2 FS bytes used 144.00KiB
> >          devid    2 size 15.00GiB used 1.16GiB path /dev/loop2
> >          devid    3 size 15.00GiB used 1.16GiB path /dev/loop3
> >
> > $ sudo btrfs filesystem resize -1G /mnt/1
> > ERROR: The file system has multiple devices, please specify devid exactly.
> > ERROR: The device information list is as follows.
> >          devid    2 size 15.00GiB used 1.16GiB path /dev/loop2
> >          devid    3 size 15.00GiB used 1.16GiB path /dev/loop3
> >
> > $ sudo btrfs device delete 2 /mnt/1/
> >
> > $ sudo btrfs filesystem show /mnt/1/
> > Label: none  uuid: 2025e6ae-0b6d-40b4-8685-3e7e9fc9b2c2
> >          Total devices 1 FS bytes used 144.00KiB
> >          devid    3 size 15.00GiB used 1.28GiB path /dev/loop3
> >
> > $ sudo btrfs filesystem resize -1G /mnt/1
> > Resize device id 3 (/dev/loop3) from 15.00GiB to 14.00GiB
> >
> > $ sudo btrfs filesystem show /mnt/1/
> > Label: none  uuid: cc6e1beb-255b-431f-baf5-02e8056fd0b6
> >       Total devices 1 FS bytes used 144.00KiB
> >       devid    3 size 14.00GiB used 1.28GiB path /dev/loop3
> >
> > Signed-off-by: Li Zhang <zhanglikernel@gmail.com>
> > ---
> >   cmds/filesystem.c | 47 ++++++++++++++++++++++++++++++++++++++++-------
> >   1 file changed, 40 insertions(+), 7 deletions(-)
> >
> > diff --git a/cmds/filesystem.c b/cmds/filesystem.c
> > index 7cd08fc..e641fcb 100644
> > --- a/cmds/filesystem.c
> > +++ b/cmds/filesystem.c
> > @@ -1078,6 +1078,7 @@ static DEFINE_SIMPLE_COMMAND(filesystem_defrag, "defragment");
> >   static const char * const cmd_filesystem_resize_usage[] = {
> >       "btrfs filesystem resize [options] [devid:][+/-]<newsize>[kKmMgGtTpPeE]|[devid:]max <path>",
> >       "Resize a filesystem",
> > +     "If the filesystem contains only one device, devid can be ignored.",
> >       "If 'max' is passed, the filesystem will occupy all available space",
> >       "on the device 'devid'.",
> >       "[kK] means KiB, which denotes 1KiB = 1024B, 1MiB = 1024KiB, etc.",
> > @@ -1087,7 +1088,8 @@ static const char * const cmd_filesystem_resize_usage[] = {
> >       NULL
> >   };
> >
> > -static int check_resize_args(const char *amount, const char *path) {
> > +static int check_resize_args(char * const amount, const char *path)
> > +{
> >       struct btrfs_ioctl_fs_info_args fi_args;
> >       struct btrfs_ioctl_dev_info_args *di_args = NULL;
> >       int ret, i, dev_idx = -1;
> > @@ -1112,11 +1114,14 @@ static int check_resize_args(const char *amount, const char *path) {
> >       }
> >
> >       ret = snprintf(amount_dup, BTRFS_VOL_NAME_MAX, "%s", amount);
> > +check:
> >       if (strlen(amount) != ret) {
> >               error("newsize argument is too long");
> >               ret = 1;
> >               goto out;
> >       }
> > +     if (strcmp(amount, amount_dup) != 0)
> > +             strcpy(amount, amount_dup);
> >
> >       sizestr = amount_dup;
> >       devstr = strchr(sizestr, ':');
> > @@ -1133,6 +1138,24 @@ static int check_resize_args(const char *amount, const char *path) {
> >                       ret = 1;
> >                       goto out;
> >               }
> > +     } else if (fi_args.num_devices != 1) {
> > +             error("The file system has multiple devices, please specify devid exactly.");
> > +             error("The device information list is as follows.");
> > +             for (i = 0; i < fi_args.num_devices; i++) {
> > +                     fprintf(stderr, "\tdevid %4llu size %s used %s path %s\n",
> > +                             di_args[i].devid,
> > +                             pretty_size_mode(di_args[i].total_bytes, UNITS_DEFAULT),
> > +                             pretty_size_mode(di_args[i].bytes_used, UNITS_DEFAULT),
> > +                             di_args[i].path);
> > +             }
> > +             ret = 1;
> > +             goto out;
> > +     } else {
> > +             memset(amount_dup, 0, BTRFS_VOL_NAME_MAX);
> > +             ret = snprintf(amount_dup, BTRFS_VOL_NAME_MAX, "%llu:", di_args[0].devid);
> > +             ret = snprintf(amount_dup + strlen(amount_dup),
> > +                     BTRFS_VOL_NAME_MAX - strlen(amount_dup), "%s", amount);
> > +             goto check;
> >       }
> >
> >       dev_idx = -1;
> > @@ -1200,10 +1223,11 @@ static int check_resize_args(const char *amount, const char *path) {
> >               di_args[dev_idx].path,
> >               pretty_size_mode(di_args[dev_idx].total_bytes, UNITS_DEFAULT),
> >               res_str);
> > +     ret = 0;
> >
> >   out:
> >       free(di_args);
> > -     return 0;
> > +     return ret;
> >   }
> >
> >   static int cmd_filesystem_resize(const struct cmd_struct *cmd,
> > @@ -1213,7 +1237,7 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
> >       int     fd, res, len, e;
> >       char    *amount, *path;
> >       DIR     *dirstream = NULL;
> > -     int ret;
> > +     int ret = 0;
> >       bool enqueue = false;
> >       bool cancel = false;
> >
> > @@ -1277,10 +1301,17 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
> >               }
> >       }
> >
> > +     amount = (char *)malloc(BTRFS_VOL_NAME_MAX);
> > +     if (!amount)
> > +             return -ENOMEM;
> > +
> > +     strcpy(amount, argv[optind]);
> > +
> >       ret = check_resize_args(amount, path);
> >       if (ret != 0) {
> >               close_file_or_dir(fd, dirstream);
> > -             return 1;
> > +             ret = 1;
> > +             goto free_amount;
> >       }
> >
> >       memset(&args, 0, sizeof(args));
> > @@ -1298,7 +1329,7 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
> >                       error("unable to resize '%s': %m", path);
> >                       break;
> >               }
> > -             return 1;
> > +             ret = 1;
> >       } else if (res > 0) {
> >               const char *err_str = btrfs_err_str(res);
> >
> > @@ -1308,9 +1339,11 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
> >                       error("resizing of '%s' failed: unknown error %d",
> >                               path, res);
> >               }
> > -             return 1;
> > +             ret = 1;
> >       }
> > -     return 0;
> > +free_amount:
> > +     free(amount);
> > +     return ret;
> >   }
> >   static DEFINE_SIMPLE_COMMAND(filesystem_resize, "resize");
> >
Qu Wenruo July 26, 2022, 2:08 a.m. UTC | #3
On 2022/7/26 09:38, li zhang wrote:
> Sorry, I'm a little confused, does the SOB line mean the "--" line?

SOB = Signed-of-by line.

The correct example for that tag for btrfs-progs can be found here:

https://lore.kernel.org/linux-btrfs/20220114005123.19426-4-wqu@suse.com/

Thanks,
Qu

>
> Thanks,
> Li
>
> Qu Wenruo <quwenruo.btrfs@gmx.com> 于2022年7月25日周一 08:34写道:
>>
>>
>>
>> On 2022/7/24 20:43, Li Zhang wrote:
>>> related issuse:
>>> https://github.com/kdave/btrfs-progs/issues/470
>>
>> Something I forgot to mention is related to the changelog part.
>>
>> This can be replaced by the following tag before SOB line:
>>
>> Issue: 470
>>
>>>
>>> V1 link:
>>> https://www.spinics.net/lists/linux-btrfs/msg126661.html
>>>
>>> V2 link:
>>> https://www.spinics.net/lists/linux-btrfs/msg126853.html
>>
>> Changelog for single patch can be put after all the tags, and with a
>> line of "---", so at apply time git will discard the extra info.
>>
>> One example can be found here:
>>
>> https://lore.kernel.org/linux-btrfs/20220617151133.GO20633@twin.jikos.cz/T/
>>
>>>
>>> [BUG]
>>> 1. If there is no devid=1, when the user uses the btrfs file system tool,
>>> the following error will be reported,
>>>
>>> $ sudo btrfs filesystem show /mnt/1
>>> Label: none  uuid: 64dc0f68-9afa-4465-9ea1-2bbebfdb6cec
>>>       Total devices 2 FS bytes used 704.00KiB
>>>       devid    2 size 15.00GiB used 1.16GiB path /dev/loop2
>>>       devid    3 size 15.00GiB used 1.16GiB path /dev/loop3
>>> $ sudo btrfs filesystem resize -1G /mnt/1
>>> ERROR: cannot find devid: 1
>>> ERROR: unable to resize '/mnt/1': No such device
>>>
>>> 2. Function check_resize_args, if get_fs_info is successful,
>>> check_resize_args always returns 0, Even if the parameter
>>> passed to kernel space is longer than the size allowed to
>>> be passed to kernel space (BTRFS_VOL_NAME_MAX).
>>>
>>> [CAUSE]
>>> 1. If the user does not specify the devid id explicitly,
>>> btrfs will use the default devid 1, so it will report an error when dev 1 is missing.
>>>
>>> 2. The last line of the function check_resize_args is return 0.
>>>
>>> [FIX]
>>> 1. If the file system contains multiple devices, output an error message to the user.
>>> If the filesystem has only one device, resize should automatically add the unique devid.
>>>
>>> 2. The function check_resize_args should not return 0 on the last line,
>>> it should return ret representing the return value.
>>>
>>> 3. Update the "btrfs-filesystem" man page
>>>
>>> [RESULT]
>>>
>>> $ sudo btrfs filesystem resize --help
>>> usage: btrfs filesystem resize [options] [devid:][+/-]<newsize>[kKmMgGtTpPeE]|[devid:]max <path>
>>>
>>>       Resize a filesystem
>>>
>>>       If the filesystem contains only one device, devid can be ignored.
>>>       If 'max' is passed, the filesystem will occupy all available space
>>>       on the device 'devid'.
>>>       [kK] means KiB, which denotes 1KiB = 1024B, 1MiB = 1024KiB, etc.
>>>
>>>       --enqueue         wait if there's another exclusive operation running,
>>>                         otherwise continue
>>
>> Although help string is updated, the manpage is still not updated.
>>
>> Thanks,
>> Qu
>>
>>>
>>> $ sudo btrfs filesystem show /mnt/1/
>>> Label: none  uuid: 2025e6ae-0b6d-40b4-8685-3e7e9fc9b2c2
>>>           Total devices 2 FS bytes used 144.00KiB
>>>           devid    2 size 15.00GiB used 1.16GiB path /dev/loop2
>>>           devid    3 size 15.00GiB used 1.16GiB path /dev/loop3
>>>
>>> $ sudo btrfs filesystem resize -1G /mnt/1
>>> ERROR: The file system has multiple devices, please specify devid exactly.
>>> ERROR: The device information list is as follows.
>>>           devid    2 size 15.00GiB used 1.16GiB path /dev/loop2
>>>           devid    3 size 15.00GiB used 1.16GiB path /dev/loop3
>>>
>>> $ sudo btrfs device delete 2 /mnt/1/
>>>
>>> $ sudo btrfs filesystem show /mnt/1/
>>> Label: none  uuid: 2025e6ae-0b6d-40b4-8685-3e7e9fc9b2c2
>>>           Total devices 1 FS bytes used 144.00KiB
>>>           devid    3 size 15.00GiB used 1.28GiB path /dev/loop3
>>>
>>> $ sudo btrfs filesystem resize -1G /mnt/1
>>> Resize device id 3 (/dev/loop3) from 15.00GiB to 14.00GiB
>>>
>>> $ sudo btrfs filesystem show /mnt/1/
>>> Label: none  uuid: cc6e1beb-255b-431f-baf5-02e8056fd0b6
>>>        Total devices 1 FS bytes used 144.00KiB
>>>        devid    3 size 14.00GiB used 1.28GiB path /dev/loop3
>>>
>>> Signed-off-by: Li Zhang <zhanglikernel@gmail.com>
>>> ---
>>>    cmds/filesystem.c | 47 ++++++++++++++++++++++++++++++++++++++++-------
>>>    1 file changed, 40 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/cmds/filesystem.c b/cmds/filesystem.c
>>> index 7cd08fc..e641fcb 100644
>>> --- a/cmds/filesystem.c
>>> +++ b/cmds/filesystem.c
>>> @@ -1078,6 +1078,7 @@ static DEFINE_SIMPLE_COMMAND(filesystem_defrag, "defragment");
>>>    static const char * const cmd_filesystem_resize_usage[] = {
>>>        "btrfs filesystem resize [options] [devid:][+/-]<newsize>[kKmMgGtTpPeE]|[devid:]max <path>",
>>>        "Resize a filesystem",
>>> +     "If the filesystem contains only one device, devid can be ignored.",
>>>        "If 'max' is passed, the filesystem will occupy all available space",
>>>        "on the device 'devid'.",
>>>        "[kK] means KiB, which denotes 1KiB = 1024B, 1MiB = 1024KiB, etc.",
>>> @@ -1087,7 +1088,8 @@ static const char * const cmd_filesystem_resize_usage[] = {
>>>        NULL
>>>    };
>>>
>>> -static int check_resize_args(const char *amount, const char *path) {
>>> +static int check_resize_args(char * const amount, const char *path)
>>> +{
>>>        struct btrfs_ioctl_fs_info_args fi_args;
>>>        struct btrfs_ioctl_dev_info_args *di_args = NULL;
>>>        int ret, i, dev_idx = -1;
>>> @@ -1112,11 +1114,14 @@ static int check_resize_args(const char *amount, const char *path) {
>>>        }
>>>
>>>        ret = snprintf(amount_dup, BTRFS_VOL_NAME_MAX, "%s", amount);
>>> +check:
>>>        if (strlen(amount) != ret) {
>>>                error("newsize argument is too long");
>>>                ret = 1;
>>>                goto out;
>>>        }
>>> +     if (strcmp(amount, amount_dup) != 0)
>>> +             strcpy(amount, amount_dup);
>>>
>>>        sizestr = amount_dup;
>>>        devstr = strchr(sizestr, ':');
>>> @@ -1133,6 +1138,24 @@ static int check_resize_args(const char *amount, const char *path) {
>>>                        ret = 1;
>>>                        goto out;
>>>                }
>>> +     } else if (fi_args.num_devices != 1) {
>>> +             error("The file system has multiple devices, please specify devid exactly.");
>>> +             error("The device information list is as follows.");
>>> +             for (i = 0; i < fi_args.num_devices; i++) {
>>> +                     fprintf(stderr, "\tdevid %4llu size %s used %s path %s\n",
>>> +                             di_args[i].devid,
>>> +                             pretty_size_mode(di_args[i].total_bytes, UNITS_DEFAULT),
>>> +                             pretty_size_mode(di_args[i].bytes_used, UNITS_DEFAULT),
>>> +                             di_args[i].path);
>>> +             }
>>> +             ret = 1;
>>> +             goto out;
>>> +     } else {
>>> +             memset(amount_dup, 0, BTRFS_VOL_NAME_MAX);
>>> +             ret = snprintf(amount_dup, BTRFS_VOL_NAME_MAX, "%llu:", di_args[0].devid);
>>> +             ret = snprintf(amount_dup + strlen(amount_dup),
>>> +                     BTRFS_VOL_NAME_MAX - strlen(amount_dup), "%s", amount);
>>> +             goto check;
>>>        }
>>>
>>>        dev_idx = -1;
>>> @@ -1200,10 +1223,11 @@ static int check_resize_args(const char *amount, const char *path) {
>>>                di_args[dev_idx].path,
>>>                pretty_size_mode(di_args[dev_idx].total_bytes, UNITS_DEFAULT),
>>>                res_str);
>>> +     ret = 0;
>>>
>>>    out:
>>>        free(di_args);
>>> -     return 0;
>>> +     return ret;
>>>    }
>>>
>>>    static int cmd_filesystem_resize(const struct cmd_struct *cmd,
>>> @@ -1213,7 +1237,7 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
>>>        int     fd, res, len, e;
>>>        char    *amount, *path;
>>>        DIR     *dirstream = NULL;
>>> -     int ret;
>>> +     int ret = 0;
>>>        bool enqueue = false;
>>>        bool cancel = false;
>>>
>>> @@ -1277,10 +1301,17 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
>>>                }
>>>        }
>>>
>>> +     amount = (char *)malloc(BTRFS_VOL_NAME_MAX);
>>> +     if (!amount)
>>> +             return -ENOMEM;
>>> +
>>> +     strcpy(amount, argv[optind]);
>>> +
>>>        ret = check_resize_args(amount, path);
>>>        if (ret != 0) {
>>>                close_file_or_dir(fd, dirstream);
>>> -             return 1;
>>> +             ret = 1;
>>> +             goto free_amount;
>>>        }
>>>
>>>        memset(&args, 0, sizeof(args));
>>> @@ -1298,7 +1329,7 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
>>>                        error("unable to resize '%s': %m", path);
>>>                        break;
>>>                }
>>> -             return 1;
>>> +             ret = 1;
>>>        } else if (res > 0) {
>>>                const char *err_str = btrfs_err_str(res);
>>>
>>> @@ -1308,9 +1339,11 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
>>>                        error("resizing of '%s' failed: unknown error %d",
>>>                                path, res);
>>>                }
>>> -             return 1;
>>> +             ret = 1;
>>>        }
>>> -     return 0;
>>> +free_amount:
>>> +     free(amount);
>>> +     return ret;
>>>    }
>>>    static DEFINE_SIMPLE_COMMAND(filesystem_resize, "resize");
>>>
Li Zhang July 26, 2022, 2:29 a.m. UTC | #4
Got it, thanks!

Qu Wenruo <quwenruo.btrfs@gmx.com> 于2022年7月26日周二 10:08写道:
>
>
>
> On 2022/7/26 09:38, li zhang wrote:
> > Sorry, I'm a little confused, does the SOB line mean the "--" line?
>
> SOB = Signed-of-by line.
>
> The correct example for that tag for btrfs-progs can be found here:
>
> https://lore.kernel.org/linux-btrfs/20220114005123.19426-4-wqu@suse.com/
>
> Thanks,
> Qu
>
> >
> > Thanks,
> > Li
> >
> > Qu Wenruo <quwenruo.btrfs@gmx.com> 于2022年7月25日周一 08:34写道:
> >>
> >>
> >>
> >> On 2022/7/24 20:43, Li Zhang wrote:
> >>> related issuse:
> >>> https://github.com/kdave/btrfs-progs/issues/470
> >>
> >> Something I forgot to mention is related to the changelog part.
> >>
> >> This can be replaced by the following tag before SOB line:
> >>
> >> Issue: 470
> >>
> >>>
> >>> V1 link:
> >>> https://www.spinics.net/lists/linux-btrfs/msg126661.html
> >>>
> >>> V2 link:
> >>> https://www.spinics.net/lists/linux-btrfs/msg126853.html
> >>
> >> Changelog for single patch can be put after all the tags, and with a
> >> line of "---", so at apply time git will discard the extra info.
> >>
> >> One example can be found here:
> >>
> >> https://lore.kernel.org/linux-btrfs/20220617151133.GO20633@twin.jikos.cz/T/
> >>
> >>>
> >>> [BUG]
> >>> 1. If there is no devid=1, when the user uses the btrfs file system tool,
> >>> the following error will be reported,
> >>>
> >>> $ sudo btrfs filesystem show /mnt/1
> >>> Label: none  uuid: 64dc0f68-9afa-4465-9ea1-2bbebfdb6cec
> >>>       Total devices 2 FS bytes used 704.00KiB
> >>>       devid    2 size 15.00GiB used 1.16GiB path /dev/loop2
> >>>       devid    3 size 15.00GiB used 1.16GiB path /dev/loop3
> >>> $ sudo btrfs filesystem resize -1G /mnt/1
> >>> ERROR: cannot find devid: 1
> >>> ERROR: unable to resize '/mnt/1': No such device
> >>>
> >>> 2. Function check_resize_args, if get_fs_info is successful,
> >>> check_resize_args always returns 0, Even if the parameter
> >>> passed to kernel space is longer than the size allowed to
> >>> be passed to kernel space (BTRFS_VOL_NAME_MAX).
> >>>
> >>> [CAUSE]
> >>> 1. If the user does not specify the devid id explicitly,
> >>> btrfs will use the default devid 1, so it will report an error when dev 1 is missing.
> >>>
> >>> 2. The last line of the function check_resize_args is return 0.
> >>>
> >>> [FIX]
> >>> 1. If the file system contains multiple devices, output an error message to the user.
> >>> If the filesystem has only one device, resize should automatically add the unique devid.
> >>>
> >>> 2. The function check_resize_args should not return 0 on the last line,
> >>> it should return ret representing the return value.
> >>>
> >>> 3. Update the "btrfs-filesystem" man page
> >>>
> >>> [RESULT]
> >>>
> >>> $ sudo btrfs filesystem resize --help
> >>> usage: btrfs filesystem resize [options] [devid:][+/-]<newsize>[kKmMgGtTpPeE]|[devid:]max <path>
> >>>
> >>>       Resize a filesystem
> >>>
> >>>       If the filesystem contains only one device, devid can be ignored.
> >>>       If 'max' is passed, the filesystem will occupy all available space
> >>>       on the device 'devid'.
> >>>       [kK] means KiB, which denotes 1KiB = 1024B, 1MiB = 1024KiB, etc.
> >>>
> >>>       --enqueue         wait if there's another exclusive operation running,
> >>>                         otherwise continue
> >>
> >> Although help string is updated, the manpage is still not updated.
> >>
> >> Thanks,
> >> Qu
> >>
> >>>
> >>> $ sudo btrfs filesystem show /mnt/1/
> >>> Label: none  uuid: 2025e6ae-0b6d-40b4-8685-3e7e9fc9b2c2
> >>>           Total devices 2 FS bytes used 144.00KiB
> >>>           devid    2 size 15.00GiB used 1.16GiB path /dev/loop2
> >>>           devid    3 size 15.00GiB used 1.16GiB path /dev/loop3
> >>>
> >>> $ sudo btrfs filesystem resize -1G /mnt/1
> >>> ERROR: The file system has multiple devices, please specify devid exactly.
> >>> ERROR: The device information list is as follows.
> >>>           devid    2 size 15.00GiB used 1.16GiB path /dev/loop2
> >>>           devid    3 size 15.00GiB used 1.16GiB path /dev/loop3
> >>>
> >>> $ sudo btrfs device delete 2 /mnt/1/
> >>>
> >>> $ sudo btrfs filesystem show /mnt/1/
> >>> Label: none  uuid: 2025e6ae-0b6d-40b4-8685-3e7e9fc9b2c2
> >>>           Total devices 1 FS bytes used 144.00KiB
> >>>           devid    3 size 15.00GiB used 1.28GiB path /dev/loop3
> >>>
> >>> $ sudo btrfs filesystem resize -1G /mnt/1
> >>> Resize device id 3 (/dev/loop3) from 15.00GiB to 14.00GiB
> >>>
> >>> $ sudo btrfs filesystem show /mnt/1/
> >>> Label: none  uuid: cc6e1beb-255b-431f-baf5-02e8056fd0b6
> >>>        Total devices 1 FS bytes used 144.00KiB
> >>>        devid    3 size 14.00GiB used 1.28GiB path /dev/loop3
> >>>
> >>> Signed-off-by: Li Zhang <zhanglikernel@gmail.com>
> >>> ---
> >>>    cmds/filesystem.c | 47 ++++++++++++++++++++++++++++++++++++++++-------
> >>>    1 file changed, 40 insertions(+), 7 deletions(-)
> >>>
> >>> diff --git a/cmds/filesystem.c b/cmds/filesystem.c
> >>> index 7cd08fc..e641fcb 100644
> >>> --- a/cmds/filesystem.c
> >>> +++ b/cmds/filesystem.c
> >>> @@ -1078,6 +1078,7 @@ static DEFINE_SIMPLE_COMMAND(filesystem_defrag, "defragment");
> >>>    static const char * const cmd_filesystem_resize_usage[] = {
> >>>        "btrfs filesystem resize [options] [devid:][+/-]<newsize>[kKmMgGtTpPeE]|[devid:]max <path>",
> >>>        "Resize a filesystem",
> >>> +     "If the filesystem contains only one device, devid can be ignored.",
> >>>        "If 'max' is passed, the filesystem will occupy all available space",
> >>>        "on the device 'devid'.",
> >>>        "[kK] means KiB, which denotes 1KiB = 1024B, 1MiB = 1024KiB, etc.",
> >>> @@ -1087,7 +1088,8 @@ static const char * const cmd_filesystem_resize_usage[] = {
> >>>        NULL
> >>>    };
> >>>
> >>> -static int check_resize_args(const char *amount, const char *path) {
> >>> +static int check_resize_args(char * const amount, const char *path)
> >>> +{
> >>>        struct btrfs_ioctl_fs_info_args fi_args;
> >>>        struct btrfs_ioctl_dev_info_args *di_args = NULL;
> >>>        int ret, i, dev_idx = -1;
> >>> @@ -1112,11 +1114,14 @@ static int check_resize_args(const char *amount, const char *path) {
> >>>        }
> >>>
> >>>        ret = snprintf(amount_dup, BTRFS_VOL_NAME_MAX, "%s", amount);
> >>> +check:
> >>>        if (strlen(amount) != ret) {
> >>>                error("newsize argument is too long");
> >>>                ret = 1;
> >>>                goto out;
> >>>        }
> >>> +     if (strcmp(amount, amount_dup) != 0)
> >>> +             strcpy(amount, amount_dup);
> >>>
> >>>        sizestr = amount_dup;
> >>>        devstr = strchr(sizestr, ':');
> >>> @@ -1133,6 +1138,24 @@ static int check_resize_args(const char *amount, const char *path) {
> >>>                        ret = 1;
> >>>                        goto out;
> >>>                }
> >>> +     } else if (fi_args.num_devices != 1) {
> >>> +             error("The file system has multiple devices, please specify devid exactly.");
> >>> +             error("The device information list is as follows.");
> >>> +             for (i = 0; i < fi_args.num_devices; i++) {
> >>> +                     fprintf(stderr, "\tdevid %4llu size %s used %s path %s\n",
> >>> +                             di_args[i].devid,
> >>> +                             pretty_size_mode(di_args[i].total_bytes, UNITS_DEFAULT),
> >>> +                             pretty_size_mode(di_args[i].bytes_used, UNITS_DEFAULT),
> >>> +                             di_args[i].path);
> >>> +             }
> >>> +             ret = 1;
> >>> +             goto out;
> >>> +     } else {
> >>> +             memset(amount_dup, 0, BTRFS_VOL_NAME_MAX);
> >>> +             ret = snprintf(amount_dup, BTRFS_VOL_NAME_MAX, "%llu:", di_args[0].devid);
> >>> +             ret = snprintf(amount_dup + strlen(amount_dup),
> >>> +                     BTRFS_VOL_NAME_MAX - strlen(amount_dup), "%s", amount);
> >>> +             goto check;
> >>>        }
> >>>
> >>>        dev_idx = -1;
> >>> @@ -1200,10 +1223,11 @@ static int check_resize_args(const char *amount, const char *path) {
> >>>                di_args[dev_idx].path,
> >>>                pretty_size_mode(di_args[dev_idx].total_bytes, UNITS_DEFAULT),
> >>>                res_str);
> >>> +     ret = 0;
> >>>
> >>>    out:
> >>>        free(di_args);
> >>> -     return 0;
> >>> +     return ret;
> >>>    }
> >>>
> >>>    static int cmd_filesystem_resize(const struct cmd_struct *cmd,
> >>> @@ -1213,7 +1237,7 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
> >>>        int     fd, res, len, e;
> >>>        char    *amount, *path;
> >>>        DIR     *dirstream = NULL;
> >>> -     int ret;
> >>> +     int ret = 0;
> >>>        bool enqueue = false;
> >>>        bool cancel = false;
> >>>
> >>> @@ -1277,10 +1301,17 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
> >>>                }
> >>>        }
> >>>
> >>> +     amount = (char *)malloc(BTRFS_VOL_NAME_MAX);
> >>> +     if (!amount)
> >>> +             return -ENOMEM;
> >>> +
> >>> +     strcpy(amount, argv[optind]);
> >>> +
> >>>        ret = check_resize_args(amount, path);
> >>>        if (ret != 0) {
> >>>                close_file_or_dir(fd, dirstream);
> >>> -             return 1;
> >>> +             ret = 1;
> >>> +             goto free_amount;
> >>>        }
> >>>
> >>>        memset(&args, 0, sizeof(args));
> >>> @@ -1298,7 +1329,7 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
> >>>                        error("unable to resize '%s': %m", path);
> >>>                        break;
> >>>                }
> >>> -             return 1;
> >>> +             ret = 1;
> >>>        } else if (res > 0) {
> >>>                const char *err_str = btrfs_err_str(res);
> >>>
> >>> @@ -1308,9 +1339,11 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
> >>>                        error("resizing of '%s' failed: unknown error %d",
> >>>                                path, res);
> >>>                }
> >>> -             return 1;
> >>> +             ret = 1;
> >>>        }
> >>> -     return 0;
> >>> +free_amount:
> >>> +     free(amount);
> >>> +     return ret;
> >>>    }
> >>>    static DEFINE_SIMPLE_COMMAND(filesystem_resize, "resize");
> >>>
diff mbox series

Patch

diff --git a/cmds/filesystem.c b/cmds/filesystem.c
index 7cd08fc..e641fcb 100644
--- a/cmds/filesystem.c
+++ b/cmds/filesystem.c
@@ -1078,6 +1078,7 @@  static DEFINE_SIMPLE_COMMAND(filesystem_defrag, "defragment");
 static const char * const cmd_filesystem_resize_usage[] = {
 	"btrfs filesystem resize [options] [devid:][+/-]<newsize>[kKmMgGtTpPeE]|[devid:]max <path>",
 	"Resize a filesystem",
+	"If the filesystem contains only one device, devid can be ignored.",
 	"If 'max' is passed, the filesystem will occupy all available space",
 	"on the device 'devid'.",
 	"[kK] means KiB, which denotes 1KiB = 1024B, 1MiB = 1024KiB, etc.",
@@ -1087,7 +1088,8 @@  static const char * const cmd_filesystem_resize_usage[] = {
 	NULL
 };
 
-static int check_resize_args(const char *amount, const char *path) {
+static int check_resize_args(char * const amount, const char *path)
+{
 	struct btrfs_ioctl_fs_info_args fi_args;
 	struct btrfs_ioctl_dev_info_args *di_args = NULL;
 	int ret, i, dev_idx = -1;
@@ -1112,11 +1114,14 @@  static int check_resize_args(const char *amount, const char *path) {
 	}
 
 	ret = snprintf(amount_dup, BTRFS_VOL_NAME_MAX, "%s", amount);
+check:
 	if (strlen(amount) != ret) {
 		error("newsize argument is too long");
 		ret = 1;
 		goto out;
 	}
+	if (strcmp(amount, amount_dup) != 0)
+		strcpy(amount, amount_dup);
 
 	sizestr = amount_dup;
 	devstr = strchr(sizestr, ':');
@@ -1133,6 +1138,24 @@  static int check_resize_args(const char *amount, const char *path) {
 			ret = 1;
 			goto out;
 		}
+	} else if (fi_args.num_devices != 1) {
+		error("The file system has multiple devices, please specify devid exactly.");
+		error("The device information list is as follows.");
+		for (i = 0; i < fi_args.num_devices; i++) {
+			fprintf(stderr, "\tdevid %4llu size %s used %s path %s\n",
+				di_args[i].devid,
+				pretty_size_mode(di_args[i].total_bytes, UNITS_DEFAULT),
+				pretty_size_mode(di_args[i].bytes_used, UNITS_DEFAULT),
+				di_args[i].path);
+		}
+		ret = 1;
+		goto out;
+	} else {
+		memset(amount_dup, 0, BTRFS_VOL_NAME_MAX);
+		ret = snprintf(amount_dup, BTRFS_VOL_NAME_MAX, "%llu:", di_args[0].devid);
+		ret = snprintf(amount_dup + strlen(amount_dup),
+			BTRFS_VOL_NAME_MAX - strlen(amount_dup), "%s", amount);
+		goto check;
 	}
 
 	dev_idx = -1;
@@ -1200,10 +1223,11 @@  static int check_resize_args(const char *amount, const char *path) {
 		di_args[dev_idx].path,
 		pretty_size_mode(di_args[dev_idx].total_bytes, UNITS_DEFAULT),
 		res_str);
+	ret = 0;
 
 out:
 	free(di_args);
-	return 0;
+	return ret;
 }
 
 static int cmd_filesystem_resize(const struct cmd_struct *cmd,
@@ -1213,7 +1237,7 @@  static int cmd_filesystem_resize(const struct cmd_struct *cmd,
 	int	fd, res, len, e;
 	char	*amount, *path;
 	DIR	*dirstream = NULL;
-	int ret;
+	int ret = 0;
 	bool enqueue = false;
 	bool cancel = false;
 
@@ -1277,10 +1301,17 @@  static int cmd_filesystem_resize(const struct cmd_struct *cmd,
 		}
 	}
 
+	amount = (char *)malloc(BTRFS_VOL_NAME_MAX);
+	if (!amount)
+		return -ENOMEM;
+
+	strcpy(amount, argv[optind]);
+
 	ret = check_resize_args(amount, path);
 	if (ret != 0) {
 		close_file_or_dir(fd, dirstream);
-		return 1;
+		ret = 1;
+		goto free_amount;
 	}
 
 	memset(&args, 0, sizeof(args));
@@ -1298,7 +1329,7 @@  static int cmd_filesystem_resize(const struct cmd_struct *cmd,
 			error("unable to resize '%s': %m", path);
 			break;
 		}
-		return 1;
+		ret = 1;
 	} else if (res > 0) {
 		const char *err_str = btrfs_err_str(res);
 
@@ -1308,9 +1339,11 @@  static int cmd_filesystem_resize(const struct cmd_struct *cmd,
 			error("resizing of '%s' failed: unknown error %d",
 				path, res);
 		}
-		return 1;
+		ret = 1;
 	}
-	return 0;
+free_amount:
+	free(amount);
+	return ret;
 }
 static DEFINE_SIMPLE_COMMAND(filesystem_resize, "resize");