linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
To: <linux-btrfs@vger.kernel.org>
Cc: Fan Chengniang <fancn.fnst@cn.fujitsu.com>
Subject: [PATCH 2/2] btrfs-progs:set max_rfer and max_excl on creating new subvolume
Date: Tue, 10 Feb 2015 18:23:15 +0800	[thread overview]
Message-ID: <1423563803-8996-4-git-send-email-yangds.fnst@cn.fujitsu.com> (raw)
In-Reply-To: <1423563803-8996-1-git-send-email-yangds.fnst@cn.fujitsu.com>

From: Fan Chengniang <fancn.fnst@cn.fujitsu.com>

add -r and -e options to enable setting max reference size
and max exclusive on creating new subvolumes.

Signed-off-by: Fan Chengniang <fancn.fnst@cn.fujitsu.com>
---
 Documentation/btrfs-subvolume.txt |  8 +++-
 cmds-qgroup.c                     | 42 ------------------
 cmds-subvolume.c                  | 57 +++++++++++++++++++++++-
 ioctl.h                           |  3 ++
 qgroup.c                          | 92 +++++++++++++++++++++++++++++++++++++++
 qgroup.h                          |  3 ++
 6 files changed, 160 insertions(+), 45 deletions(-)

diff --git a/Documentation/btrfs-subvolume.txt b/Documentation/btrfs-subvolume.txt
index b0ae030..fe13943 100644
--- a/Documentation/btrfs-subvolume.txt
+++ b/Documentation/btrfs-subvolume.txt
@@ -43,7 +43,7 @@ from normal directories.
 
 SUBCOMMAND
 -----------
-*create* [-i <qgroupid>] [<dest>]<name>::
+*create* [-i <qgroupid>] [-r <max_rfer>] [-e <max_excl>] [<dest>]<name>::
 Create a subvolume <name> in <dest>.
 +
 If <dest> is not given, subvolume <name> will be created in the currently
@@ -54,6 +54,12 @@ directory.
 -i <qgroupid>::::
 Add the newly created subvolume to a qgroup. This option can be given multiple
 times.
++
+-r <max_rfer>::::
+set the newly created subvolume's max reference size
++
+-e <max_excl>::::
+set the newly created subvolume's max exclusive size
 
 *delete* [options] <subvolume> [<subvolume>...]::
 Delete the subvolume(s) from the filesystem.
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 2172944..30f0851 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -106,48 +106,6 @@ static int qgroup_create(int create, int argc, char **argv)
 	return 0;
 }
 
-static int parse_limit(const char *p, unsigned long long *s)
-{
-	char *endptr;
-	unsigned long long size;
-
-	if (strcasecmp(p, "none") == 0) {
-		*s = 0;
-		return 1;
-	}
-	size = strtoull(p, &endptr, 10);
-	switch (*endptr) {
-	case 'T':
-	case 't':
-		size *= 1024;
-		/* fallthrough */
-	case 'G':
-	case 'g':
-		size *= 1024;
-		/* fallthrough */
-	case 'M':
-	case 'm':
-		size *= 1024;
-		/* fallthrough */
-	case 'K':
-	case 'k':
-		size *= 1024;
-		++endptr;
-		break;
-	case 0:
-		break;
-	default:
-		return 0;
-	}
-
-	if (*endptr)
-		return 0;
-
-	*s = size;
-
-	return 1;
-}
-
 static const char * const cmd_qgroup_assign_usage[] = {
 	"btrfs qgroup assign <src> <dst> <path>",
 	"Enable subvolume qgroup support for a filesystem.",
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index a31cb1b..f0e22ac 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -42,13 +42,15 @@ static const char * const subvolume_cmd_group_usage[] = {
 };
 
 static const char * const cmd_subvol_create_usage[] = {
-	"btrfs subvolume create [-i <qgroupid>] [<dest>/]<name>",
+	"btrfs subvolume create [-i <qgroupid>] [-r <max_rfer>] [-e <max_excl>] [<dest>/]<name>",
 	"Create a subvolume",
 	"Create a subvolume <name> in <dest>.  If <dest> is not given",
 	"subvolume <name> will be created in the current directory.",
 	"",
 	"-i <qgroupid>  add the newly created subvolume to a qgroup. This",
 	"               option can be given multiple times.",
+	"-r <max_rfer>  set the newly created subvolume's max reference size",
+	"-e <max_excl>  set the newly created subvolume's max exclusive size",
 	NULL
 };
 
@@ -66,7 +68,7 @@ static int cmd_subvol_create(int argc, char **argv)
 
 	optind = 1;
 	while (1) {
-		int c = getopt(argc, argv, "c:i:v");
+		int c = getopt(argc, argv, "c:i:r:e:v");
 		if (c < 0)
 			break;
 
@@ -85,6 +87,20 @@ static int cmd_subvol_create(int argc, char **argv)
 				goto out;
 			}
 			break;
+		case 'r':
+			res = qgroup_inherit_set_maxrfer(&inherit, optarg);
+			if (res) {
+				retval = res;
+				goto out;
+			}
+			break;
+		case 'e':
+			res = qgroup_inherit_set_maxexcl(&inherit, optarg);
+			if (res) {
+				retval = res;
+				goto out;
+			}
+			break;
 		default:
 			usage(cmd_subvol_create_usage);
 		}
@@ -129,6 +145,43 @@ static int cmd_subvol_create(int argc, char **argv)
 	printf("Create subvolume '%s/%s'\n", dstdir, newname);
 	if (inherit) {
 		struct btrfs_ioctl_vol_args_v2	args;
+		struct btrfs_ioctl_quota_ctl_args sa;
+
+		printf("Set qgroup arguments:\n");
+		if (inherit->num_qgroups > 0) {
+			__u64 index;
+			__u64 qgroupid;
+
+			printf("\tparent qgroup: ");
+			for (index = 0; index < inherit->num_qgroups; index++) {
+				qgroupid = inherit->qgroups[index];
+				printf("%llu/%llu ", qgroupid >> 48,
+					(qgroupid << 16) >> 16);
+			}
+			printf("\n");
+		}
+		if (inherit->lim.flags) {
+			if (inherit->lim.flags & BTRFS_QGROUP_LIMIT_MAX_RFER)
+				printf("\tmax reference: %llu\n",
+					inherit->lim.max_referenced);
+			if (inherit->lim.flags & BTRFS_QGROUP_LIMIT_MAX_EXCL)
+				printf("\tmax exclusive: %llu\n",
+					inherit->lim.max_exclusive);
+		}
+
+		sa.cmd = BTRFS_QUOTA_CTL_STATUS;
+		res = ioctl(fddst, BTRFS_IOC_QUOTA_CTL, &sa);
+		if (res < 0) {
+			fprintf(stderr, "ERROR: cannot get quota status - %s\n",
+			       strerror(errno));
+			retval = 1;
+			goto out;
+		}
+		if (!(sa.status & BTRFS_QUOTA_STATUS_QUOTA_ENABLED)) {
+			fprintf(stderr, "ERROR: quota disabled\n");
+			retval = 1;
+			goto out;
+		}
 
 		memset(&args, 0, sizeof(args));
 		strncpy_null(args.name, newname);
diff --git a/ioctl.h b/ioctl.h
index d550ca6..a47eab8 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -450,6 +450,9 @@ struct btrfs_ioctl_get_dev_stats {
 /* BTRFS_IOC_SNAP_CREATE is no longer used by the btrfs command */
 #define BTRFS_QUOTA_CTL_ENABLE	1
 #define BTRFS_QUOTA_CTL_DISABLE	2
+#define BTRFS_QUOTA_CTL_STATUS  4
+
+#define BTRFS_QUOTA_STATUS_QUOTA_ENABLED 1
 /* 3 has formerly been reserved for BTRFS_QUOTA_CTL_RESCAN */
 struct btrfs_ioctl_quota_ctl_args {
 	__u64 cmd;
diff --git a/qgroup.c b/qgroup.c
index 5a4e393..620ec7e 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -1273,6 +1273,48 @@ err:
 	exit(-1);
 }
 
+int parse_limit(const char *p, unsigned long long *s)
+{
+	char *endptr;
+	unsigned long long size;
+
+	if (strcasecmp(p, "none") == 0) {
+		*s = 0;
+		return 1;
+	}
+	size = strtoull(p, &endptr, 10);
+	switch (*endptr) {
+	case 'T':
+	case 't':
+		size *= 1024;
+		/* fallthrough */
+	case 'G':
+	case 'g':
+		size *= 1024;
+		/* fallthrough */
+	case 'M':
+	case 'm':
+		size *= 1024;
+		/* fallthrough */
+	case 'K':
+	case 'k':
+		size *= 1024;
+		++endptr;
+		break;
+	case 0:
+		break;
+	default:
+		return 0;
+	}
+
+	if (*endptr)
+		return 0;
+
+	*s = size;
+
+	return 1;
+}
+
 int qgroup_inherit_size(struct btrfs_qgroup_inherit *p)
 {
 	return sizeof(*p) + sizeof(p->qgroups[0]) *
@@ -1302,6 +1344,8 @@ qgroup_inherit_realloc(struct btrfs_qgroup_inherit **inherit, int n, int pos)
 		struct btrfs_qgroup_inherit *i = *inherit;
 		int s = sizeof(out->qgroups[0]);
 
+		out->flags = i->flags;
+		out->lim = i->lim;
 		out->num_qgroups = i->num_qgroups;
 		out->num_ref_copies = i->num_ref_copies;
 		out->num_excl_copies = i->num_excl_copies;
@@ -1378,3 +1422,51 @@ bad:
 
 	return 0;
 }
+
+int qgroup_inherit_set_maxrfer(struct btrfs_qgroup_inherit **inherit, char *arg)
+{
+	unsigned long long size;
+
+	if(!parse_limit(arg, &size)) {
+		fprintf(stderr, "Invalid size argument given\n");
+		return 1;
+	}
+
+	if ((*inherit) == NULL) {
+		(*inherit) = malloc(sizeof(struct btrfs_qgroup_inherit));
+		if ((*inherit) == NULL) {
+			fprintf(stderr, "ERROR: Not enough memory\n");
+			return -ENOMEM;
+		}
+		memset((*inherit), 0, sizeof(struct btrfs_qgroup_inherit));
+	}
+
+	(*inherit)->flags |= BTRFS_QGROUP_INHERIT_SET_LIMITS;
+	(*inherit)->lim.flags |= BTRFS_QGROUP_LIMIT_MAX_RFER;
+	(*inherit)->lim.max_referenced = size;
+	return 0;
+}
+
+int qgroup_inherit_set_maxexcl(struct btrfs_qgroup_inherit **inherit, char *arg)
+{
+	unsigned long long size;
+
+	if(!parse_limit(arg, &size)) {
+		fprintf(stderr, "Invalid size argument given\n");
+		return 1;
+	}
+
+	if ((*inherit) == NULL) {
+		(*inherit) = malloc(sizeof(struct btrfs_qgroup_inherit));
+		if ((*inherit) == NULL) {
+			fprintf(stderr, "ERROR: Not enough memory\n");
+			return -ENOMEM;
+		}
+		memset((*inherit), 0, sizeof(struct btrfs_qgroup_inherit));
+	}
+
+	(*inherit)->flags |= BTRFS_QGROUP_INHERIT_SET_LIMITS;
+	(*inherit)->lim.flags |= BTRFS_QGROUP_LIMIT_MAX_EXCL;
+	(*inherit)->lim.max_exclusive = size;
+	return 0;
+}
diff --git a/qgroup.h b/qgroup.h
index 6e65ef7..e5d03ca 100644
--- a/qgroup.h
+++ b/qgroup.h
@@ -94,9 +94,12 @@ int btrfs_qgroup_setup_comparer(struct btrfs_qgroup_comparer_set **comp_set,
 				enum btrfs_qgroup_comp_enum comparer,
 				int is_descending);
 u64 parse_qgroupid(char *p);
+int parse_limit(const char *p, unsigned long long *s);
 int qgroup_inherit_size(struct btrfs_qgroup_inherit *p);
 int qgroup_inherit_add_group(struct btrfs_qgroup_inherit **inherit, char *arg);
 int qgroup_inherit_add_copy(struct btrfs_qgroup_inherit **inherit, char *arg,
 			    int type);
+int qgroup_inherit_set_maxrfer(struct btrfs_qgroup_inherit **inherit, char *arg);
+int qgroup_inherit_set_maxexcl(struct btrfs_qgroup_inherit **inherit, char *arg);
 
 #endif
-- 
1.8.4.2


  parent reply	other threads:[~2015-02-10 10:26 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-10 10:23 [PATCH 0/9] Btrfs: qgroup: part-1: bug fixes for qgroup inherit Dongsheng Yang
2015-02-10 10:23 ` [PATCH 1/2] btrfs-progs:correct the return value Dongsheng Yang
2015-02-27 15:37   ` David Sterba
2015-02-10 10:23 ` [PATCH 1/9] btrfs: qgroup: move WARN_ON() to the correct location Dongsheng Yang
2015-03-02 22:05   ` Josef Bacik
2015-02-10 10:23 ` Dongsheng Yang [this message]
2015-02-10 10:23 ` [PATCH 2/9] btrfs: qgroup: inherit limit info from srcgroup in creating snapshot Dongsheng Yang
2015-03-02 22:10   ` Josef Bacik
2015-02-10 10:23 ` [PATCH 3/9] btrfs: qgroup: update qgroup in memory at the same time when we update it in btree Dongsheng Yang
2015-02-10 10:23 ` [PATCH 4/9] btrfs: qgroup: consolidate the parameter of fucntion update_qgroup_limit_item() Dongsheng Yang
2015-02-10 10:23 ` [PATCH 5/9] btrfs: qgroup: update limit info in function btrfs_run_qgroups() Dongsheng Yang
2015-02-10 10:23 ` [PATCH 6/9] btrfs: qgroup: fix limit args override whole limit struct Dongsheng Yang
2015-02-10 10:23 ` [PATCH 7/9] Btrfs: qgroup: make the btree for qgroup increase from left to right Dongsheng Yang
2015-02-10 10:23 ` [PATCH 8/9] Btrfs: qgroup: cleanup, remove an unsued parameter in btrfs_create_qgroup() Dongsheng Yang
2015-02-10 10:23 ` [PATCH 9/9] btrfs: qgroup: obtain quota status Dongsheng 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=1423563803-8996-4-git-send-email-yangds.fnst@cn.fujitsu.com \
    --to=yangds.fnst@cn.fujitsu.com \
    --cc=fancn.fnst@cn.fujitsu.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).