linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* 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).