]> granicus.if.org Git - strace/commitdiff
ioctl: add decoding for FS_IOC_FIEMAP
authorJeff Mahoney <jeffm@suse.com>
Wed, 18 May 2016 22:09:40 +0000 (18:09 -0400)
committerDmitry V. Levin <ldv@altlinux.org>
Tue, 24 May 2016 14:52:27 +0000 (14:52 +0000)
* file_ioctl.c: Include <linux/fiemap.h>, "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.

file_ioctl.c
ioctl.c

index 3a735dc49a6e5478250ec88e184f88921d4f3b59..c803576e9badb99bc4f1d692b496d6a24d1419b5 100644 (file)
 #include "defs.h"
 #include <sys/ioctl.h>
 #include <linux/fs.h>
+#include <linux/fiemap.h>
+
+#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 d82af4b9e850a274f133f63b09fd3d82a21f0358..f6ca2f0a5abbf1ad5c5705aef30aac46200c8f81 100644 (file)
--- 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);