Filipe Brandenburger
2013-Jan-29 06:06 UTC
[PATCH 0/3] strace: Add support for Btrfs ioctls
Hi,
This is a patch to strace!!! Not btrfs-next or btrfs-progs. I just wanted to
circulate it on this list before submitting it to the strace maintainers.
It also depends on "[PATCH] Btrfs: move fs/btrfs/ioctl.h to
include/uapi/linux/btrfs.h" being committed as that''s what will
export
linux/btrfs.h to userspace and this patch to strace depends on that file.
I added a patch decoding a specific ioctl to have an idea of whether the output
format is good or should be tweaked differently. I opted to be a bit more
verbose but increase readability. I also ended up deciding to truncate the
output to show at most 10 results, not sure if that''s OK or should be
configurable somewhere (maybe I can tap into strace''s "-s"
parameter to
estimate the size of output allowable?)
Without the patch:
$ strace -e ioctl btrfs fi df .
ioctl(3, 0xc0109414, 0x195b040) = 0
ioctl(3, 0xc0109414, 0x195b040) = 0
Data: total=1.01GB, used=4.87MB
System, DUP: total=8.00MB, used=4.00KB
System: total=4.00MB, used=0.00
Metadata, DUP: total=1.75GB, used=1.38GB
Metadata: total=8.00MB, used=0.00
+++ exited with 0 +++
With the patch:
$ strace -e ioctl btrfs fi df .
ioctl(3, BTRFS_IOC_SPACE_INFO, {space_slots=0, total_spaces=5}) = 0
ioctl(3, BTRFS_IOC_SPACE_INFO, {space_slots=5, total_spaces=5,
spaces={[0]={flags=0x1 /* BTRFS_BLOCK_GROUP_DATA */, total_bytes=1081999360,
used_bytes=5107712}, [1]={flags=0x22 /*
BTRFS_BLOCK_GROUP_SYSTEM|BTRFS_BLOCK_GROUP_DUP */, total_bytes=8388608,
used_bytes=4096}, [2]={flags=0x2 /* BTRFS_BLOCK_GROUP_SYSTEM */,
total_bytes=4194304, used_bytes=0}, [3]={flags=0x24 /*
BTRFS_BLOCK_GROUP_METADATA|BTRFS_BLOCK_GROUP_DUP */, total_bytes=1878982656,
used_bytes=1485590528}, [4]={flags=0x4 /* BTRFS_BLOCK_GROUP_METADATA */,
total_bytes=8388608, used_bytes=0}}}) = 0
Data: total=1.01GB, used=4.87MB
System, DUP: total=8.00MB, used=4.00KB
System: total=4.00MB, used=0.00
Metadata, DUP: total=1.75GB, used=1.38GB
Metadata: total=8.00MB, used=0.00
+++ exited with 0 +++
Any comments? Or do you think this is good enough? Before submitting to the
strace project I''d like to review the constants and structs that need
to be in
linux/btrfs.h and move them there (which should be further commits to
btrfs-next) so that I don''t need to duplicate them there, but before I
do that
I''d like to have some feedback if you think this is the right approach.
Thanks!
Filipe
Filipe Brandenburger (3):
Add support for Btrfs ioctls: decode them by name
Add support for Btrfs ioctls: infrastructure to decode ioctl structs
Add support for Btrfs ioctls: BTRFS_IOC_SPACE_INFO (filesystem df)
Makefile.am | 2 +-
btrfs.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 1 +
defs.h | 1 +
ioctl.c | 2 +
linux/ioctlent.h.in | 44 +++++++++++++++
6 files changed, 208 insertions(+), 1 deletion(-)
create mode 100644 btrfs.c
--
1.7.11.7
--
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
Filipe Brandenburger
2013-Jan-29 06:06 UTC
[PATCH 1/3] Add support for Btrfs ioctls: decode them by name
This patch will include Btrfs-specific ioctls from linux/btrfs.h into
ioctlent.h.in so that they get translated by strace. That''s useful for
using
strace to debug the tools in btrfs-progs.
Signed-off-by: Filipe Brandenburger <filbranden@google.com>
---
linux/ioctlent.h.in | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/linux/ioctlent.h.in b/linux/ioctlent.h.in
index 8843b47..06a5300 100644
--- a/linux/ioctlent.h.in
+++ b/linux/ioctlent.h.in
@@ -1825,6 +1825,50 @@
{"linux/auto_fs4.h", "AUTOFS_IOC_EXPIRE_MULTI", 0x9366},
{"linux/auto_fs4.h", "AUTOFS_IOC_PROTOSUBVER", 0x9367},
{"linux/auto_fs4.h", "AUTOFS_IOC_ASKUMOUNT", 0x9370},
+ {"linux/btrfs.h", "BTRFS_IOC_SNAP_CREATE", 0x9401},
+ {"linux/btrfs.h", "BTRFS_IOC_DEFRAG", 0x9402},
+ {"linux/btrfs.h", "BTRFS_IOC_RESIZE", 0x9403},
+ {"linux/btrfs.h", "BTRFS_IOC_SCAN_DEV", 0x9404},
+ {"linux/btrfs.h", "BTRFS_IOC_TRANS_START", 0x9406},
+ {"linux/btrfs.h", "BTRFS_IOC_TRANS_END", 0x9407},
+ {"linux/btrfs.h", "BTRFS_IOC_SYNC", 0x9408},
+ {"linux/btrfs.h", "BTRFS_IOC_CLONE", 0x9409},
+ {"linux/btrfs.h", "BTRFS_IOC_ADD_DEV", 0x940a},
+ {"linux/btrfs.h", "BTRFS_IOC_RM_DEV", 0x940b},
+ {"linux/btrfs.h", "BTRFS_IOC_BALANCE", 0x940c},
+ {"linux/btrfs.h", "BTRFS_IOC_CLONE_RANGE", 0x940d},
+ {"linux/btrfs.h", "BTRFS_IOC_SUBVOL_CREATE", 0x940e},
+ {"linux/btrfs.h", "BTRFS_IOC_SNAP_DESTROY", 0x940f},
+ {"linux/btrfs.h", "BTRFS_IOC_DEFRAG_RANGE", 0x9410},
+ {"linux/btrfs.h", "BTRFS_IOC_TREE_SEARCH", 0x9411},
+ {"linux/btrfs.h", "BTRFS_IOC_INO_LOOKUP", 0x9412},
+ {"linux/btrfs.h", "BTRFS_IOC_DEFAULT_SUBVOL", 0x9413},
+ {"linux/btrfs.h", "BTRFS_IOC_SPACE_INFO", 0x9414},
+ {"linux/btrfs.h", "BTRFS_IOC_WAIT_SYNC", 0x9416},
+ {"linux/btrfs.h", "BTRFS_IOC_SNAP_CREATE_V2", 0x9417},
+ {"linux/btrfs.h", "BTRFS_IOC_START_SYNC", 0x9418},
+ {"linux/btrfs.h", "BTRFS_IOC_SUBVOL_CREATE_V2", 0x9418},
+ {"linux/btrfs.h", "BTRFS_IOC_SUBVOL_GETFLAGS", 0x9419},
+ {"linux/btrfs.h", "BTRFS_IOC_SUBVOL_SETFLAGS", 0x941a},
+ {"linux/btrfs.h", "BTRFS_IOC_SCRUB", 0x941b},
+ {"linux/btrfs.h", "BTRFS_IOC_SCRUB_CANCEL", 0x941c},
+ {"linux/btrfs.h", "BTRFS_IOC_SCRUB_PROGRESS", 0x941d},
+ {"linux/btrfs.h", "BTRFS_IOC_DEV_INFO", 0x941e},
+ {"linux/btrfs.h", "BTRFS_IOC_FS_INFO", 0x941f},
+ {"linux/btrfs.h", "BTRFS_IOC_BALANCE_V2", 0x9420},
+ {"linux/btrfs.h", "BTRFS_IOC_BALANCE_CTL", 0x9421},
+ {"linux/btrfs.h", "BTRFS_IOC_BALANCE_PROGRESS", 0x9422},
+ {"linux/btrfs.h", "BTRFS_IOC_INO_PATHS", 0x9423},
+ {"linux/btrfs.h", "BTRFS_IOC_LOGICAL_INO", 0x9424},
+ {"linux/btrfs.h", "BTRFS_IOC_SET_RECEIVED_SUBVOL",
0x9425},
+ {"linux/btrfs.h", "BTRFS_IOC_SEND", 0x9426},
+ {"linux/btrfs.h", "BTRFS_IOC_DEVICES_READY", 0x9427},
+ {"linux/btrfs.h", "BTRFS_IOC_QUOTA_CTL", 0x9428},
+ {"linux/btrfs.h", "BTRFS_IOC_QGROUP_ASSIGN", 0x9429},
+ {"linux/btrfs.h", "BTRFS_IOC_QGROUP_CREATE", 0x942a},
+ {"linux/btrfs.h", "BTRFS_IOC_QGROUP_LIMIT", 0x942b},
+ {"linux/btrfs.h", "BTRFS_IOC_GET_DEV_STATS", 0x9434},
+ {"linux/btrfs.h", "BTRFS_IOC_DEV_REPLACE", 0x9435},
{"linux/nbd.h", "NBD_SET_SOCK", 0xab00},
{"linux/nbd.h", "NBD_SET_BLKSIZE", 0xab01},
{"linux/nbd.h", "NBD_SET_SIZE", 0xab02},
--
1.7.11.7
--
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
Filipe Brandenburger
2013-Jan-29 06:06 UTC
[PATCH 2/3] Add support for Btrfs ioctls: infrastructure to decode ioctl structs
This adds a new btrfs_ioctl() function that can be used to decode Btrfs structs
from Btrfs-specific ioctls. It adds a new case to ioctl_decode() to handle
Btrfs ioctls.
This adds autoconf detection of header file linux/btrfs.h so that the code can
be disabled when the header is not present.
Signed-off-by: Filipe Brandenburger <filbranden@google.com>
---
Makefile.am | 2 +-
btrfs.c | 39 +++++++++++++++++++++++++++++++++++++++
configure.ac | 1 +
defs.h | 1 +
ioctl.c | 2 ++
5 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 btrfs.c
diff --git a/Makefile.am b/Makefile.am
index aa1a5f4..fe809b8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -18,7 +18,7 @@ strace_SOURCES = strace.c syscall.c count.c util.c desc.c
file.c ipc.c \
io.c ioctl.c mem.c net.c process.c bjm.c quota.c \
resource.c signal.c sock.c system.c term.c time.c \
scsi.c stream.c block.c pathtrace.c mtd.c vsprintf.c \
- loop.c
+ loop.c btrfs.c
noinst_HEADERS = defs.h
EXTRA_DIST = $(man_MANS) errnoent.sh signalent.sh syscallent.sh ioctlsort.c \
diff --git a/btrfs.c b/btrfs.c
new file mode 100644
index 0000000..a4895e4
--- /dev/null
+++ b/btrfs.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013 Filipe Brandenburger <filbranden@google.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'''' AND ANY
EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "defs.h"
+#include <sys/ioctl.h>
+
+#ifdef HAVE_LINUX_BTRFS_H
+#include <linux/btrfs.h>
+#endif /* HAVE_LINUX_BTRFS_H */
+
+int
+btrfs_ioctl(struct tcb *tcp, long code, long arg)
+{
+ return 0;
+}
diff --git a/configure.ac b/configure.ac
index f44eaf1..9021fe1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -222,6 +222,7 @@ AC_CHECK_HEADERS([asm/sigcontext.h], [], [], [#include
<signal.h>])
AC_CHECK_TYPES([struct sigcontext_struct,
struct sigcontext],,, [#include <signal.h>])
AC_CHECK_HEADERS([netinet/tcp.h netinet/udp.h],,, [#include
<netinet/in.h>])
+AC_CHECK_HEADERS([linux/btrfs.h])
AC_CHECK_MEMBERS([struct msghdr.msg_control],,, [#include
<sys/socket.h>])
diff --git a/defs.h b/defs.h
index 0e05c6e..9270786 100644
--- a/defs.h
+++ b/defs.h
@@ -631,6 +631,7 @@ extern int scsi_ioctl(struct tcb *, long, long);
extern int block_ioctl(struct tcb *, long, long);
extern int mtd_ioctl(struct tcb *, long, long);
extern int loop_ioctl(struct tcb *, long, long);
+extern int btrfs_ioctl(struct tcb *, long, long);
extern int tv_nz(struct timeval *);
extern int tv_cmp(struct timeval *, struct timeval *);
diff --git a/ioctl.c b/ioctl.c
index 323946d..6c39fc0 100644
--- a/ioctl.c
+++ b/ioctl.c
@@ -92,6 +92,8 @@ ioctl_decode(struct tcb *tcp, long code, long arg)
return loop_ioctl(tcp, code, arg);
case ''M'':
return mtd_ioctl(tcp, code, arg);
+ case 0x94:
+ return btrfs_ioctl(tcp, code, arg);
default:
break;
}
--
1.7.11.7
--
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
Filipe Brandenburger
2013-Jan-29 06:06 UTC
[PATCH 3/3] Add support for Btrfs ioctls: BTRFS_IOC_SPACE_INFO (filesystem df)
This adds support for the BTRFS_IOC_SPACE_INFO (used by `btrfs filesystem
df'')
by parsing the struct passed by userspace to the kernel and interpreting the
output fields filled in by kernel code.
TODO: Some constants are defined in the C file because they''re not
currently
present in linux/btrfs.h, but they should be moved to that file in Btrfs source
code so that they can be used by userspace programs that need those constants.
Signed-off-by: Filipe Brandenburger <filbranden@google.com>
---
btrfs.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 120 insertions(+)
diff --git a/btrfs.c b/btrfs.c
index a4895e4..799ae46 100644
--- a/btrfs.c
+++ b/btrfs.c
@@ -30,10 +30,130 @@
#ifdef HAVE_LINUX_BTRFS_H
#include <linux/btrfs.h>
+
+/* TODO: in btrfs source code, these are currently in ctree.h, must be moved to
btrfs.h */
+#ifndef BTRFS_BLOCK_GROUP_DATA
+#define BTRFS_BLOCK_GROUP_DATA (1ULL << 0)
+#define BTRFS_BLOCK_GROUP_SYSTEM (1ULL << 1)
+#define BTRFS_BLOCK_GROUP_METADATA (1ULL << 2)
+#define BTRFS_BLOCK_GROUP_RAID0 (1ULL << 3)
+#define BTRFS_BLOCK_GROUP_RAID1 (1ULL << 4)
+#define BTRFS_BLOCK_GROUP_DUP (1ULL << 5)
+#define BTRFS_BLOCK_GROUP_RAID10 (1ULL << 6)
+#endif /* BTRFS_BLOCK_GROUP_DATA */
+
+static const struct xlat btrfs_space_info_flags[] = {
+ {BTRFS_BLOCK_GROUP_DATA, "BTRFS_BLOCK_GROUP_DATA"},
+ {BTRFS_BLOCK_GROUP_SYSTEM, "BTRFS_BLOCK_GROUP_SYSTEM"},
+ {BTRFS_BLOCK_GROUP_METADATA, "BTRFS_BLOCK_GROUP_METADATA"},
+ {BTRFS_BLOCK_GROUP_RAID0, "BTRFS_BLOCK_GROUP_RAID0"},
+ {BTRFS_BLOCK_GROUP_RAID1, "BTRFS_BLOCK_GROUP_RAID1"},
+ {BTRFS_BLOCK_GROUP_DUP, "BTRFS_BLOCK_GROUP_DUP"},
+ {BTRFS_BLOCK_GROUP_RAID10, "BTRFS_BLOCK_GROUP_RAID10"},
+ {0, NULL}
+};
+
+static void
+print_space_info(struct btrfs_ioctl_space_info *si)
+{
+ __u64 flags;
+ int first;
+ const struct xlat *xl;
+
+ flags = si->flags;
+ tprintf("{flags=%#llx", flags);
+ first = 1;
+ for (xl = btrfs_space_info_flags; flags && xl->val; xl++) {
+ if (flags & xl->val) {
+ if (first)
+ tprints(" /* ");
+ else
+ tprints("|");
+ first = 0;
+ tprints(xl->str);
+ flags &= ~xl->val;
+ }
+ }
+ if (!first) {
+ /* flags were expanded at least once */
+ if (flags)
+ tprintf("|%#llx */", flags);
+ else
+ tprints(" */");
+ }
+ tprintf(", total_bytes=%llu, used_bytes=%llu}", si->total_bytes,
si->used_bytes);
+}
+
+static void
+print_space_args_out(struct tcb *tcp, long arg)
+{
+ struct btrfs_ioctl_space_args sa, *sa_ptr;
+ __u64 i, total;
+ int truncated;
+ long sa_size;
+
+ if (syserror(tcp) || umove(tcp, arg, &sa) < 0)
+ return;
+
+ total = sa.total_spaces;
+ tprintf(", total_spaces=%llu", total);
+ if (total > sa.space_slots)
+ total = sa.space_slots;
+ if (total <= 0)
+ return;
+ /* if total > 10 then truncate it */
+ truncated = 0;
+ if (total > 10) {
+ total = 10;
+ truncated = 1;
+ }
+
+ sa_size = sizeof(struct btrfs_ioctl_space_args) + total * sizeof(struct
btrfs_ioctl_space_info);
+ sa_ptr = malloc(sa_size);
+ if (!sa_ptr)
+ return;
+
+ if (umoven(tcp, arg, sa_size, (char *) sa_ptr) < 0)
+ goto out;
+
+ tprints(", spaces={");
+ for (i = 0L; i < total; i++) {
+ if (i)
+ tprints(", ");
+ tprintf("[%llu]=", i);
+ print_space_info(&sa_ptr->spaces[i]);
+ }
+ if (truncated)
+ tprints(", ...");
+ tprints("}");
+
+out:
+ free(sa_ptr);
+}
+
#endif /* HAVE_LINUX_BTRFS_H */
int
btrfs_ioctl(struct tcb *tcp, long code, long arg)
{
+#ifdef HAVE_LINUX_BTRFS_H
+ switch (code) {
+ case BTRFS_IOC_SPACE_INFO:
+ if (entering(tcp)) {
+ struct btrfs_ioctl_space_args sa;
+ if (umove(tcp, arg, &sa) < 0)
+ tprintf(", %#lx", arg);
+ else {
+ tprintf(", {space_slots=%llu", sa.space_slots);
+ }
+ }
+ if (exiting(tcp)) {
+ print_space_args_out(tcp, arg);
+ tprints("}");
+ }
+ return 1;
+ }
+#endif /* HAVE_LINUX_BTRFS_H */
+
return 0;
}
--
1.7.11.7
--
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