diff mbox

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

Message ID 201003112244.31375.kreijack@inwind.it (mailing list archive)
State Accepted, archived
Headers show

Commit Message

Goffredo Baroncelli March 11, 2010, 9:44 p.m. UTC
None
diff mbox

Patch

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);