[PATCH 1/2] Re: New btrfs command pushed into the btrfs-progs subvol branch - commands

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Chris,

I updated my git repository. You can pull from 

git pull http://cassiopea.homelinux.net/git/btrfs-command.git mlc-subvol

(branch mlc-subvol, commit e59135a27dc1fde6acc4fb198499be2b6cbd9f6f)

$ git diff remotes/origin/subvol | diffstat
 btrfs-list.c   |   15 +++--
 btrfs.c        |   56 +++++++++++++++++-
 btrfs_cmds.c   |   84 +++++++++++++++++-----------
 btrfs_cmds.h   |    1 
 man/btrfs.8.in |  150 +++++++++++++++++++++++++++++++++++++++++++++[...]
 5 files changed, 283 insertions(+), 43 deletions(-)


As you requested I update the parser in order set the argv[0] argument as the 
program name + the verb. For example if I do

	$ btrfs dev add

the argv[0] will be equal to "btrfs device add". I hope that is what you 
requested.

Due to this change I update all the commands in order to evaluate the 
arguments from argv[1] and not from argv[0] anymore. (I update also your 
do_defrag() function)

Also because I implemented that already the week ago:
- I made some small modification to btrfs-list.c in order to be more friendly 
in case of error (replace some "exit(2)" with "return -ERR")
- I implemented the command "btrf subvolume set-default"

Hoping that this can you help
Regards 
G.Baroncelli


diff --git a/btrfs-list.c b/btrfs-list.c
index 6305d3c..f2f119b 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -66,7 +66,7 @@ struct root_info {
 	char name[];
 };
 
-void root_lookup_init(struct root_lookup *tree)
+static void root_lookup_init(struct root_lookup *tree)
 {
 	tree->root.rb_node = NULL;
 }
@@ -275,9 +275,9 @@ static int lookup_ino_path(int fd, struct root_info *ri)
 
 	ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args);
 	if (ret) {
-		fprintf(stderr, "Failed to lookup path for root %llu\n",
+		fprintf(stderr, "ERROR: Failed to lookup path for root 
%llu\n",
 			(unsigned long long)ri->ref_tree);
-		exit(1);
+		return ret;
 	}
 
 	if (args.name[0]) {
@@ -346,8 +346,8 @@ int list_subvols(int fd)
 	while(1) {
 		ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
 		if (ret < 0) {
-			perror("ioctl:");
-			break;
+			fprintf(stderr, "ERROR: can't perform the search\n");
+			return ret;
 		}
 		/* the ioctl returns the number of item it found in nr_items 
*/
 		if (sk->nr_items == 0)
@@ -398,8 +398,11 @@ int list_subvols(int fd)
 	n = rb_first(&root_lookup.root);
 	while (n) {
 		struct root_info *entry;
+		int ret;
 		entry = rb_entry(n, struct root_info, rb_node);
-		lookup_ino_path(fd, entry);
+		ret = lookup_ino_path(fd, entry);
+		if(ret < 0)
+			return ret;
 		n = rb_next(n);
 	}
 
diff --git a/btrfs.c b/btrfs.c
index 20f7413..58271f6 100644
--- a/btrfs.c
+++ b/btrfs.c
@@ -60,10 +60,15 @@ static struct Command commands[] = {
 	{ do_subvol_list, 1, "subvolume list", "<path>\n"
 		"List the snapshot/subvolume of a filesystem."
 	},
-
 	{ do_defrag, -1,
 	  "filesystem defragment", "[-vcf] [-s start] [-l len] [-t size] 
<file>|<dir> [<file>|<dir>...]\n"
 		"Defragment a file or a directory."
+
+	},
+	{ do_set_default_subvol, 2,
+	  "subvolume set-default", "<id> <path>\n"
+		"Set the subvolume of the filesystem <path> which will be 
mounted\n"
+		"as default."
 	},
 	{ do_fssync, 1,
 	  "filesystem sync", "<path>\n"
@@ -88,11 +93,12 @@ static struct Command commands[] = {
 		"Scan all device for or the passed device for a btrfs\n"
 		"filesystem."
 	},
-	{ do_add_volume, -1,
+
+	{ do_add_volume, -2,
 	  "device add", "<dev> [<dev>..] <path>\n"
 		"Add a device to a filesystem."
 	},
-	{ do_remove_volume, -1,
+	{ do_remove_volume, -2,
 	  "device delete", "<dev> [<dev>..] <path>\n"
 		"Remove a device from a filesystem."
 	},
@@ -208,6 +214,41 @@ static int check_ambiguity(struct Command *cmd, char 
**argv){
 }
 
 /*
+ * This function, compacts the program name and the command in the first
+ * element of the '*av' array
+ */
+static int prepare_args(int *ac, char ***av, char *prgname, struct Command 
*cmd ){
+
+	char	**ret;
+	int	i;
+	char	*newname;
+
+	ret = (char **)malloc(sizeof(char*)*(*ac+1));
+	newname = (char*)malloc(strlen(prgname)+strlen(cmd->verb)+2);
+	if( !ret || !newname ){
+		free(ret);
+		free(newname);
+		return -1;
+	}
+
+	ret[0] = newname;
+	for(i=0; i < *ac ; i++ )
+		ret[i+1] = (*av)[i];
+
+	strcpy(newname, prgname);
+	strcat(newname, " ");
+	strcat(newname, cmd->verb);
+
+	(*ac)++;
+	*av = ret;
+
+	return 0;
+
+}
+
+
+
+/*
 
 	This function perform the following jobs:
 	- show the help if '--help' or 'help' or '-h' are passed
@@ -307,11 +348,18 @@ static int parse_args(int argc, char **argv,
 			matchcmd->verb, -matchcmd->nargs);
 			return -2;
 	}
-	if(matchcmd->nargs >= 0 && matchcmd->nargs != *nargs_ && matchcmd-
>nargs != 999 ){
+
+	if(matchcmd->nargs >= 0 && matchcmd->nargs != *nargs_ && matchcmd-
>nargs != 999){
 		fprintf(stderr, "ERROR: '%s' requires %d arg(s)\n",
 			matchcmd->verb, matchcmd->nargs);
 			return -2;
 	}
+	
+        if (prepare_args( nargs_, args_, prgname, matchcmd )){
+                fprintf(stderr, "ERROR: not enough memory\\n");
+		return -20;
+        }
+
 
 	return 1;
 }
diff --git a/btrfs_cmds.c b/btrfs_cmds.c
index 3a21be3..89f47c2 100644
--- a/btrfs_cmds.c
+++ b/btrfs_cmds.c
@@ -59,7 +59,7 @@ static inline int ioctl(int fd, int define, void *arg) { 
return 0; }
 static int test_issubvolume(char *path)
 {
 
-	struct stat	st;
+	struct stat 	st;
 	int		res;
 
 	res = stat(path, &st);
@@ -79,7 +79,7 @@ static int test_issubvolume(char *path)
  */
 static int test_isdir(char *path)
 {
-	struct stat	st;
+	struct stat 	st;
 	int		res;
 
 	res = stat(path, &st);
@@ -142,7 +142,7 @@ static u64 parse_size(char *s)
 	return atoll(s) * mult;
 }
 
-int do_defrag(int ac, char **avp)
+int do_defrag(int ac, char **av)
 {
 	int fd;
 	int compress = 0;
@@ -156,17 +156,6 @@ int do_defrag(int ac, char **avp)
 	int verbose = 0;
 	int fancy_ioctl = 0;
 	struct btrfs_ioctl_defrag_range_args range;
-	char **av;
-
-	/*
-	 * getopt expects av[0] to be the program name and it seems
-	 * to get confused when this isn't the case
-	 */
-	av = malloc((ac + 2) * sizeof(char *));
-	av[0] = "defrag";
-	av[ac + 1] = NULL;
-	memcpy(av + 1, avp, ac * sizeof(char *));
-	ac += 1;
 
 	optind = 1;
 	while(1) {
@@ -264,7 +253,7 @@ int do_subvol_list(int argc, char **argv)
 	int ret;
 	char *subvol;
 
-	subvol = argv[0];
+	subvol = argv[1];
 
 	ret = test_issubvolume(subvol);
 	if (ret < 0) {
@@ -289,13 +278,13 @@ int do_subvol_list(int argc, char **argv)
 
 int do_clone(int argc, char **argv)
 {
-	char	*subvol, *dst;
+	char 	*subvol, *dst;
 	int	res, fd, fddst, len;
 	char	*newname;
 	char	*dstdir;
 
-	subvol = argv[0];
-	dst = argv[1];
+	subvol = argv[1];
+	dst = argv[2];
 	struct btrfs_ioctl_vol_args	args;
 
 	res = test_issubvolume(subvol);
@@ -375,7 +364,7 @@ int do_delete_subvolume(int argc, char **argv)
 	int	res, fd, len;
 	struct btrfs_ioctl_vol_args	args;
 	char	*dname, *vname, *cpath;
-	char	*path = argv[0];
+	char	*path = argv[1];
 
 	res = test_issubvolume(path);
 	if(res<0){
@@ -436,7 +425,7 @@ int do_create_subvol(int argc, char **argv)
 	char	*newname;
 	char	*dstdir;
 	struct btrfs_ioctl_vol_args	args;
-	char	*dst = argv[0];
+	char	*dst = argv[1];
 
 	res = test_isdir(dst);
 	if(res >= 0 ){
@@ -487,7 +476,7 @@ int do_create_subvol(int argc, char **argv)
 int do_fssync(int argc, char **argv)
 {
 	int fd, res;
-	char	*path = argv[0];
+	char	*path = argv[1];
 
 	fd = open_file_or_dir(path);
 	if (fd < 0) {
@@ -506,10 +495,10 @@ int do_fssync(int argc, char **argv)
 	return 0;
 }
 
-int do_scan(int nargs, char **argv)
+int do_scan(int argc, char **argv)
 {
 	int	i, fd;
-	if(!nargs){
+	if(argc<=1){
 		int ret;
 
 		printf("Scanning for Btrfs filesystems\n");
@@ -527,8 +516,8 @@ int do_scan(int nargs, char **argv)
 		return 10;
 	}
 
-	for( i = 0 ; i < nargs ; i++ ){
-		struct btrfs_ioctl_vol_args	args;
+	for( i = 1 ; i < argc ; i++ ){
+		struct btrfs_ioctl_vol_args 	args;
 		int	ret;
 
 		printf("Scanning for Btrfs filesystems in '%s'\n", argv[i]);
@@ -558,8 +547,8 @@ int do_resize(int argc, char **argv)
 
 	struct btrfs_ioctl_vol_args	args;
 	int	fd, res, len;
-	char	*amount=argv[0], *path=argv[1];
-
+	char 	*amount=argv[1], *path=argv[2];
+	
 	fd = open_file_or_dir(path);
 	if (fd < 0) {
 		fprintf(stderr, "ERROR: can't access to '%s'\n", path);
@@ -646,7 +635,7 @@ int do_show_filesystem(int argc, char **argv)
 	struct list_head *all_uuids;
 	struct btrfs_fs_devices *fs_devices;
 	struct list_head *cur_uuid;
-	char *search = argv[0];
+	char *search = argv[1];
 	int ret;
 
 	ret = btrfs_scan_one_dir("/dev", 0);
@@ -680,8 +669,8 @@ int do_add_volume(int nargs, char **args)
 		return 12;
 	}
 
-	for(i=0 ; i < (nargs-1) ; i++ ){
-		struct	btrfs_ioctl_vol_args ioctl_args;
+	for(i=1 ; i < (nargs-1) ; i++ ){
+		struct 	btrfs_ioctl_vol_args ioctl_args;
 		int	devfd, res;
 		u64 dev_block_count = 0;
 		struct stat st;
@@ -737,8 +726,8 @@ int do_balance(int argc, char **argv)
 {
 
 	int	fdmnt, ret=0;
-	char	*path = argv[0];
 	struct btrfs_ioctl_vol_args args;
+	char	*path = argv[1];
 
 	fdmnt = open_file_or_dir(path);
 	if (fdmnt < 0) {
@@ -768,8 +757,8 @@ int do_remove_volume(int nargs, char **args)
 		return 12;
 	}
 
-	for(i=0 ; i < (nargs-1) ; i++ ){
-		struct	btrfs_ioctl_vol_args arg;
+	for(i=1 ; i < (nargs-1) ; i++ ){
+		struct 	btrfs_ioctl_vol_args arg;
 		int	res;
 
 		strcpy(arg.name, args[i]);
@@ -786,3 +775,32 @@ int do_remove_volume(int nargs, char **args)
 	else
 		return 0;
 }
+
+int do_set_default_subvol(int nargs, char **argv)
+{
+	int	ret=0, fd;
+	u64	objectid;
+	char 	*path = argv[2];
+	char	*subvolid = argv[1];
+
+	fd = open_file_or_dir(path);
+	if (fd < 0) {
+		fprintf(stderr, "ERROR: can't access to '%s'\n", path);
+		return 12;
+	}
+
+	objectid = (unsigned long long)strtoll(subvolid, NULL, 0);
+	if (errno == ERANGE) {
+		fprintf(stderr, "ERROR: invalid tree id (%s)\n",subvolid);
+		return 30;
+	}
+	ret = ioctl(fd, BTRFS_IOC_DEFAULT_SUBVOL, &objectid);
+	close(fd);
+	if( ret < 0 ){
+		fprintf(stderr, "ERROR: unable to set a new default 
subvolume\n");
+		return 30;
+	}
+	return 0;
+	
+}
+
diff --git a/btrfs_cmds.h b/btrfs_cmds.h
index cfdbde2..c63baa9 100644
--- a/btrfs_cmds.h
+++ b/btrfs_cmds.h
@@ -27,4 +27,5 @@ int do_remove_volume(int nargs, char **args);
 int do_scan(int nargs, char **argv);
 int do_resize(int nargs, char **argv);
 int do_subvol_list(int nargs, char **argv);
+int do_set_default_subvol(int nargs, char **argv);
 int list_subvols(int fd);


----




On Thursday 11 March 2010, you (Chris Mason) wrote:
> Thanks for all your work on btrfs!
> 
> -chris
> 
> On Thu, Mar 11, 2010 at 08:03:17PM +0100, Goffredo Baroncelli wrote:
> > On Thursday 11 March 2010, Chris Mason wrote:
> > > Hi everyone,
> > > 
> > > I've pushed Goffredo's new btrfs utility into the subvol branch of the
> > > btrfs-progs repo.  I'm using it as my starting point for the subvol
> > > listing utility as well as my fancy new defrag range ioctl.
> > > 
> > > Goffredo, the new defrag ioctl takes a bunch of arguments, and I used
> > > getopt inside the command to do it.  The tricky part is that getopt
> > > expects argv[0] to be the command name, so I had to hack things a bit.
> > > 
> > > Could you please send a patch that changes the commands to include the
> > > command name in argv[0]?  That'll make it easier to be flexible.
> > > 
> > 
> > I will start to work 
> > 
> > > -chris
> > > 
> > 
> > 
> > -- 
> > gpg key@ keyserver.linux.it: Goffredo Baroncelli (ghigo) 
<kreijack@xxxxxxxxx>
> > Key fingerprint = 4769 7E51 5293 D36C 814E  C054 BF04 F161 3DC5 0512
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
> > the body of a message to majordomo@xxxxxxxxxxxxxxx
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


-- 
gpg key@ keyserver.linux.it: Goffredo Baroncelli (ghigo) <kreijackATinwind.it>
Key fingerprint = 4769 7E51 5293 D36C 814E  C054 BF04 F161 3DC5 0512

Attachment: signature.asc
Description: This is a digitally signed message part.


[Index of Archives]     [Linux Filesystem Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux