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