From: Jeff Mahoney Date: Wed, 18 May 2016 22:09:40 +0000 (-0400) Subject: ioctl: add decoding for FS_IOC_FIEMAP X-Git-Tag: v4.12~98 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=398fe0493ee0da44fecd98d0c72fab3627060953;p=strace ioctl: add decoding for FS_IOC_FIEMAP * file_ioctl.c: Include , "xlat/fiemap_flags.h", and "xlat/fiemap_extent_flags.h". (file_ioctl): Handle FS_IOC_FIEMAP. * ioctl.c (ioctl_decode): Use file_ioctl for decoding 'f' code ioctls. --- diff --git a/file_ioctl.c b/file_ioctl.c index 3a735dc4..c803576e 100644 --- a/file_ioctl.c +++ b/file_ioctl.c @@ -28,6 +28,11 @@ #include "defs.h" #include #include +#include + +#include "xlat/fiemap_flags.h" +#include "xlat/fiemap_extent_flags.h" + #ifndef FICLONE #define FICLONE _IOW(0x94, 9, int) #endif @@ -154,6 +159,69 @@ file_ioctl(struct tcb *tcp, const unsigned int code, const long arg) break; } + case FS_IOC_FIEMAP: { + struct fiemap args; + struct fiemap_extent fe; + unsigned int i; + + if (entering(tcp)) + tprints(", "); + else if (syserror(tcp)) + break; + else + tprints(" => "); + + if (umove_or_printaddr(tcp, arg, &args)) + break; + + if (entering(tcp)) { + tprintf("{fm_start=%" PRI__u64 ", " + "fm_length=%" PRI__u64 ", " + "fm_flags=", + args.fm_start, args.fm_length); + printflags64(fiemap_flags, args.fm_flags, + "FIEMAP_FLAG_???"); + tprintf(", fm_extent_count=%u}", args.fm_extent_count); + return 0; + } + + tprints("{fm_flags="); + printflags64(fiemap_flags, args.fm_flags, + "FIEMAP_FLAG_???"); + tprintf(", fm_mapped_extents=%u", + args.fm_mapped_extents); + tprints(", fm_extents="); + if (abbrev(tcp)) { + tprints("...}"); + break; + } + + tprints("["); + for (i = 0; i < args.fm_mapped_extents; i++) { + unsigned long offset; + offset = offsetof(typeof(args), fm_extents[i]); + if (i) + tprints(", "); + + if (i > max_strlen || + umoven(tcp, arg + offset, sizeof(fe), &fe)) { + tprints("..."); + break; + } + + tprintf("{fe_logical=%" PRI__u64 + ", fe_physical=%" PRI__u64 + ", fe_length=%" PRI__u64 ", ", + fe.fe_logical, fe.fe_physical, fe.fe_length); + + printflags64(fiemap_extent_flags, fe.fe_flags, + "FIEMAP_EXTENT_???"); + tprints("}"); + } + tprints("]}"); + break; + } + default: return RVAL_DECODED; }; diff --git a/ioctl.c b/ioctl.c index d82af4b9..f6ca2f0a 100644 --- a/ioctl.c +++ b/ioctl.c @@ -228,11 +228,20 @@ ioctl_decode(struct tcb *tcp) { const unsigned int code = tcp->u_arg[1]; const long arg = tcp->u_arg[2]; + int ret; switch (_IOC_TYPE(code)) { #if defined(ALPHA) || defined(POWERPC) - case 'f': case 't': case 'T': + case 'f': + ret = file_ioctl(tcp, code, arg); + if (ret != RVAL_DECODED) + return ret; + case 't' + case 'T': + return term_ioctl(tcp, code, arg); #else /* !ALPHA */ + case 'f': + return file_ioctl(tcp, code, arg); case 0x54: #endif /* !ALPHA */ return term_ioctl(tcp, code, arg);