* revised ioctl#21 btrfsprogs patch @ 2010-12-15 22:18 David Nicol 2010-12-24 19:52 ` David Nicol 0 siblings, 1 reply; 2+ messages in thread From: David Nicol @ 2010-12-15 22:18 UTC (permalink / raw) To: BTRFS MAILING LIST the below is against 70c6c10134b502fa69955746554031939b85fb0c which is the head of the "next" branch. 1: absolute-sized fields in the interface object 2: now getting error from errno instead of the return value of ioctl(2) ---------- Forwarded message ---------- =46rom: project user Date: Wed, Dec 15, 2010 at 4:15 PM Subject: btrfsprogs revised ioctl#21 patch diff --git a/Makefile b/Makefile index d65f6a2..b8ef1f2 100644 --- a/Makefile +++ b/Makefile @@ -37,12 +37,13 @@ all: version $(progs) manpages =C2=A0version: =C2=A0 =C2=A0 =C2=A0 =C2=A0bash version.sh -btrfs: $(objects) btrfs.o btrfs_cmds.o - =C2=A0 =C2=A0 =C2=A0 gcc $(CFLAGS) -o btrfs btrfs.o btrfs_cmds.o \ +btrfs: $(objects) btrfs.o btrfs_cmds.o iso8601toms.o + =C2=A0 =C2=A0 =C2=A0 gcc $(CFLAGS) -o btrfs btrfs.o btrfs_cmds.o iso8= 601toms.o \ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0$(objects) $(LDF= LAGS) $(LIBS) -btrfsctl: $(objects) btrfsctl.o - =C2=A0 =C2=A0 =C2=A0 gcc $(CFLAGS) -o btrfsctl btrfsctl.o $(objects) = $(LDFLAGS) $(LIBS) +btrfsctl: $(objects) btrfsctl.o iso8601toms.o + =C2=A0 =C2=A0 =C2=A0 gcc $(CFLAGS) -o btrfsctl btrfsctl.o iso8601toms= =2Eo \ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 $(objects) $(LDFLAGS= ) $(LIBS) =C2=A0btrfs-vol: $(objects) btrfs-vol.o =C2=A0 =C2=A0 =C2=A0 =C2=A0gcc $(CFLAGS) -o btrfs-vol btrfs-vol.o $(obj= ects) $(LDFLAGS) $(LIBS) diff --git a/btrfs.c b/btrfs.c index 46314cf..6b3ebf6 100644 --- a/btrfs.c +++ b/btrfs.c @@ -29,6 +29,7 @@ struct Command { =C2=A0 =C2=A0 =C2=A0 =C2=A0CommandFunction func; =C2=A0 /* function whi= ch implements the command */ =C2=A0 =C2=A0 =C2=A0 =C2=A0int =C2=A0 =C2=A0 nargs; =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0/* if =3D=3D 999, any number of arguments =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if >=3D 0, number of argu= ments, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if > 1000, 1000 more t= han the _maximum_ number of arguments, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if < 0, _minimum_ number = of arguments */ =C2=A0 =C2=A0 =C2=A0 =C2=A0char =C2=A0 =C2=A0*verb; =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0/* verb */ =C2=A0 =C2=A0 =C2=A0 =C2=A0char =C2=A0 =C2=A0*help; =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0/* help lines; form the 2nd onward they are @@ -73,14 +74,19 @@ static struct Command commands[] =3D { =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"Set the subvolu= me of the filesystem <path> which will be mounted\n" =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"as default." =C2=A0 =C2=A0 =C2=A0 =C2=A0}, - =C2=A0 =C2=A0 =C2=A0 { do_fssync, 1, - =C2=A0 =C2=A0 =C2=A0 =C2=A0 "filesystem sync", "<path>\n" - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "Force a sync on the= filesystem <path>." + =C2=A0 =C2=A0 =C2=A0 { do_fssync, 1002, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 "filesystem sync", "[-dq] <path>\n" + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "Force a sync on the= filesystem <path>, defaulting to '.'." + =C2=A0 =C2=A0 =C2=A0 }, + =C2=A0 =C2=A0 =C2=A0 { do_wait4clean, 1002, /* require at most two ar= gs */ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 "filesystem reclaim", "[path [timeout]] \= n" + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "Wait for cleanup of= deleted subvolumes. Path defaults to .\n" + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "Timeout in seconds,= or add m for minutes.\n" =C2=A0 =C2=A0 =C2=A0 =C2=A0}, =C2=A0 =C2=A0 =C2=A0 =C2=A0{ do_resize, 2, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"filesystem resize", "[+/-]<newsize>[= gkm]|max <filesystem>\n" =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"Resize the file= system. If 'max' is passed, the filesystem\n" - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "will occupe all ava= ilable space on the device." + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "will occupy all ava= ilable space on the device." =C2=A0 =C2=A0 =C2=A0 =C2=A0}, =C2=A0 =C2=A0 =C2=A0 =C2=A0{ do_show_filesystem, 999, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"filesystem show", "[<uuid>|<label>]\= n" @@ -349,6 +355,15 @@ static int parse_args(int argc, char **argv, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -2; =C2=A0 =C2=A0 =C2=A0 =C2=A0/* check the number of argument */ + + =C2=A0 =C2=A0 =C2=A0 if(matchcmd->nargs > 1000 ){ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if ( matchcmd->nargs < (1000 + *nar= gs_)){ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr, "ERR= OR: '%s' requires only %d or fewer arg(s)\n", + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 matchcmd->verb, matchcmd->nargs - 1000 ); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 return -2; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 } else { + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (matchcmd->nargs < 0 && matchcmd->nargs <= -*nargs_ ){ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, = "ERROR: '%s' requires minimum %d arg(s)\n", =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0matchcmd->verb, -matchcmd->nargs); @@ -359,7 +374,7 @@ static int parse_args(int argc, char **argv, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0matchcmd->verb, matchcmd->nargs); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0return -2; =C2=A0 =C2=A0 =C2=A0 =C2=A0} - + =C2=A0 =C2=A0 =C2=A0 } =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (prepare_args( nargs_, args_, prgname, m= atchcmd )){ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr,= "ERROR: not enough memory\\n"); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -20; diff --git a/btrfs_cmds.c b/btrfs_cmds.c index 8031c58..89f1f22 100644 --- a/btrfs_cmds.c +++ b/btrfs_cmds.c @@ -507,15 +507,37 @@ int do_create_subvol(int argc, char **argv) =C2=A0int do_fssync(int argc, char **argv) =C2=A0{ =C2=A0 =C2=A0 =C2=A0 =C2=A0int fd, res; - =C2=A0 =C2=A0 =C2=A0 char =C2=A0 =C2=A0*path =3D argv[1]; - + =C2=A0 =C2=A0 =C2=A0 =C2=A0int cleanup=3D1, quiet=3D0; + =C2=A0 =C2=A0 =C2=A0 char =C2=A0 =C2=A0*path =3D ".", *p; /* [-dq] [<= path>] */ + =C2=A0 =C2=A0 =C2=A0 =C2=A0struct btrfs_ioctl_cleaner_wait_args w4c_a= rg; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (argc > 1){ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (argv[1][0] =3D=3D '-'){ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for (p=3D&argv[1][1]; *p; p= ++) switch (*p){ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 'q': quie= t++; break; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 'd': clea= nup++; break; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0default: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprint= f(stderr, + =C2=A0 =C2=A0 "ERROR: unknown flag '%c' in '%s'\n", *p,argv[1]); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return = 12; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (argc > 2) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 path =3D argv= [2]; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }else{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0path =3D argv[1]; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0}; + =C2=A0 =C2=A0while (cleanup--){ /* cleanup starts at 1 */ =C2=A0 =C2=A0 =C2=A0 =C2=A0fd =3D open_file_or_dir(path); =C2=A0 =C2=A0 =C2=A0 =C2=A0if (fd < 0) { =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, = "ERROR: can't access to '%s'\n", path); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return 12; =C2=A0 =C2=A0 =C2=A0 =C2=A0} - =C2=A0 =C2=A0 =C2=A0 printf("FSSync '%s'\n", path); + =C2=A0 =C2=A0 =C2=A0 if (!quiet) printf("FSSync '%s'\n", path); =C2=A0 =C2=A0 =C2=A0 =C2=A0res =3D ioctl(fd, BTRFS_IOC_SYNC); =C2=A0 =C2=A0 =C2=A0 =C2=A0close(fd); =C2=A0 =C2=A0 =C2=A0 =C2=A0if( res < 0 ){ @@ -523,6 +545,56 @@ int do_fssync(int argc, char **argv) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return 16; =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (cleanup){ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 w4c_arg.ms =3D 0x00000000; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 w4c_arg.flags =3D 0x00000000; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fd =3D open_file_or_dir(path); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (fd < 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr, "ERR= OR: can't access to '%s'\n", path); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 12; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (!quiet) printf("reclaim: '%s'\n= ", path); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0res =3D ioctl(fd, BTRFS_IOC_CLEANER= _WAIT, &w4c_arg); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0close(fd); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if( res !=3D 0 ){ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr, "%s:= error #%i:%s\n", + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0path, errno,strerror(errno)); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return errno; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0}; + =C2=A0 =C2=A0 =C2=A0 return 0; +} + +#include "iso8601toms.h" + +int do_wait4clean(int argc, char **argv) +{ + =C2=A0 =C2=A0 =C2=A0 int fd, res; + =C2=A0 =C2=A0 =C2=A0 =C2=A0struct btrfs_ioctl_cleaner_wait_args w4c_a= rg; + + =C2=A0 =C2=A0 =C2=A0 char =C2=A0 =C2=A0*path =3D "."; + =C2=A0 =C2=A0 =C2=A0 =C2=A0w4c_arg.ms =3D 0x00000000; + =C2=A0 =C2=A0 =C2=A0 =C2=A0w4c_arg.flags =3D 0x00000000; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (argc > 1) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0path =3D argv[1]; + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (argc > 2) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 w4c_arg.ms =3D iso8601toms(= argv[2]); + + =C2=A0 =C2=A0 =C2=A0 fd =3D open_file_or_dir(path); + =C2=A0 =C2=A0 =C2=A0 if (fd < 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr, "ERR= OR: can't open file or dir '%s'\n", path); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 12; + =C2=A0 =C2=A0 =C2=A0 } + =C2=A0 =C2=A0 =C2=A0 res =3D ioctl(fd, BTRFS_IOC_CLEANER_WAIT, &w4c_a= rg); + =C2=A0 =C2=A0 =C2=A0 close(fd); + =C2=A0 =C2=A0 =C2=A0 if( res !=3D 0 ){ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr, "%s:= error #%i:%s\n", + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0path, errno,strerror(errno)); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return errno; + =C2=A0 =C2=A0 =C2=A0 } + =C2=A0 =C2=A0 =C2=A0 =C2=A0return 0; =C2=A0} diff --git a/btrfs_cmds.h b/btrfs_cmds.h index 7bde191..c958338 100644 --- a/btrfs_cmds.h +++ b/btrfs_cmds.h @@ -19,6 +19,7 @@ int do_clone(int nargs, char **argv); =C2=A0int do_delete_subvolume(int nargs, char **argv); =C2=A0int do_create_subvol(int nargs, char **argv); =C2=A0int do_fssync(int nargs, char **argv); +int do_wait4clean(int nargs, char **argv); =C2=A0int do_defrag(int argc, char **argv); =C2=A0int do_show_filesystem(int nargs, char **argv); =C2=A0int do_add_volume(int nargs, char **args); diff --git a/btrfsctl.c b/btrfsctl.c index 92bdf39..cf7f69a 100644 --- a/btrfsctl.c +++ b/btrfsctl.c @@ -34,6 +34,7 @@ =C2=A0#include "ctree.h" =C2=A0#include "transaction.h" =C2=A0#include "utils.h" +#include "iso8601toms.h" =C2=A0#include "version.h" =C2=A0#ifdef __CHECKER__ @@ -57,6 +58,7 @@ static void print_usage(void) =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("\t-a: scans all devices for Btrfs fi= lesystems\n"); =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("\t-c: forces a single FS sync\n"); =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("\t-D: delete snapshot\n"); + =C2=A0 =C2=A0 =C2=A0 printf("\t-C [timeout [directory]]: wait for sna= pshot space recovery\n"); =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("\t-m [tree id] directory: set the de= fault mounted subvolume" =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 " to the [tree id] or = the directory\n"); =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("%s\n", BTRFS_BUILD_VERSION); @@ -96,7 +98,7 @@ int main(int ac, char **av) =C2=A0 =C2=A0 =C2=A0 =C2=A0char *fname =3D NULL; =C2=A0 =C2=A0 =C2=A0 =C2=A0char *snap_location =3D NULL; =C2=A0 =C2=A0 =C2=A0 =C2=A0int snap_fd =3D 0; - =C2=A0 =C2=A0 =C2=A0 int fd; + =C2=A0 =C2=A0 =C2=A0 int fd =3D -999; /* silence a warning */ =C2=A0 =C2=A0 =C2=A0 =C2=A0int ret; =C2=A0 =C2=A0 =C2=A0 =C2=A0struct btrfs_ioctl_vol_args args; =C2=A0 =C2=A0 =C2=A0 =C2=A0char *name =3D NULL; @@ -106,6 +108,7 @@ int main(int ac, char **av) =C2=A0 =C2=A0 =C2=A0 =C2=A0char *pos; =C2=A0 =C2=A0 =C2=A0 =C2=A0char *fullpath; =C2=A0 =C2=A0 =C2=A0 =C2=A0u64 objectid =3D 0; + =C2=A0 =C2=A0 =C2=A0 =C2=A0struct btrfs_ioctl_cleaner_wait_args CWarg= s; =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ac =3D=3D 2 && strcmp(av[1], "-a") =3D=3D= 0) { =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, = "Scanning for Btrfs filesystems\n"); @@ -186,6 +189,11 @@ int main(int ac, char **av) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "-D size too long= \n"); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0exit(1); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } else if (strcmp(av= [i], "-C") =3D=3D 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 command =3D BTRFS_IOC_CLEANER_WAIT; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0CWargs.ms =3D ( ac > (i+1) ? iso8601toms(av[i+1]) : 0x00000000 ); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0CWargs.flags =3D 0x00000000; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 name =3D ( ac > ( i+2 ) ? av[i + 2] : "." ); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} else if (strcm= p(av[i], "-A") =3D=3D 0) { =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0if (i >=3D ac - 1) { =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "-A requires an a= rg\n"); @@ -232,7 +240,7 @@ int main(int ac, char **av) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0exit(1); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0name =3D fname; - =C2=A0 =C2=A0 =C2=A0 =C2=A0} else { + =C2=A0 =C2=A0 =C2=A0 } else if (command !=3D BTRFS_IOC_CLEANER_WAIT) = { =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fd =3D open_file= _or_dir(fname); =C2=A0 =C2=A0 =C2=A0 =C2=A0 } @@ -247,6 +255,9 @@ int main(int ac, char **av) =C2=A0 =C2=A0 =C2=A0 =C2=A0} else if (command =3D=3D BTRFS_IOC_DEFAULT_= SUBVOL) { =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("objectid= is %llu\n", objectid); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D ioctl(fd= , command, &objectid); + =C2=A0 =C2=A0 =C2=A0 } else if (command =3D=3D BTRFS_IOC_CLEANER_WAIT= ) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fd =3D open_file_or_= dir(name); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret =3D ioctl(fd, co= mmand, &CWargs); =C2=A0 =C2=A0 =C2=A0 =C2=A0} else =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D ioctl(fd= , command, &args); =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret < 0) { diff --git a/ioctl.h b/ioctl.h index 776d7a9..dc3f2fb 100644 --- a/ioctl.h +++ b/ioctl.h @@ -169,4 +169,11 @@ struct btrfs_ioctl_space_args { =C2=A0#define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64) =C2=A0#define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0struct btrfs_ioctl_= space_args) +struct btrfs_ioctl_cleaner_wait_args{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0__u32 ms; + =C2=A0 =C2=A0 =C2=A0 =C2=A0__u32 flags; /* controls what to wait for,= and stricture. Zero waits for subvol deletions. */ +}; +#define BTRFS_IOC_CLEANER_WAIT _IOW(BTRFS_IOCTL_MAGIC, 21, \ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 struct btrfs_ioctl_cl= eaner_wait_args) =C2=A0#endif + diff --git a/man/btrfs.8.in b/man/btrfs.8.in index 26ef982..a62f02b 100644 --- a/man/btrfs.8.in +++ b/man/btrfs.8.in @@ -17,7 +17,9 @@ btrfs \- control a btrfs filesystem =C2=A0.PP =C2=A0\fBbtrfs\fP \fBfilesystem defrag\fP\fI <file>|<dir> [<file>|<dir>= =2E..]\fP =C2=A0.PP -\fBbtrfs\fP \fBfilesystem sync\fP\fI <path> \fP +\fBbtrfs\fP \fBfilesystem sync\fP\fI [-dq] [<path>] \fP +.PP +\fBbtrfs\fP \fBfilesystem reclaim\fP\fI [path [timeout]] \fP =C2=A0.PP =C2=A0\fBbtrfs\fP \fBfilesystem resize\fP\fI [+/\-]<size>[gkm]|max <fil= esystem>\fP =C2=A0.PP @@ -111,8 +113,22 @@ Scan devices for a btrfs filesystem. If no devices are passed, \fBbtrfs\fR scans =C2=A0all the block devices. =C2=A0.TP -\fBfilesystem sync\fR\fI <path> \fR -Force a sync for the filesystem identified by \fI<path>\fR. +\fBfilesystem sync\fR \fI[-dq] [<path>]\fR +Force a sync for the filesystem identified by \fI<path>\fR, which defa= ults +to the current directory. Use the \fI-d\fR switch to wait for the dele= ted +subvolume cleaner thread to finish, and the \fI-q\fR switch to suppres= s +informational output. +.TP + +\fBfilesystem reclaim\fR\fI [path [timeout]] \fR +Wait for recovery of space from deleted +subvolumes on the filesystem containing \fIpath\fR, +which defaults to the current working directory, to complete. +The optional timeout parameter is a series of number[.number][letter] +components where the letter is one of wdhms for weeks, days, hours, mi= nutes, +seconds, defaulting to seconds. The default timeout is zero which mean= s +no timeout. 90, 1.5m, and PT1.5M all mean ninety seconds. + =C2=A0.TP =C2=A0.\" diff --git a/man/btrfsctl.8.in b/man/btrfsctl.8.in index c2d4488..890c625 100644 --- a/man/btrfsctl.8.in +++ b/man/btrfsctl.8.in @@ -10,6 +10,7 @@ btrfsctl \- control a btrfs filesystem =C2=A0[ \fB \-A\fP\fI device\fP ] =C2=A0[ \fB \-a\fP ] =C2=A0[ \fB \-c\fP ] +[ \fB \-C\fP\fI [timeout [directory]]\fP ] =C2=A0.SH DESCRIPTION =C2=A0.B btrfsctl =C2=A0is used to control the filesystem and the files and directories stored. It is the tool to create a new snapshot for the filesystem. @@ -35,6 +36,13 @@ Scans all devices present in the system for btrfs fi= lesystem. =C2=A0.TP =C2=A0\fB\-c\fR =C2=A0Forces a filesystem sync. +.TP +\fB\-C\fR \fI[timeout [directory]]\fR +Wait until all the space from all deleted snapshots has been recovered= =2E +The optional timeout parameter is seconds[.subseconds], or append "m" +for minutes[.subminutes]. "90", "90.000s", "T1.5M", and "1m30" all mea= n +the same thing. The default timeout is zero, which means do not time o= ut. +The optional directory parameter defaults to the current directory. =C2=A0.SH AVAILABILITY =C2=A0.B btrfsctl =C2=A0is part of btrfs-progs. Btrfs is currently under heavy developmen= t, --=20 =E2=80=9CThe aeroplane is fatally defective. It is merely a toy=E2=80=94= a sporting play-thing. =C2=A0It can never become commercially practical." -- Nikol= a Tesla -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" = in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: revised ioctl#21 btrfsprogs patch 2010-12-15 22:18 revised ioctl#21 btrfsprogs patch David Nicol @ 2010-12-24 19:52 ` David Nicol 0 siblings, 0 replies; 2+ messages in thread From: David Nicol @ 2010-12-24 19:52 UTC (permalink / raw) To: BTRFS MAILING LIST [-- Attachment #1: Type: text/plain, Size: 377 bytes --] Attached is another patch, that includes the new files, against a progs clone taken earlier today. It's attached, not in-line, because that seems better, as there are lines that wrap in-line. I have 2.6.35-24-generic_2.6.35-24.42_i386 Maverick kernel image and header debs available with the ioctl#21 feature in them too if anyone would like; e-mail me off-list for the link. [-- Attachment #2: 20101224.dln.patch --] [-- Type: text/x-diff, Size: 14796 bytes --] diff --git a/Makefile b/Makefile index 6e6f6c6..555da92 100644 --- a/Makefile +++ b/Makefile @@ -37,12 +37,13 @@ all: version $(progs) manpages version: bash version.sh -btrfs: $(objects) btrfs.o btrfs_cmds.o - gcc $(CFLAGS) -o btrfs btrfs.o btrfs_cmds.o \ +btrfs: $(objects) btrfs.o btrfs_cmds.o iso8601toms.o + gcc $(CFLAGS) -o btrfs btrfs.o btrfs_cmds.o iso8601toms.o \ $(objects) $(LDFLAGS) $(LIBS) -btrfsctl: $(objects) btrfsctl.o - gcc $(CFLAGS) -o btrfsctl btrfsctl.o $(objects) $(LDFLAGS) $(LIBS) +btrfsctl: $(objects) btrfsctl.o iso8601toms.o + gcc $(CFLAGS) -o btrfsctl btrfsctl.o iso8601toms.o \ + $(objects) $(LDFLAGS) $(LIBS) btrfs-vol: $(objects) btrfs-vol.o gcc $(CFLAGS) -o btrfs-vol btrfs-vol.o $(objects) $(LDFLAGS) $(LIBS) diff --git a/btrfs.c b/btrfs.c index 46314cf..6b3ebf6 100644 --- a/btrfs.c +++ b/btrfs.c @@ -29,6 +29,7 @@ struct Command { CommandFunction func; /* function which implements the command */ int nargs; /* if == 999, any number of arguments if >= 0, number of arguments, + if > 1000, 1000 more than the _maximum_ number of arguments, if < 0, _minimum_ number of arguments */ char *verb; /* verb */ char *help; /* help lines; form the 2nd onward they are @@ -73,14 +74,19 @@ static struct Command commands[] = { "Set the subvolume of the filesystem <path> which will be mounted\n" "as default." }, - { do_fssync, 1, - "filesystem sync", "<path>\n" - "Force a sync on the filesystem <path>." + { do_fssync, 1002, + "filesystem sync", "[-dq] <path>\n" + "Force a sync on the filesystem <path>, defaulting to '.'." + }, + { do_wait4clean, 1002, /* require at most two args */ + "filesystem reclaim", "[path [timeout]] \n" + "Wait for cleanup of deleted subvolumes. Path defaults to .\n" + "Timeout in seconds, or add m for minutes.\n" }, { do_resize, 2, "filesystem resize", "[+/-]<newsize>[gkm]|max <filesystem>\n" "Resize the file system. If 'max' is passed, the filesystem\n" - "will occupe all available space on the device." + "will occupy all available space on the device." }, { do_show_filesystem, 999, "filesystem show", "[<uuid>|<label>]\n" @@ -349,6 +355,15 @@ static int parse_args(int argc, char **argv, return -2; /* check the number of argument */ + + if(matchcmd->nargs > 1000 ){ + if ( matchcmd->nargs < (1000 + *nargs_)){ + fprintf(stderr, "ERROR: '%s' requires only %d or fewer arg(s)\n", + matchcmd->verb, matchcmd->nargs - 1000 ); + return -2; + } + } else { + if (matchcmd->nargs < 0 && matchcmd->nargs < -*nargs_ ){ fprintf(stderr, "ERROR: '%s' requires minimum %d arg(s)\n", matchcmd->verb, -matchcmd->nargs); @@ -359,7 +374,7 @@ static int parse_args(int argc, char **argv, matchcmd->verb, matchcmd->nargs); return -2; } - + } if (prepare_args( nargs_, args_, prgname, matchcmd )){ fprintf(stderr, "ERROR: not enough memory\\n"); return -20; diff --git a/btrfs_cmds.c b/btrfs_cmds.c index 8031c58..89f1f22 100644 --- a/btrfs_cmds.c +++ b/btrfs_cmds.c @@ -507,15 +507,37 @@ int do_create_subvol(int argc, char **argv) int do_fssync(int argc, char **argv) { int fd, res; - char *path = argv[1]; - + int cleanup=1, quiet=0; + char *path = ".", *p; /* [-dq] [<path>] */ + struct btrfs_ioctl_cleaner_wait_args w4c_arg; + + if (argc > 1){ + if (argv[1][0] == '-'){ + for (p=&argv[1][1]; *p; p++) switch (*p){ + case 'q': quiet++; break; + case 'd': cleanup++; break; + default: + fprintf(stderr, + "ERROR: unknown flag '%c' in '%s'\n", *p,argv[1]); + return 12; + }; + if (argc > 2) + path = argv[2]; + + }else{ + path = argv[1]; + + }; + + }; + while (cleanup--){ /* cleanup starts at 1 */ fd = open_file_or_dir(path); if (fd < 0) { fprintf(stderr, "ERROR: can't access to '%s'\n", path); return 12; } - printf("FSSync '%s'\n", path); + if (!quiet) printf("FSSync '%s'\n", path); res = ioctl(fd, BTRFS_IOC_SYNC); close(fd); if( res < 0 ){ @@ -523,6 +545,56 @@ int do_fssync(int argc, char **argv) return 16; } + if (cleanup){ + w4c_arg.ms = 0x00000000; + w4c_arg.flags = 0x00000000; + fd = open_file_or_dir(path); + if (fd < 0) { + fprintf(stderr, "ERROR: can't access to '%s'\n", path); + return 12; + } + if (!quiet) printf("reclaim: '%s'\n", path); + res = ioctl(fd, BTRFS_IOC_CLEANER_WAIT, &w4c_arg); + close(fd); + if( res != 0 ){ + fprintf(stderr, "%s:error #%i:%s\n", + path, errno,strerror(errno)); + return errno; + } + } + }; + return 0; +} + +#include "iso8601toms.h" + +int do_wait4clean(int argc, char **argv) +{ + int fd, res; + struct btrfs_ioctl_cleaner_wait_args w4c_arg; + + char *path = "."; + w4c_arg.ms = 0x00000000; + w4c_arg.flags = 0x00000000; + + if (argc > 1) + path = argv[1]; + if (argc > 2) + w4c_arg.ms = iso8601toms(argv[2]); + + fd = open_file_or_dir(path); + if (fd < 0) { + fprintf(stderr, "ERROR: can't open file or dir '%s'\n", path); + return 12; + } + res = ioctl(fd, BTRFS_IOC_CLEANER_WAIT, &w4c_arg); + close(fd); + if( res != 0 ){ + fprintf(stderr, "%s:error #%i:%s\n", + path, errno,strerror(errno)); + return errno; + } + return 0; } diff --git a/btrfs_cmds.h b/btrfs_cmds.h index 7bde191..c958338 100644 --- a/btrfs_cmds.h +++ b/btrfs_cmds.h @@ -19,6 +19,7 @@ int do_clone(int nargs, char **argv); int do_delete_subvolume(int nargs, char **argv); int do_create_subvol(int nargs, char **argv); int do_fssync(int nargs, char **argv); +int do_wait4clean(int nargs, char **argv); int do_defrag(int argc, char **argv); int do_show_filesystem(int nargs, char **argv); int do_add_volume(int nargs, char **args); diff --git a/btrfsctl.c b/btrfsctl.c index 92bdf39..cf7f69a 100644 --- a/btrfsctl.c +++ b/btrfsctl.c @@ -34,6 +34,7 @@ #include "ctree.h" #include "transaction.h" #include "utils.h" +#include "iso8601toms.h" #include "version.h" #ifdef __CHECKER__ @@ -57,6 +58,7 @@ static void print_usage(void) printf("\t-a: scans all devices for Btrfs filesystems\n"); printf("\t-c: forces a single FS sync\n"); printf("\t-D: delete snapshot\n"); + printf("\t-C [timeout [directory]]: wait for snapshot space recovery\n"); printf("\t-m [tree id] directory: set the default mounted subvolume" " to the [tree id] or the directory\n"); printf("%s\n", BTRFS_BUILD_VERSION); @@ -96,7 +98,7 @@ int main(int ac, char **av) char *fname = NULL; char *snap_location = NULL; int snap_fd = 0; - int fd; + int fd = -999; /* silence a warning */ int ret; struct btrfs_ioctl_vol_args args; char *name = NULL; @@ -106,6 +108,7 @@ int main(int ac, char **av) char *pos; char *fullpath; u64 objectid = 0; + struct btrfs_ioctl_cleaner_wait_args CWargs; if (ac == 2 && strcmp(av[1], "-a") == 0) { fprintf(stderr, "Scanning for Btrfs filesystems\n"); @@ -186,6 +189,11 @@ int main(int ac, char **av) fprintf(stderr, "-D size too long\n"); exit(1); } + } else if (strcmp(av[i], "-C") == 0) { + command = BTRFS_IOC_CLEANER_WAIT; + CWargs.ms = ( ac > (i+1) ? iso8601toms(av[i+1]) : 0x00000000 ); + CWargs.flags = 0x00000000; + name = ( ac > ( i+2 ) ? av[i + 2] : "." ); } else if (strcmp(av[i], "-A") == 0) { if (i >= ac - 1) { fprintf(stderr, "-A requires an arg\n"); @@ -232,7 +240,7 @@ int main(int ac, char **av) exit(1); } name = fname; - } else { + } else if (command != BTRFS_IOC_CLEANER_WAIT) { fd = open_file_or_dir(fname); } @@ -247,6 +255,9 @@ int main(int ac, char **av) } else if (command == BTRFS_IOC_DEFAULT_SUBVOL) { printf("objectid is %llu\n", objectid); ret = ioctl(fd, command, &objectid); + } else if (command == BTRFS_IOC_CLEANER_WAIT) { + fd = open_file_or_dir(name); + ret = ioctl(fd, command, &CWargs); } else ret = ioctl(fd, command, &args); if (ret < 0) { diff --git a/ioctl.h b/ioctl.h index 776d7a9..dc3f2fb 100644 --- a/ioctl.h +++ b/ioctl.h @@ -169,4 +169,11 @@ struct btrfs_ioctl_space_args { #define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64) #define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \ struct btrfs_ioctl_space_args) +struct btrfs_ioctl_cleaner_wait_args{ + __u32 ms; + __u32 flags; /* controls what to wait for, and stricture. Zero waits for subvol deletions. */ +}; +#define BTRFS_IOC_CLEANER_WAIT _IOW(BTRFS_IOCTL_MAGIC, 21, \ + struct btrfs_ioctl_cleaner_wait_args) #endif + diff --git a/iso8601toms.c b/iso8601toms.c new file mode 100644 index 0000000..0397aae --- /dev/null +++ b/iso8601toms.c @@ -0,0 +1,115 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +/*********** + + the following will correctly parse valid duration strings, + also it will accept a lot of invalid ones. + + it does: + + know all the ISO8601 letters + + accept a non-integer as the last numeric component + + always treats "m" as minutes + + it silently accepts: + + out of order duration type letters + + strings missing the leading P character + + lowercase duration type letters + + non-integers in any position + + it halts and catches fire on: + + P or p appearing somewhere besides the beginning of the string + + Attempts to use Years or Months + + unrecognized characters + + +***********/ + +#include <stdlib.h> +#include <stdio.h> +#include <asm/types.h> + +__u32 iso8601toms(char *P){ + unsigned long ms; + double component; + char *ptr; + char *endptr; + short M_min = 0; + ms = 0UL; + ptr = P; + for(;;){ + component=strtod(ptr, &endptr); + switch (*endptr) + { + case 'P': /* anchor */ case 'p': + if (ptr > P) + fprintf(stderr, "non-initial P " + "in duration string %s\n", P); + exit (-1); + case 'Y': /* year */ case 'y': + fprintf(stderr, "Years are not supported " + "in duration string %s\n", P); + exit (-1); + case 'T': /* Time (not date) anchor */ case 't': + M_min = 1; + break; + case 'W': /* week */ case 'w': + component *= 7; + case 'D': /* day */ case 'd': + component *= 24 ; + case 'H': /* hour */ case 'h': + component *= 60; + M_min = 1; + case 'M': /* month, or minute */ + if (M_min == 0 ){ + fprintf(stderr, "Months are not supported " + "in duration string %s\n" + "use 'm' instead or prefix a 'T'\n" + , P); + exit (-1); + }; + case 'm': /* minute */ + component *= 60; + case 'S': /* second */ case 's': + case '\0': /* default to second */ + component *= 1000; + ms += component; + break; + + default: + fprintf(stderr, + "unexpected char [%c] in duration string %s\n" + "valid designators are [WwDdHhMmSs] with implied trailing S.\n", + *endptr, P + ); + exit (-1); + }; + if (!*endptr) + return (ms); + ptr = 1+endptr; + }; +} + diff --git a/iso8601toms.h b/iso8601toms.h new file mode 100644 index 0000000..36c9537 --- /dev/null +++ b/iso8601toms.h @@ -0,0 +1,3 @@ +#include <asm/types.h> +__u32 iso8601toms(char *P); + diff --git a/man/btrfs.8.in b/man/btrfs.8.in index 26ef982..1bf1256 100644 --- a/man/btrfs.8.in +++ b/man/btrfs.8.in @@ -17,7 +17,9 @@ btrfs \- control a btrfs filesystem .PP \fBbtrfs\fP \fBfilesystem defrag\fP\fI <file>|<dir> [<file>|<dir>...]\fP .PP -\fBbtrfs\fP \fBfilesystem sync\fP\fI <path> \fP +\fBbtrfs\fP \fBfilesystem sync\fP\fI [-dq] [<path>] \fP +.PP +\fBbtrfs\fP \fBfilesystem reclaim\fP\fI [<path> [<timeout>]] \fP .PP \fBbtrfs\fP \fBfilesystem resize\fP\fI [+/\-]<size>[gkm]|max <filesystem>\fP .PP @@ -111,8 +113,21 @@ Scan devices for a btrfs filesystem. If no devices are passed, \fBbtrfs\fR scans all the block devices. .TP -\fBfilesystem sync\fR\fI <path> \fR -Force a sync for the filesystem identified by \fI<path>\fR. +\fBfilesystem sync\fR\fI [-dq] [<path>] \fR +Force a sync for the filesystem identified by \fI<path>\fR, +which defaults to the current directory. Use the -d switch +to wait for the subvolume cleaner thread to finish, use the +-q switch to suppress informational output. +.TP + +\fBfilesystem reclaim\fR\fI [<path> [<timeout>]] \fR +Wait for the backgrounded recovery of space from deleted +subvolumes, if any, to complete. The optional path +defaults to the current working directory, and the +timeout defaults to indefinately. The timeout is in +seconds, but can also take a [WDHmS] suffix meaning +weeks, days, hours, minutes, or explicit seconds, loosely +following the ISO8601 standard for durations. .TP .\" diff --git a/man/btrfsctl.8.in b/man/btrfsctl.8.in index c2d4488..eeed516 100644 --- a/man/btrfsctl.8.in +++ b/man/btrfsctl.8.in @@ -10,6 +10,7 @@ btrfsctl \- control a btrfs filesystem [ \fB \-A\fP\fI device\fP ] [ \fB \-a\fP ] [ \fB \-c\fP ] +[ \fB \-C\fP\fI [timeout [directory]]\fP ] .SH DESCRIPTION .B btrfsctl is used to control the filesystem and the files and directories stored. It is the tool to create a new snapshot for the filesystem. @@ -35,6 +36,11 @@ Scans all devices present in the system for btrfs filesystem. .TP \fB\-c\fR Forces a filesystem sync. +.TP +\fB \-C\fR\fI [timeout [directory]]\fR +Wait for backgrounded subvolume deletions to complete. The optional timeout +parameter loosely follows ISO8601. the optional directory defaults to +the current working directory. .SH AVAILABILITY .B btrfsctl is part of btrfs-progs. Btrfs is currently under heavy development, ^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-12-24 19:52 UTC | newest] Thread overview: 2+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-12-15 22:18 revised ioctl#21 btrfsprogs patch David Nicol 2010-12-24 19:52 ` David Nicol
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).