From patchwork Thu Mar 11 21:44:21 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 85097 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o2BLihYg018522 for ; Thu, 11 Mar 2010 21:44:43 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755034Ab0CKVoi (ORCPT ); Thu, 11 Mar 2010 16:44:38 -0500 Received: from mail-fx0-f227.google.com ([209.85.220.227]:60163 "EHLO mail-fx0-f227.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754982Ab0CKVoh (ORCPT ); Thu, 11 Mar 2010 16:44:37 -0500 Received: by fxm27 with SMTP id 27so655449fxm.28 for ; Thu, 11 Mar 2010 13:44:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:reply-to:to:subject:date :user-agent:references:in-reply-to:cc:mime-version:content-type :content-transfer-encoding:message-id; bh=mQXRG42OFH27+KXJJWM20XWUZjyTg0jOAlbE+iozqtM=; b=MYQl4qOQ3yD0ijdgU9ty5bMcFqEOyil/gf/7Wx/OSqzcQpYL0Kwvry+MQmRDlLLpoh CykSKhdZ46iP01pIeRi7mEbvefPlN7xCT40VkHEdL5kv49HeSZcQEzwJi1rWFFbew9n9 ZsT3J6ZirraAtwfDbZoPv2O5/plBV9KDhFhd8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:reply-to:to:subject:date:user-agent:references:in-reply-to:cc :mime-version:content-type:content-transfer-encoding:message-id; b=SAtTBwUxGsq9ltJrEgYgH1D4Ol5o3ttx3URyrcgaT9TlTZZSeJNKWIb2UcAczphBFD G1urmkC+Ul4nTEmNxZwJs5GELZ9G/1+oNnQZbxTy5DiGfZPyMLHbdxpY2QCwogbiiP52 pnH1B01vIEaegd/Gxk8qFndNbcI2BT8AOwkA0= Received: by 10.87.47.1 with SMTP id z1mr237252fgj.74.1268343873658; Thu, 11 Mar 2010 13:44:33 -0800 (PST) Received: from venice.localnet (host166-189-dynamic.17-87-r.retail.telecomitalia.it [87.17.189.166]) by mx.google.com with ESMTPS id l19sm216393fgb.3.2010.03.11.13.44.30 (version=TLSv1/SSLv3 cipher=RC4-MD5); Thu, 11 Mar 2010 13:44:31 -0800 (PST) From: Goffredo Baroncelli Reply-To: kreijack@inwind.it To: Chris Mason Subject: [PATCH 1/2] Re: New btrfs command pushed into the btrfs-progs subvol branch - commands Date: Thu, 11 Mar 2010 22:44:21 +0100 User-Agent: KMail/1.13.1 (Linux/2.6.32-10-generic; KDE/4.4.1; x86_64; ; ) References: <20100311185421.GM6509@think> <201003112003.18245.kreijack@inwind.it> <20100311190828.GN6509@think> In-Reply-To: <20100311190828.GN6509@think> Cc: linux-btrfs@vger.kernel.org MIME-Version: 1.0 Message-Id: <201003112244.31375.kreijack@inwind.it> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 11 Mar 2010 21:44:43 +0000 (UTC) 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", "\n" "List the snapshot/subvolume of a filesystem." }, - { do_defrag, -1, "filesystem defragment", "[-vcf] [-s start] [-l len] [-t size] | [|...]\n" "Defragment a file or a directory." + + }, + { do_set_default_subvol, 2, + "subvolume set-default", " \n" + "Set the subvolume of the filesystem which will be mounted\n" + "as default." }, { do_fssync, 1, "filesystem sync", "\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", " [..] \n" "Add a device to a filesystem." }, - { do_remove_volume, -1, + { do_remove_volume, -2, "device delete", " [..] \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);