diff -urN ../strace-4.5.16-orig/Makefile.am Makefile.am
--- ../strace-4.5.16-orig/Makefile.am	2007-07-03 11:07:28 +0900
+++ Makefile.am	2007-08-27 19:36:34 +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 \
 	     strace.spec \
diff -urN ../strace-4.5.16-orig/Makefile.in Makefile.in
--- ../strace-4.5.16-orig/Makefile.in	2007-08-03 19:24:40 +0900
+++ Makefile.in	2007-08-27 19:36:34 +0900
@@ -66,6 +66,7 @@
 	scsi.$(OBJEXT) stream.$(OBJEXT)
 strace_OBJECTS = $(am_strace_OBJECTS)
 strace_LDADD = $(LDADD)
+am_strace_OBJECTS += loop.$(OBJEXT)
 binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
 SCRIPTS = $(bin_SCRIPTS)
 DEFAULT_INCLUDES = -I.@am__isrc@
@@ -206,6 +207,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 \
 	     strace.spec \
@@ -384,6 +386,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.16-orig/defs.h defs.h
--- ../strace-4.5.16-orig/defs.h	2007-07-24 10:57:11 +0900
+++ defs.h	2007-08-27 19:36:34 +0900
@@ -492,6 +492,7 @@
 extern int proc_ioctl P((struct tcb *, int, int));
 extern int stream_ioctl P((struct tcb *, int, int));
 #ifdef LINUX
+extern int loop_ioctl P((struct tcb *, int, int));
 extern int rtc_ioctl P((struct tcb *, long, long));
 extern int scsi_ioctl P((struct tcb *, long, long));
 #endif
diff -urN ../strace-4.5.16-orig/ioctl.c ioctl.c
--- ../strace-4.5.16-orig/ioctl.c	2007-07-03 11:07:28 +0900
+++ ioctl.c	2007-08-27 19:36:34 +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.16-orig/linux/ioctlent.h linux/ioctlent.h
--- ../strace-4.5.16-orig/linux/ioctlent.h	2005-05-09 17:01:32 +0900
+++ linux/ioctlent.h	2007-08-27 19:36:34 +0900
@@ -306,6 +306,13 @@
 	{"linux/kd.h",	"GIO_CMAP",	0x4b70},
 	{"linux/kd.h",	"PIO_CMAP",	0x4b71},
 	{"linux/kd.h",	"KDFONTOP",	0x4b72},
+	{"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/mtrr.h",	"MTRRIOC_SET_ENTRY",	0x4d01},
 	{"asm/mtrr.h",	"MTRRIOC_DEL_ENTRY",	0x4d02},
diff -urN ../strace-4.5.16-orig/loop.c loop.c
--- ../strace-4.5.16-orig/loop.c	1970-01-01 09:00:00 +0900
+++ loop.c	2007-08-27 19:36:34 +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 */
