All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sidong Yang <realwakka@gmail.com>
To: linux-btrfs@vger.kernel.org
Cc: Sidong Yang <realwakka@gmail.com>
Subject: [RFC PATCH 1/2] btrfs-progs: fi resize: refactor function check_resize_args()
Date: Mon, 15 Aug 2022 12:36:51 +0000	[thread overview]
Message-ID: <20220815123652.52314-2-realwakka@gmail.com> (raw)
In-Reply-To: <20220815123652.52314-1-realwakka@gmail.com>

This patch removes check_resize_args() and makes resize_with_args() for
supporting "all" option for resize function. The old code checks user
arguments and execute resizing with ioctl call. For new option, we
need to check user arguments and make new arguments if it needs multiple
ioctl calls. So it needs a function that checks argument and resize at
once. In a new function resize_with_args(), we will need to check each
sizestr for each device in "all" option. This patch also make
check_resize_args_sizestr() for checking sizestr.

Signed-off-by: Sidong Yang <realwakka@gmail.com>
---
 cmds/filesystem.c | 177 ++++++++++++++++++++++++----------------------
 1 file changed, 94 insertions(+), 83 deletions(-)

diff --git a/cmds/filesystem.c b/cmds/filesystem.c
index 7cd08fcd..ea1b0c84 100644
--- a/cmds/filesystem.c
+++ b/cmds/filesystem.c
@@ -1087,17 +1087,77 @@ 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_sizestr(const char *sizestr, u64 devid, int dev_idx,
+									 struct btrfs_ioctl_dev_info_args *di_args,
+									 struct btrfs_ioctl_fs_info_args *fi_args) {
+	const char *res_str;
+	int ret;
+
+	if (strcmp(sizestr, "max") == 0) {
+		res_str = "max";
+	} else if (strcmp(sizestr, "cancel") == 0) {
+		/* Different format, print and exit */
+		printf("Request to cancel resize\n");
+		ret = 0;
+	} else {
+		int mod = 0;
+		u64 diff = 0, old_size = 0, new_size = 0;
+		if (sizestr[0] == '-') {
+			mod = -1;
+			sizestr++;
+		} else if (sizestr[0] == '+') {
+			mod = 1;
+			sizestr++;
+		}
+		diff = parse_size_from_string(sizestr);
+		if (!diff) {
+			error("failed to parse size %s", sizestr);
+			ret = 1;
+			goto out;
+		}
+		old_size = di_args[dev_idx].total_bytes;
+
+		/* For target sizes without +/- sign prefix (e.g. 1:150g) */
+		if (mod == 0) {
+			new_size = diff;
+		} else if (mod < 0) {
+			if (diff > old_size) {
+				error("current size is %s which is smaller than %s",
+				      pretty_size_mode(old_size, UNITS_DEFAULT),
+				      pretty_size_mode(diff, UNITS_DEFAULT));
+				ret = 1;
+				goto out;
+			}
+			new_size = old_size - diff;
+		} else if (mod > 0) {
+			if (diff > ULLONG_MAX - old_size) {
+				error("increasing %s is out of range",
+				      pretty_size_mode(diff, UNITS_DEFAULT));
+				ret = 1;
+				goto out;
+			}
+			new_size = old_size + diff;
+		}
+		new_size = round_down(new_size, fi_args->sectorsize);
+		res_str = pretty_size_mode(new_size, UNITS_DEFAULT);
+	}
+
+	printf("Resize device id %lld (%s) from %s to %s\n", devid,
+		di_args[dev_idx].path,
+		pretty_size_mode(di_args[dev_idx].total_bytes, UNITS_DEFAULT),
+		res_str);
+out:
+	return ret;
+}
+
+static int resize_with_args(const char *amount, const char *path, int fd) {
 	struct btrfs_ioctl_fs_info_args fi_args;
 	struct btrfs_ioctl_dev_info_args *di_args = NULL;
-	int ret, i, dev_idx = -1;
+	int ret, i, e, dev_idx = -1;
 	u64 devid = 1;
-	const char *res_str = NULL;
 	char *devstr = NULL, *sizestr = NULL;
-	u64 new_size = 0, old_size = 0, diff = 0;
-	int mod = 0;
 	char amount_dup[BTRFS_VOL_NAME_MAX];
-
+	struct btrfs_ioctl_vol_args	args;
 	ret = get_fs_info(path, &fi_args, &di_args);
 
 	if (ret) {
@@ -1149,58 +1209,37 @@ static int check_resize_args(const char *amount, const char *path) {
 		goto out;
 	}
 
-	if (strcmp(sizestr, "max") == 0) {
-		res_str = "max";
-	} else if (strcmp(sizestr, "cancel") == 0) {
-		/* Different format, print and exit */
-		printf("Request to cancel resize\n");
-		goto out;
-	} else {
-		if (sizestr[0] == '-') {
-			mod = -1;
-			sizestr++;
-		} else if (sizestr[0] == '+') {
-			mod = 1;
-			sizestr++;
-		}
-		diff = parse_size_from_string(sizestr);
-		if (!diff) {
-			error("failed to parse size %s", sizestr);
-			ret = 1;
-			goto out;
+	ret = check_resize_args_sizestr(sizestr, devid, dev_idx, di_args, &fi_args);
+	if (ret)
+		return 1;
+
+	memset(&args, 0, sizeof(args));
+	strncpy_null(args.name, amount);
+	ret = ioctl(fd, BTRFS_IOC_RESIZE, &args);
+	e = errno;
+	if(ret < 0){
+		switch (e) {
+		case EFBIG:
+			error("unable to resize '%s': no enough free space",
+				  path);
+			break;
+		default:
+			error("unable to resize '%s': %m", path);
+			break;
 		}
-		old_size = di_args[dev_idx].total_bytes;
+		return 1;
+	} else if (ret > 0) {
+		const char *err_str = btrfs_err_str(ret);
 
-		/* For target sizes without +/- sign prefix (e.g. 1:150g) */
-		if (mod == 0) {
-			new_size = diff;
-		} else if (mod < 0) {
-			if (diff > old_size) {
-				error("current size is %s which is smaller than %s",
-				      pretty_size_mode(old_size, UNITS_DEFAULT),
-				      pretty_size_mode(diff, UNITS_DEFAULT));
-				ret = 1;
-				goto out;
-			}
-			new_size = old_size - diff;
-		} else if (mod > 0) {
-			if (diff > ULLONG_MAX - old_size) {
-				error("increasing %s is out of range",
-				      pretty_size_mode(diff, UNITS_DEFAULT));
-				ret = 1;
-				goto out;
-			}
-			new_size = old_size + diff;
+		if (err_str) {
+			error("resizing of '%s' failed: %s", path, err_str);
+		} else {
+			error("resizing of '%s' failed: unknown error %d",
+				  path, ret);
 		}
-		new_size = round_down(new_size, fi_args.sectorsize);
-		res_str = pretty_size_mode(new_size, UNITS_DEFAULT);
+		return 1;
 	}
 
-	printf("Resize device id %lld (%s) from %s to %s\n", devid,
-		di_args[dev_idx].path,
-		pretty_size_mode(di_args[dev_idx].total_bytes, UNITS_DEFAULT),
-		res_str);
-
 out:
 	free(di_args);
 	return 0;
@@ -1209,8 +1248,7 @@ out:
 static int cmd_filesystem_resize(const struct cmd_struct *cmd,
 				 int argc, char **argv)
 {
-	struct btrfs_ioctl_vol_args	args;
-	int	fd, res, len, e;
+	int	fd, len;
 	char	*amount, *path;
 	DIR	*dirstream = NULL;
 	int ret;
@@ -1277,39 +1315,12 @@ static int cmd_filesystem_resize(const struct cmd_struct *cmd,
 		}
 	}
 
-	ret = check_resize_args(amount, path);
+	ret = resize_with_args(amount, path, fd);
 	if (ret != 0) {
 		close_file_or_dir(fd, dirstream);
 		return 1;
 	}
-
-	memset(&args, 0, sizeof(args));
-	strncpy_null(args.name, amount);
-	res = ioctl(fd, BTRFS_IOC_RESIZE, &args);
-	e = errno;
 	close_file_or_dir(fd, dirstream);
-	if( res < 0 ){
-		switch (e) {
-		case EFBIG:
-			error("unable to resize '%s': no enough free space",
-				path);
-			break;
-		default:
-			error("unable to resize '%s': %m", path);
-			break;
-		}
-		return 1;
-	} else if (res > 0) {
-		const char *err_str = btrfs_err_str(res);
-
-		if (err_str) {
-			error("resizing of '%s' failed: %s", path, err_str);
-		} else {
-			error("resizing of '%s' failed: unknown error %d",
-				path, res);
-		}
-		return 1;
-	}
 	return 0;
 }
 static DEFINE_SIMPLE_COMMAND(filesystem_resize, "resize");
-- 
2.34.1


  reply	other threads:[~2022-08-15 12:37 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-15 12:36 [RFC PATCH 0/2] support all option for resize command Sidong Yang
2022-08-15 12:36 ` Sidong Yang [this message]
2022-08-15 12:36 ` [RFC PATCH 2/2] btrfs-progs: fi resize: support all option for resize Sidong Yang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220815123652.52314-2-realwakka@gmail.com \
    --to=realwakka@gmail.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.