diff -urN strace-4.5.20-orig/Makefile.am strace-4.5.20/Makefile.am
--- strace-4.5.20-orig/Makefile.am	2010-04-07 19:17:50 +0900
+++ strace-4.5.20/Makefile.am	2010-04-17 11:23:00 +0900
@@ -18,6 +18,8 @@
 		 proc.c scsi.c stream.c
 noinst_HEADERS = defs.h
 
+strace_SOURCES += loop.c
+
 EXTRA_DIST = $(man_MANS) errnoent.sh signalent.sh syscallent.sh ioctlsort.c \
 	     debian/changelog debian/control debian/copyright debian/rules \
 	     debian/compat debian/strace64.install debian/strace64.manpages \
diff -urN strace-4.5.20-orig/Makefile.in strace-4.5.20/Makefile.in
--- strace-4.5.20-orig/Makefile.in	2010-04-15 04:41:05 +0900
+++ strace-4.5.20/Makefile.in	2010-04-17 11:23:00 +0900
@@ -66,6 +66,7 @@
 	system.$(OBJEXT) term.$(OBJEXT) time.$(OBJEXT) proc.$(OBJEXT) \
 	scsi.$(OBJEXT) stream.$(OBJEXT)
 strace_OBJECTS = $(am_strace_OBJECTS)
+am_strace_OBJECTS += loop.$(OBJEXT)
 strace_LDADD = $(LDADD)
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
@@ -230,6 +231,7 @@
 		 proc.c scsi.c stream.c
 
 noinst_HEADERS = defs.h
+strace_SOURCES += loop.c
 EXTRA_DIST = $(man_MANS) errnoent.sh signalent.sh syscallent.sh ioctlsort.c \
 	     debian/changelog debian/control debian/copyright debian/rules \
 	     debian/compat debian/strace64.install debian/strace64.manpages \
@@ -447,6 +449,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ioctl.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc.Po@am__quote@
diff -urN strace-4.5.20-orig/defs.h strace-4.5.20/defs.h
--- strace-4.5.20-orig/defs.h	2010-04-07 19:19:26 +0900
+++ strace-4.5.20/defs.h	2010-04-17 11:17:01 +0900
@@ -548,6 +548,7 @@
 extern int proc_ioctl(struct tcb *, int, int);
 extern int stream_ioctl(struct tcb *, int, int);
 #ifdef LINUX
+extern int loop_ioctl(struct tcb *, int, int);
 extern int rtc_ioctl(struct tcb *, long, long);
 extern int scsi_ioctl(struct tcb *, long, long);
 #endif
diff -urN strace-4.5.20-orig/ioctl.c strace-4.5.20/ioctl.c
--- strace-4.5.20-orig/ioctl.c	2007-06-30 20:37:09 +0900
+++ strace-4.5.20/ioctl.c	2010-04-17 11:23:00 +0900
@@ -150,6 +150,8 @@
 		return stream_ioctl(tcp, code, arg);
 #endif /* HAVE_SYS_STREAM_H */
 #ifdef LINUX
+	case 'L':
+		return loop_ioctl(tcp, code, arg);
 	case 'p':
 		return rtc_ioctl(tcp, code, arg);
 	case 0x22:
diff -urN strace-4.5.20-orig/linux/ioctlent.h strace-4.5.20/linux/ioctlent.h
--- strace-4.5.20-orig/linux/ioctlent.h	2010-04-07 20:34:29 +0900
+++ strace-4.5.20/linux/ioctlent.h	2010-04-17 11:15:42 +0900
@@ -310,6 +310,13 @@
 	{"linux/kd.h",	"KDFONTOP",	0x4b72},
 	{"linux/kd.h",	"KDGKBDIACRUC",	0x4bfa},
 	{"linux/kd.h",	"KDSKBDIACRUC",	0x4bfb},
+	{"linux/loop.h",	"LOOP_SET_FD",	0x4c00},
+	{"linux/loop.h",	"LOOP_CLR_FD",	0x4c01},
+	{"linux/loop.h",	"LOOP_SET_STATUS",	0x4c02},
+	{"linux/loop.h",	"LOOP_GET_STATUS",	0x4c03},
+	{"linux/loop.h",	"LOOP_SET_STATUS64",	0x4c04},
+	{"linux/loop.h",	"LOOP_GET_STATUS64",	0x4c05},
+	{"linux/loop.h",	"LOOP_CHANGE_FD",	0x4c06},
 	{"asm/mtrr.h",	"MTRRIOC_ADD_ENTRY",	0x4d00},
 	{"asm/mce.h",	"MCE_GET_RECORD_LEN",	0x4d01},
 	{"asm/mtrr.h",	"MTRRIOC_SET_ENTRY",	0x4d01},
diff -urN strace-4.5.20-orig/loop.c strace-4.5.20/loop.c
--- strace-4.5.20-orig/loop.c	1970-01-01 09:00:00 +0900
+++ strace-4.5.20/loop.c	2010-04-17 11:23:00 +0900
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2004 Andrew Church <achurch@achurch.org>
+ * 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.
+ *
+ *	$Id: $
+ */
+
+#include "defs.h"
+
+#ifdef LINUX
+
+#include <linux/loop.h>
+
+static struct xlat loop_flags[] = {
+	{ LO_FLAGS_READ_ONLY, "LO_FLAGS_READ_ONLY" },
+	{ 0, NULL }
+};
+
+static struct xlat loop_crypt[] = {
+	{ LO_CRYPT_NONE,      "LO_CRYPT_NONE" },
+	{ LO_CRYPT_XOR,       "LO_CRYPT_XOR" },
+	{ LO_CRYPT_DES,       "LO_CRYPT_DES" },
+	{ LO_CRYPT_FISH2,     "LO_CRYPT_FISH2" },
+	{ LO_CRYPT_BLOW,      "LO_CRYPT_BLOW" },
+	{ LO_CRYPT_CAST128,   "LO_CRYPT_CAST128" },
+	{ LO_CRYPT_IDEA,      "LO_CRYPT_IDEA" },
+	{ LO_CRYPT_DUMMY,     "LO_CRYPT_DUMMY" },
+	{ LO_CRYPT_SKIPJACK,  "LO_CRYPT_SKIPJACK" },
+	{ LO_CRYPT_CRYPTOAPI, "LO_CRYPT_CRYPTOAPI" },
+	{ 0, NULL }
+};
+
+static void
+printstr_loop(const unsigned char *s, int len, int maxlen)
+{
+	int i;
+
+	if (len > maxlen)
+		len = maxlen;
+	tprintf("\"");
+	for (i = 0; len>=0 ? i<len : s[i] && i<maxlen; i++) {
+		if (isprint(s[i]))
+			tprintf("%c", s[i]);
+		else
+			tprintf("\\x%02x", s[i]);
+	}
+	tprintf("\"");
+}
+
+int
+loop_ioctl(struct tcb *tcp, int code, int arg)
+{
+	struct loop_info li;
+	struct loop_info64 li64;
+
+	switch (code) {
+	case LOOP_CLR_FD:
+		/* no argument */
+		return 1;
+	case LOOP_SET_FD:
+	case LOOP_CHANGE_FD:
+		/* FD argument */
+		if (entering(tcp))
+			tprintf(", %d", arg);
+		return 1;
+	case LOOP_SET_STATUS:
+	case LOOP_GET_STATUS:
+		if (code == LOOP_GET_STATUS && entering(tcp))
+			return 0;
+		else if (code == LOOP_SET_STATUS && !entering(tcp))
+			return 1;
+		if (arg == 0)
+			tprintf(", NULL");
+		else if (syserror(tcp))
+			tprintf(", %#x", arg);
+		else if (umove(tcp, arg, &li) < 0)
+			tprintf(", {...}");
+		else {
+			tprintf(", {");
+			if (code == LOOP_GET_STATUS) {
+				tprintf("lo_number=%d, ", li.lo_number);
+				tprintf("lo_device=makedev(%lu, %lu), ",
+					(unsigned long)major(li.lo_device),
+					(unsigned long)minor(li.lo_device));
+				tprintf("lo_inode=%lu, ", li.lo_inode);
+				tprintf("lo_rdevice=makedev(%lu, %lu), ",
+					(unsigned long)major(li.lo_rdevice),
+					(unsigned long)minor(li.lo_rdevice));
+				tprintf("lo_flags=");
+				if (!printflags(loop_flags, li.lo_flags, "LO_FLAGS_???"))
+					tprintf("0");
+				tprintf(", ");
+			}
+			tprintf("lo_offset=%d", li.lo_offset);
+			tprintf(", lo_encrypt_type=");
+			printxval(loop_crypt, li.lo_encrypt_type,
+				  "LO_CRYPT_???");
+			if (code == LOOP_SET_STATUS) {
+				tprintf(", lo_encrypt_key_size=%d",
+					li.lo_encrypt_key_size);
+				tprintf(", lo_encrypt_key=");
+				printstr_loop(li.lo_encrypt_key,
+					      li.lo_encrypt_key_size,
+					      LO_KEY_SIZE);
+			}
+			tprintf(", lo_name=");
+			printstr_loop((char *)li.lo_name, -1, LO_NAME_SIZE);
+			tprintf(", ...}");
+		}
+		return 1;
+	case LOOP_SET_STATUS64:
+	case LOOP_GET_STATUS64:
+		if (code == LOOP_GET_STATUS64 && entering(tcp))
+			return 0;
+		else if (code == LOOP_SET_STATUS64 && !entering(tcp))
+			return 1;
+		if (arg == 0)
+			tprintf(", NULL");
+		else if (syserror(tcp))
+			tprintf(", %#x", arg);
+		else if (umove(tcp, arg, &li64) < 0)
+			tprintf(", {...}");
+		else {
+			tprintf(", {");
+			if (code == LOOP_GET_STATUS64) {
+				tprintf("lo_number=%ld, ",
+					(unsigned long)li64.lo_number);
+				tprintf("lo_device=makedev(%lu, %lu), ",
+					(unsigned long)major(li64.lo_device),
+					(unsigned long)minor(li64.lo_device));
+#ifdef HAVE_LONG_LONG
+				tprintf("lo_inode=%llu, ",
+					(unsigned long long)li64.lo_inode);
+#else
+				tprintf("lo_inode=%lu, ",
+					(unsigned long)li64.lo_inode);
+#endif
+				tprintf("lo_rdevice=makedev(%lu, %lu), ",
+					(unsigned long)major(li64.lo_rdevice),
+					(unsigned long)minor(li64.lo_rdevice));
+				tprintf("lo_flags=");
+				if (!printflags(loop_flags, li64.lo_flags, "LO_FLAGS_???"))
+					tprintf("0");
+				tprintf(", ");
+			}
+#ifdef HAVE_LONG_LONG
+			tprintf("lo_offset=%llu, lo_sizelimit=%llu",
+				(unsigned long long)li64.lo_offset,
+				(unsigned long long)li64.lo_sizelimit);
+#else
+			tprintf("lo_offset=%lu, lo_sizelimit=%lu",
+				(unsigned long)li64.lo_offset,
+				(unsigned long)li64.lo_sizelimit);
+#endif
+			tprintf(", lo_encrypt_type=");
+			printxval(loop_crypt, li64.lo_encrypt_type,
+				  "LO_CRYPT_???");
+			tprintf(", lo_crypt_name=");
+			printstr_loop(li64.lo_crypt_name, -1, LO_NAME_SIZE);
+			if (code == LOOP_SET_STATUS64) {
+				tprintf(", lo_encrypt_key_size=%d",
+					li64.lo_encrypt_key_size);
+				tprintf(", lo_encrypt_key=");
+				printstr_loop(li64.lo_encrypt_key,
+					      li64.lo_encrypt_key_size,
+					      LO_KEY_SIZE);
+			}
+			tprintf(", lo_file_name=");
+			printstr_loop(li64.lo_file_name, -1, LO_NAME_SIZE);
+			tprintf(", ...}");
+		}
+		return 1;
+	}
+	return 0;
+}
+
+#endif /* LINUX */
