]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] struct loop_info64 with __u64
authorAndries E. Brouwer <andries.brouwer@cwi.nl>
Fri, 18 Apr 2003 10:18:49 +0000 (03:18 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Fri, 18 Apr 2003 10:18:49 +0000 (03:18 -0700)
(i) Replace in struct loop_info the dev_t field by __kernel_old_dev_t,
where this type is defined in <asm/posix_types.h>, so that problems
with a differently sized dev_t in userspace are avoided.

(ii) Introduce a new loop_info64, with __u64 device, inode and offset
fields.

19 files changed:
drivers/block/loop.c
include/asm-alpha/posix_types.h
include/asm-arm/posix_types.h
include/asm-cris/posix_types.h
include/asm-i386/posix_types.h
include/asm-ia64/posix_types.h
include/asm-m68k/posix_types.h
include/asm-mips/posix_types.h
include/asm-mips64/posix_types.h
include/asm-parisc/posix_types.h
include/asm-ppc/posix_types.h
include/asm-ppc64/posix_types.h
include/asm-s390/posix_types.h
include/asm-sh/posix_types.h
include/asm-sparc/posix_types.h
include/asm-sparc64/posix_types.h
include/asm-v850/posix_types.h
include/asm-x86_64/posix_types.h
include/linux/loop.h

index 2b9f558959b31964d5e940d4559a2f464412fad5..d9f69a882c97f7961ac091c1ca65e4a5f1c555bc 100644 (file)
@@ -120,13 +120,13 @@ static int transfer_xor(struct loop_device *lo, int cmd, char *raw_buf,
        return 0;
 }
 
-static int none_status(struct loop_device *lo, struct loop_info *info)
+static int none_status(struct loop_device *lo, const struct loop_info64 *info)
 {
        lo->lo_flags |= LO_FLAGS_BH_REMAP;
        return 0;
 }
 
-static int xor_status(struct loop_device *lo, struct loop_info *info)
+static int xor_status(struct loop_device *lo, const struct loop_info64 *info)
 {
        if (info->lo_encrypt_key_size <= 0)
                return -EINVAL;
@@ -215,7 +215,8 @@ do_lo_send(struct loop_device *lo, struct bio_vec *bvec, int bsize, loff_t pos)
                         * The transfer failed, but we still write the data to
                         * keep prepare/commit calls balanced.
                         */
-                       printk(KERN_ERR "loop: transfer error block %llu\n", (unsigned long long)index);
+                       printk(KERN_ERR "loop: transfer error block %llu\n",
+                              (unsigned long long)index);
                        memset(kaddr + offset, 0, size);
                }
                flush_dcache_page(page);
@@ -270,7 +271,9 @@ struct lo_read_data {
        int bsize;
 };
 
-static int lo_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size)
+static int
+lo_read_actor(read_descriptor_t *desc, struct page *page,
+             unsigned long offset, unsigned long size)
 {
        char *kaddr;
        unsigned long count = desc->count;
@@ -284,7 +287,8 @@ static int lo_read_actor(read_descriptor_t * desc, struct page *page, unsigned l
        kaddr = kmap(page);
        if (lo_do_transfer(lo, READ, kaddr + offset, p->data, size, IV)) {
                size = 0;
-               printk(KERN_ERR "loop: transfer error block %ld\n",page->index);
+               printk(KERN_ERR "loop: transfer error block %ld\n",
+                      page->index);
                desc->error = -EINVAL;
        }
        kunmap(page);
@@ -297,7 +301,7 @@ static int lo_read_actor(read_descriptor_t * desc, struct page *page, unsigned l
 
 static int
 do_lo_receive(struct loop_device *lo,
-               struct bio_vec *bvec, int bsize, loff_t pos)
+             struct bio_vec *bvec, int bsize, loff_t pos)
 {
        struct lo_read_data cookie;
        struct file *file;
@@ -330,8 +334,8 @@ lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
        return ret;
 }
 
-static inline unsigned long loop_get_iv(struct loop_device *lo,
-                                       unsigned long sector)
+static inline unsigned long
+loop_get_iv(struct loop_device *lo, unsigned long sector)
 {
        int bs = lo->lo_blocksize;
        unsigned long offset, IV;
@@ -358,6 +362,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
 }
 
 static int loop_end_io_transfer(struct bio *, unsigned int, int);
+
 static void loop_put_buffer(struct bio *bio)
 {
        /*
@@ -764,7 +769,8 @@ static int loop_release_xfer(struct loop_device *lo)
        return err;
 }
 
-static int loop_init_xfer(struct loop_device *lo, int type,struct loop_info *i)
+static int
+loop_init_xfer(struct loop_device *lo, int type, const struct loop_info64 *i)
 {
        int err = 0; 
        if (type) {
@@ -822,9 +828,9 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
        return 0;
 }
 
-static int loop_set_status(struct loop_device *lo, struct loop_info *arg)
+static int
+loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
 {
-       struct loop_info info; 
        int err;
        unsigned int type;
        loff_t offset;
@@ -834,23 +840,21 @@ static int loop_set_status(struct loop_device *lo, struct loop_info *arg)
                return -EPERM;
        if (lo->lo_state != Lo_bound)
                return -ENXIO;
-       if (copy_from_user(&info, arg, sizeof (struct loop_info)))
-               return -EFAULT; 
-       if ((unsigned int) info.lo_encrypt_key_size > LO_KEY_SIZE)
+       if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE)
                return -EINVAL;
-       type = info.lo_encrypt_type; 
+       type = info->lo_encrypt_type; 
        if (type >= MAX_LO_CRYPT || xfer_funcs[type] == NULL)
                return -EINVAL;
-       if (type == LO_CRYPT_XOR && info.lo_encrypt_key_size == 0)
+       if (type == LO_CRYPT_XOR && info->lo_encrypt_key_size == 0)
                return -EINVAL;
 
        err = loop_release_xfer(lo);
        if (!err) 
-               err = loop_init_xfer(lo, type, &info);
+               err = loop_init_xfer(lo, type, info);
 
        offset = lo->lo_offset;
-       if (offset != info.lo_offset) {
-               lo->lo_offset = info.lo_offset;
+       if (offset != info->lo_offset) {
+               lo->lo_offset = info->lo_offset;
                if (figure_loop_size(lo)){
                        err = -EFBIG;
                        lo->lo_offset = offset;
@@ -860,51 +864,147 @@ static int loop_set_status(struct loop_device *lo, struct loop_info *arg)
        if (err)
                return err;     
 
-       strncpy(lo->lo_name, info.lo_name, LO_NAME_SIZE);
+       strncpy(lo->lo_name, info->lo_name, LO_NAME_SIZE);
 
        lo->transfer = xfer_funcs[type]->transfer;
        lo->ioctl = xfer_funcs[type]->ioctl;
-       lo->lo_encrypt_key_size = info.lo_encrypt_key_size;
-       lo->lo_init[0] = info.lo_init[0];
-       lo->lo_init[1] = info.lo_init[1];
-       if (info.lo_encrypt_key_size) {
-               memcpy(lo->lo_encrypt_key, info.lo_encrypt_key, 
-                      info.lo_encrypt_key_size);
+       lo->lo_encrypt_key_size = info->lo_encrypt_key_size;
+       lo->lo_init[0] = info->lo_init[0];
+       lo->lo_init[1] = info->lo_init[1];
+       if (info->lo_encrypt_key_size) {
+               memcpy(lo->lo_encrypt_key, info->lo_encrypt_key, 
+                      info->lo_encrypt_key_size);
                lo->lo_key_owner = current->uid; 
        }       
 
        return 0;
 }
 
-static int loop_get_status(struct loop_device *lo, struct loop_info *arg)
+static int
+loop_get_status(struct loop_device *lo, struct loop_info64 *info)
 {
        struct file *file = lo->lo_backing_file;
-       struct loop_info info;
        struct kstat stat;
        int error;
 
        if (lo->lo_state != Lo_bound)
                return -ENXIO;
-       if (!arg)
-               return -EINVAL;
        error = vfs_getattr(file->f_vfsmnt, file->f_dentry, &stat);
        if (error)
                return error;
-       memset(&info, 0, sizeof(info));
-       info.lo_number = lo->lo_number;
-       info.lo_device = stat.dev;
-       info.lo_inode = stat.ino;
-       info.lo_rdevice = lo->lo_device ? stat.rdev : stat.dev;
-       info.lo_offset = lo->lo_offset;
-       info.lo_flags = lo->lo_flags;
-       strncpy(info.lo_name, lo->lo_name, LO_NAME_SIZE);
-       info.lo_encrypt_type = lo->lo_encrypt_type;
+       memset(info, 0, sizeof(*info));
+       info->lo_number = lo->lo_number;
+       info->lo_device = stat.dev;
+       info->lo_inode = stat.ino;
+       info->lo_rdevice = lo->lo_device ? stat.rdev : stat.dev;
+       info->lo_offset = lo->lo_offset;
+       info->lo_flags = lo->lo_flags;
+       strncpy(info->lo_name, lo->lo_name, LO_NAME_SIZE);
+       info->lo_encrypt_type = lo->lo_encrypt_type;
        if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
-               info.lo_encrypt_key_size = lo->lo_encrypt_key_size;
-               memcpy(info.lo_encrypt_key, lo->lo_encrypt_key,
+               info->lo_encrypt_key_size = lo->lo_encrypt_key_size;
+               memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
                       lo->lo_encrypt_key_size);
        }
-       return copy_to_user(arg, &info, sizeof(info)) ? -EFAULT : 0;
+       return 0;
+}
+
+static void
+loop_info64_from_old(const struct loop_info *info, struct loop_info64 *info64)
+{
+       info64->lo_number = info->lo_number;
+       info64->lo_device = info->lo_device;
+       info64->lo_inode = info->lo_inode;
+       info64->lo_rdevice = info->lo_rdevice;
+       info64->lo_offset = info->lo_offset;
+       info64->lo_encrypt_type = info->lo_encrypt_type;
+       info64->lo_encrypt_key_size = info->lo_encrypt_key_size;
+       info64->lo_flags = info->lo_flags;
+       info64->lo_init[0] = info->lo_init[0];
+       info64->lo_init[1] = info->lo_init[1];
+       memcpy(info64->lo_name, info->lo_name, LO_NAME_SIZE);
+       memcpy(info64->lo_encrypt_key, info->lo_encrypt_key, LO_KEY_SIZE);
+}
+
+static int
+loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info)
+{
+       info->lo_number = info64->lo_number;
+       info->lo_device = info64->lo_device;
+       info->lo_inode = info64->lo_inode;
+       info->lo_rdevice = info64->lo_rdevice;
+       info->lo_offset = info64->lo_offset;
+       info->lo_encrypt_type = info64->lo_encrypt_type;
+       info->lo_encrypt_key_size = info64->lo_encrypt_key_size;
+       info->lo_flags = info64->lo_flags;
+       info->lo_init[0] = info64->lo_init[0];
+       info->lo_init[1] = info64->lo_init[1];
+       memcpy(info->lo_name, info64->lo_name, LO_NAME_SIZE);
+       memcpy(info->lo_encrypt_key,info64->lo_encrypt_key,LO_KEY_SIZE);
+
+       /* error in case values were truncated */
+       if (info->lo_device != info64->lo_device ||
+           info->lo_rdevice != info64->lo_rdevice ||
+           info->lo_inode != info64->lo_inode ||
+           info->lo_offset != info64->lo_offset)
+               return -EOVERFLOW;
+
+       return 0;
+}
+
+static int
+loop_set_status_old(struct loop_device *lo, const struct loop_info *arg)
+{
+       struct loop_info info;
+       struct loop_info64 info64;
+
+       if (copy_from_user(&info, arg, sizeof (struct loop_info)))
+               return -EFAULT;
+       loop_info64_from_old(&info, &info64);
+       return loop_set_status(lo, &info64);
+}
+
+static int
+loop_set_status64(struct loop_device *lo, const struct loop_info64 *arg)
+{
+       struct loop_info64 info64;
+
+       if (copy_from_user(&info64, arg, sizeof (struct loop_info64)))
+               return -EFAULT;
+       return loop_set_status(lo, &info64);
+}
+
+static int
+loop_get_status_old(struct loop_device *lo, struct loop_info *arg) {
+       struct loop_info info;
+       struct loop_info64 info64;
+       int err = 0;
+
+       if (!arg)
+               err = -EINVAL;
+       if (!err)
+               err = loop_get_status(lo, &info64);
+       if (!err)
+               err = loop_info64_to_old(&info64, &info);
+       if (!err && copy_to_user(arg, &info, sizeof(info)))
+               err = -EFAULT;
+
+       return err;
+}
+
+static int
+loop_get_status64(struct loop_device *lo, struct loop_info64 *arg) {
+       struct loop_info64 info64;
+       int err = 0;
+
+       if (!arg)
+               err = -EINVAL;
+       if (!err)
+               err = loop_get_status(lo, &info64);
+       if (!err && copy_to_user(arg, &info64, sizeof(info64)))
+               err = -EFAULT;
+
+       return err;
 }
 
 static int lo_ioctl(struct inode * inode, struct file * file,
@@ -922,10 +1022,16 @@ static int lo_ioctl(struct inode * inode, struct file * file,
                err = loop_clr_fd(lo, inode->i_bdev);
                break;
        case LOOP_SET_STATUS:
-               err = loop_set_status(lo, (struct loop_info *) arg);
+               err = loop_set_status_old(lo, (struct loop_info *) arg);
                break;
        case LOOP_GET_STATUS:
-               err = loop_get_status(lo, (struct loop_info *) arg);
+               err = loop_get_status_old(lo, (struct loop_info *) arg);
+               break;
+       case LOOP_SET_STATUS64:
+               err = loop_set_status64(lo, (struct loop_info64 *) arg);
+               break;
+       case LOOP_GET_STATUS64:
+               err = loop_get_status64(lo, (struct loop_info64 *) arg);
                break;
        default:
                err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
index 723efbe8a5ed2ba8be4a24a72e3cd9de0a47e32a..9c613d79189deda2e2049ea65c769ecd0db14525 100644 (file)
@@ -40,6 +40,8 @@ typedef __kernel_gid_t __kernel_old_gid_t;
 typedef __kernel_uid_t __kernel_uid32_t;
 typedef __kernel_gid_t __kernel_gid32_t;
 
+typedef unsigned int   __kernel_old_dev_t;
+
 #ifdef __KERNEL__
 
 #ifndef __GNUC__
index 9aeff7c2cb9856eff0da528e48e5724ecef2156d..23ad094247238a27b452d76cb2703adaf2bd9904 100644 (file)
@@ -45,6 +45,7 @@ typedef unsigned int          __kernel_gid32_t;
 
 typedef unsigned short         __kernel_old_uid_t;
 typedef unsigned short         __kernel_old_gid_t;
+typedef unsigned short         __kernel_old_dev_t;
 
 #ifdef __GNUC__
 typedef long long              __kernel_loff_t;
index 5cf2270024833b82a8eb42ddc94d1550a549c9c4..d10e9fc65c3246c82650ff835e125f9a0756ebe0 100644 (file)
@@ -38,6 +38,7 @@ typedef unsigned int    __kernel_gid32_t;
 
 typedef unsigned short  __kernel_old_uid_t;
 typedef unsigned short  __kernel_old_gid_t;
+typedef unsigned short __kernel_old_dev_t;
 
 #ifdef __GNUC__
 typedef long long      __kernel_loff_t;
index 34ad5659bd3f1a8c4aaa5093332d10f32caad50b..d391865fd502e5f78d65cd5a893267af8a1dbef7 100644 (file)
@@ -33,6 +33,7 @@ typedef unsigned int  __kernel_gid32_t;
 
 typedef unsigned short __kernel_old_uid_t;
 typedef unsigned short __kernel_old_gid_t;
+typedef unsigned short __kernel_old_dev_t;
 
 #ifdef __GNUC__
 typedef long long      __kernel_loff_t;
index 0140c5ac8381a9db03ef124de295bbceb94ac662..50db61f1846943cf8cb3239168470688b48b99fd 100644 (file)
@@ -43,6 +43,8 @@ typedef __kernel_gid_t __kernel_old_gid_t;
 typedef __kernel_uid_t __kernel_uid32_t;
 typedef __kernel_gid_t __kernel_gid32_t;
 
+typedef unsigned int   __kernel_old_dev_t;
+
 # ifdef __KERNEL__
 
 #  ifndef __GNUC__
index 4c25b4248450ad4e84fed7486aa4e8ebcd06bda3..d10b7bb9cb9eecff3b5d7fd45acdaee99cb739ce 100644 (file)
@@ -33,6 +33,7 @@ typedef unsigned int  __kernel_gid32_t;
 
 typedef unsigned short __kernel_old_uid_t;
 typedef unsigned short __kernel_old_gid_t;
+typedef unsigned short __kernel_old_dev_t;
 
 #ifdef __GNUC__
 typedef long long      __kernel_loff_t;
index 6c48b3f83948d3ed14d63d51e32a0b0d54276eb6..21191a76c2863d9b42b5a0e961c0c4ca7c679dae 100644 (file)
@@ -39,6 +39,7 @@ typedef int           __kernel_uid32_t;
 typedef int            __kernel_gid32_t;
 typedef __kernel_uid_t __kernel_old_uid_t;
 typedef __kernel_gid_t __kernel_old_gid_t;
+typedef unsigned int   __kernel_old_dev_t;
 
 #ifdef __GNUC__
 typedef long long      __kernel_loff_t;
index 8a3aac609eba2a4826db1394fda19b36ffb5fb52..2a1e6e8803e5cc157edf2e690739e9f726b143ad 100644 (file)
@@ -39,6 +39,7 @@ typedef int           __kernel_uid32_t;
 typedef int            __kernel_gid32_t;
 typedef __kernel_uid_t __kernel_old_uid_t;
 typedef __kernel_gid_t __kernel_old_gid_t;
+typedef unsigned int   __kernel_old_dev_t;
 
 #ifdef __GNUC__
 typedef long long      __kernel_loff_t;
index 53c74802f51b25313a9c09e3daeb61ea6ad0216e..6d241ab7ed1928dbc352dd238b694d97930dce5c 100644 (file)
@@ -45,6 +45,8 @@ typedef long long             __kernel_off64_t;
 typedef unsigned long long     __kernel_ino64_t;
 #endif
 
+typedef unsigned int           __kernel_old_dev_t;
+
 typedef struct {
 #if defined(__KERNEL__) || defined(__USE_ALL)
        int     val[2];
index 0796dd812ab4fc2c0d6ee9cd8ae8299576aa1b24..12acadb61cb92ee3bfa79b84d93dc281447c9598 100644 (file)
@@ -33,6 +33,7 @@ typedef unsigned int  __kernel_gid32_t;
 
 typedef unsigned int   __kernel_old_uid_t;
 typedef unsigned int   __kernel_old_gid_t;
+typedef unsigned int   __kernel_old_dev_t;
 
 #ifdef __GNUC__
 typedef long long      __kernel_loff_t;
index 9221ccaecdfa6e65b2360cfeff03520d9323bfe5..c3cff412a3ebf08b8d3c0a622627e99150f57551 100644 (file)
@@ -39,6 +39,7 @@ typedef unsigned int  __kernel_gid32_t;
 
 typedef unsigned int   __kernel_old_uid_t;
 typedef unsigned int   __kernel_old_gid_t;
+typedef unsigned long  __kernel_old_dev_t;
 
 typedef struct {
        int     val[2];
index 9359c22e38e28e4f70d3625c134c82ebe8b71fbb..bc296e8e39ae60ba318be2150113bce88c72c8ab 100644 (file)
@@ -47,6 +47,7 @@ typedef unsigned int  __kernel_uid32_t;
 typedef unsigned int   __kernel_gid32_t;
 typedef unsigned short __kernel_old_uid_t;
 typedef unsigned short __kernel_old_gid_t;
+typedef unsigned short __kernel_old_dev_t;
 
 #else /* __s390x__ */
 
index a1d59140d4cb8518ae4c757bf75dd22256a11ef5..02a8db8af0b1b8e3143adf4023f96d278d977409 100644 (file)
@@ -31,6 +31,7 @@ typedef unsigned int  __kernel_gid32_t;
 
 typedef unsigned short __kernel_old_uid_t;
 typedef unsigned short __kernel_old_gid_t;
+typedef unsigned short __kernel_old_dev_t;
 
 #ifdef __GNUC__
 typedef long long      __kernel_loff_t;
index 7efd7c0fae9f52649de89349e6654ab46cbc7a04..b4731a3c12a4ee223b9a53b8f75e03f01a98b47d 100644 (file)
@@ -31,6 +31,7 @@ typedef unsigned int         __kernel_uid32_t;
 typedef unsigned int          __kernel_gid32_t;
 typedef unsigned short        __kernel_old_uid_t;
 typedef unsigned short        __kernel_old_gid_t;
+typedef unsigned short        __kernel_old_dev_t;
 typedef int                    __kernel_clockid_t;
 typedef int                    __kernel_timer_t;
 
index 5bcd2a1b6ec12905baeb77f49d185a991c9c4e30..9341bb220fd8afb70656f4ec61812c340fbdb0d0 100644 (file)
@@ -34,6 +34,8 @@ typedef __kernel_gid_t         __kernel_old_gid_t;
 typedef __kernel_uid_t        __kernel_uid32_t;
 typedef __kernel_gid_t        __kernel_gid32_t;
 
+typedef unsigned int          __kernel_old_dev_t;
+
 /* Note this piece of asymmetry from the v9 ABI.  */
 typedef int                   __kernel_suseconds_t;
 
index 773fc0e1d9550eb1731dddbb1599e40ad7e46362..4f2f0d8eefeabe60c297f90787d10f1ce2e8d28b 100644 (file)
@@ -42,7 +42,7 @@ typedef unsigned int  __kernel_gid32_t;
 
 /* Some bogus code depends on this; we don't care.  */
 typedef __kernel_uid_t __kernel_old_uid_t;
-
+typedef unsigned int   __kernel_old_dev_t;
 
 typedef struct {
 #if defined(__KERNEL__) || defined(__USE_ALL)
index 162cfa2b922ea62cc8b31c4fde2dd70898b39893..33a1dccf45dab7c63d29e099f0157d2fcf79512e 100644 (file)
@@ -22,8 +22,8 @@ typedef long          __kernel_ptrdiff_t;
 typedef long           __kernel_time_t;
 typedef long           __kernel_suseconds_t;
 typedef long           __kernel_clock_t;
-typedef int            __kernel_timer_t;
-typedef int            __kernel_clockid_t;
+typedef int            __kernel_timer_t;
+typedef int            __kernel_clockid_t;
 typedef int            __kernel_daddr_t;
 typedef char *         __kernel_caddr_t;
 typedef unsigned short __kernel_uid16_t;
@@ -42,6 +42,8 @@ typedef __kernel_gid_t __kernel_old_gid_t;
 typedef __kernel_uid_t __kernel_uid32_t;
 typedef __kernel_gid_t __kernel_gid32_t;
 
+typedef unsigned long  __kernel_old_dev_t;
+
 #ifdef __KERNEL__
 
 #undef __FD_SET
index fe28a0ee8f34919778f53b13e854369c8d5d9df4..f2e8d775f43a840ffc51437050de957274733d78 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef _LINUX_LOOP_H
 #define _LINUX_LOOP_H
 
-#include <linux/kdev_t.h>
-
 /*
  * include/linux/loop.h
  *
@@ -74,34 +72,37 @@ typedef     int (* transfer_proc_t)(struct loop_device *, int cmd,
 #define LO_FLAGS_READ_ONLY     2
 #define LO_FLAGS_BH_REMAP      4
 
-/* 
- * Note that this structure gets the wrong offsets when directly used
- * from a glibc program, because glibc has a 32bit dev_t.
- * Prevent people from shooting in their own foot.  
- */
-#if __GLIBC__ >= 2 && !defined(dev_t)
-#error "Wrong dev_t in loop.h"
-#endif 
-
-/*
- *     This uses kdev_t because glibc currently has no appropiate
- *     conversion version for the loop ioctls. 
- *     The situation is very unpleasant        
- */
+#include <asm/posix_types.h>   /* for __kernel_old_dev_t */
+#include <asm/types.h>         /* for __u64 */
 
+/* Backwards compatibility version */
 struct loop_info {
-       int             lo_number;      /* ioctl r/o */
-       dev_t           lo_device;      /* ioctl r/o */
-       unsigned long   lo_inode;       /* ioctl r/o */
-       dev_t           lo_rdevice;     /* ioctl r/o */
-       int             lo_offset;
-       int             lo_encrypt_type;
-       int             lo_encrypt_key_size;    /* ioctl w/o */
-       int             lo_flags;       /* ioctl r/o */
-       char            lo_name[LO_NAME_SIZE];
-       unsigned char   lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
-       unsigned long   lo_init[2];
-       char            reserved[4];
+       int                lo_number;           /* ioctl r/o */
+       __kernel_old_dev_t lo_device;           /* ioctl r/o */
+       unsigned long      lo_inode;            /* ioctl r/o */
+       __kernel_old_dev_t lo_rdevice;          /* ioctl r/o */
+       int                lo_offset;
+       int                lo_encrypt_type;
+       int                lo_encrypt_key_size;         /* ioctl w/o */
+       int                lo_flags;                    /* ioctl r/o */
+       char               lo_name[LO_NAME_SIZE];
+       unsigned char      lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
+       unsigned long      lo_init[2];
+       char               reserved[4];
+};
+
+struct loop_info64 {
+       __u64              lo_device;           /* ioctl r/o */
+       __u64              lo_inode;            /* ioctl r/o */
+       __u64              lo_rdevice;          /* ioctl r/o */
+       __u64              lo_offset;
+       __u32              lo_number;           /* ioctl r/o */
+       __u32              lo_encrypt_type;
+       __u32              lo_encrypt_key_size;         /* ioctl w/o */
+       __u32              lo_flags;                    /* ioctl r/o */
+       __u8               lo_name[LO_NAME_SIZE];
+       __u8               lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
+       __u64              lo_init[2];
 };
 
 /*
@@ -125,7 +126,7 @@ struct loop_func_table {
        int number;     /* filter type */ 
        int (*transfer)(struct loop_device *lo, int cmd, char *raw_buf,
                        char *loop_buf, int size, sector_t real_block);
-       int (*init)(struct loop_device *, struct loop_info *); 
+       int (*init)(struct loop_device *, const struct loop_info64 *); 
        /* release is called from loop_unregister_transfer or clr_fd */
        int (*release)(struct loop_device *); 
        int (*ioctl)(struct loop_device *, int cmd, unsigned long arg);
@@ -134,7 +135,7 @@ struct loop_func_table {
        void (*unlock)(struct loop_device *);
 }; 
 
-int  loop_register_transfer(struct loop_func_table *funcs);
+int loop_register_transfer(struct loop_func_table *funcs);
 int loop_unregister_transfer(int number); 
 
 #endif
@@ -142,9 +143,11 @@ int loop_unregister_transfer(int number);
  * IOCTL commands --- we will commandeer 0x4C ('L')
  */
 
-#define LOOP_SET_FD    0x4C00
-#define LOOP_CLR_FD    0x4C01
-#define LOOP_SET_STATUS        0x4C02
-#define LOOP_GET_STATUS        0x4C03
+#define LOOP_SET_FD            0x4C00
+#define LOOP_CLR_FD            0x4C01
+#define LOOP_SET_STATUS                0x4C02
+#define LOOP_GET_STATUS                0x4C03
+#define LOOP_SET_STATUS64      0x4C04
+#define LOOP_GET_STATUS64      0x4C05
 
 #endif