Commit ca49321f authored by Andries E. Brouwer's avatar Andries E. Brouwer Committed by Linus Torvalds

[PATCH] struct loop_info64 with __u64

(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.
parent 24ebdc14
...@@ -120,13 +120,13 @@ static int transfer_xor(struct loop_device *lo, int cmd, char *raw_buf, ...@@ -120,13 +120,13 @@ static int transfer_xor(struct loop_device *lo, int cmd, char *raw_buf,
return 0; 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; lo->lo_flags |= LO_FLAGS_BH_REMAP;
return 0; 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) if (info->lo_encrypt_key_size <= 0)
return -EINVAL; return -EINVAL;
...@@ -215,7 +215,8 @@ do_lo_send(struct loop_device *lo, struct bio_vec *bvec, int bsize, loff_t pos) ...@@ -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 * The transfer failed, but we still write the data to
* keep prepare/commit calls balanced. * 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); memset(kaddr + offset, 0, size);
} }
flush_dcache_page(page); flush_dcache_page(page);
...@@ -270,7 +271,9 @@ struct lo_read_data { ...@@ -270,7 +271,9 @@ struct lo_read_data {
int bsize; 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; char *kaddr;
unsigned long count = desc->count; unsigned long count = desc->count;
...@@ -284,7 +287,8 @@ static int lo_read_actor(read_descriptor_t * desc, struct page *page, unsigned l ...@@ -284,7 +287,8 @@ static int lo_read_actor(read_descriptor_t * desc, struct page *page, unsigned l
kaddr = kmap(page); kaddr = kmap(page);
if (lo_do_transfer(lo, READ, kaddr + offset, p->data, size, IV)) { if (lo_do_transfer(lo, READ, kaddr + offset, p->data, size, IV)) {
size = 0; 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; desc->error = -EINVAL;
} }
kunmap(page); kunmap(page);
...@@ -297,7 +301,7 @@ static int lo_read_actor(read_descriptor_t * desc, struct page *page, unsigned l ...@@ -297,7 +301,7 @@ static int lo_read_actor(read_descriptor_t * desc, struct page *page, unsigned l
static int static int
do_lo_receive(struct loop_device *lo, 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 lo_read_data cookie;
struct file *file; struct file *file;
...@@ -330,8 +334,8 @@ lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos) ...@@ -330,8 +334,8 @@ lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
return ret; return ret;
} }
static inline unsigned long loop_get_iv(struct loop_device *lo, static inline unsigned long
unsigned long sector) loop_get_iv(struct loop_device *lo, unsigned long sector)
{ {
int bs = lo->lo_blocksize; int bs = lo->lo_blocksize;
unsigned long offset, IV; unsigned long offset, IV;
...@@ -358,6 +362,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) ...@@ -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 int loop_end_io_transfer(struct bio *, unsigned int, int);
static void loop_put_buffer(struct bio *bio) static void loop_put_buffer(struct bio *bio)
{ {
/* /*
...@@ -764,7 +769,8 @@ static int loop_release_xfer(struct loop_device *lo) ...@@ -764,7 +769,8 @@ static int loop_release_xfer(struct loop_device *lo)
return err; 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; int err = 0;
if (type) { if (type) {
...@@ -822,9 +828,9 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) ...@@ -822,9 +828,9 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
return 0; 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; int err;
unsigned int type; unsigned int type;
loff_t offset; loff_t offset;
...@@ -834,23 +840,21 @@ static int loop_set_status(struct loop_device *lo, struct loop_info *arg) ...@@ -834,23 +840,21 @@ static int loop_set_status(struct loop_device *lo, struct loop_info *arg)
return -EPERM; return -EPERM;
if (lo->lo_state != Lo_bound) if (lo->lo_state != Lo_bound)
return -ENXIO; return -ENXIO;
if (copy_from_user(&info, arg, sizeof (struct loop_info))) if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE)
return -EFAULT;
if ((unsigned int) info.lo_encrypt_key_size > LO_KEY_SIZE)
return -EINVAL; return -EINVAL;
type = info.lo_encrypt_type; type = info->lo_encrypt_type;
if (type >= MAX_LO_CRYPT || xfer_funcs[type] == NULL) if (type >= MAX_LO_CRYPT || xfer_funcs[type] == NULL)
return -EINVAL; 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; return -EINVAL;
err = loop_release_xfer(lo); err = loop_release_xfer(lo);
if (!err) if (!err)
err = loop_init_xfer(lo, type, &info); err = loop_init_xfer(lo, type, info);
offset = lo->lo_offset; offset = lo->lo_offset;
if (offset != info.lo_offset) { if (offset != info->lo_offset) {
lo->lo_offset = info.lo_offset; lo->lo_offset = info->lo_offset;
if (figure_loop_size(lo)){ if (figure_loop_size(lo)){
err = -EFBIG; err = -EFBIG;
lo->lo_offset = offset; lo->lo_offset = offset;
...@@ -860,51 +864,147 @@ static int loop_set_status(struct loop_device *lo, struct loop_info *arg) ...@@ -860,51 +864,147 @@ static int loop_set_status(struct loop_device *lo, struct loop_info *arg)
if (err) if (err)
return 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->transfer = xfer_funcs[type]->transfer;
lo->ioctl = xfer_funcs[type]->ioctl; lo->ioctl = xfer_funcs[type]->ioctl;
lo->lo_encrypt_key_size = 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[0] = info->lo_init[0];
lo->lo_init[1] = info.lo_init[1]; lo->lo_init[1] = info->lo_init[1];
if (info.lo_encrypt_key_size) { if (info->lo_encrypt_key_size) {
memcpy(lo->lo_encrypt_key, info.lo_encrypt_key, memcpy(lo->lo_encrypt_key, info->lo_encrypt_key,
info.lo_encrypt_key_size); info->lo_encrypt_key_size);
lo->lo_key_owner = current->uid; lo->lo_key_owner = current->uid;
} }
return 0; 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 file *file = lo->lo_backing_file;
struct loop_info info;
struct kstat stat; struct kstat stat;
int error; int error;
if (lo->lo_state != Lo_bound) if (lo->lo_state != Lo_bound)
return -ENXIO; return -ENXIO;
if (!arg)
return -EINVAL;
error = vfs_getattr(file->f_vfsmnt, file->f_dentry, &stat); error = vfs_getattr(file->f_vfsmnt, file->f_dentry, &stat);
if (error) if (error)
return error; return error;
memset(&info, 0, sizeof(info)); memset(info, 0, sizeof(*info));
info.lo_number = lo->lo_number; info->lo_number = lo->lo_number;
info.lo_device = stat.dev; info->lo_device = stat.dev;
info.lo_inode = stat.ino; info->lo_inode = stat.ino;
info.lo_rdevice = lo->lo_device ? stat.rdev : stat.dev; info->lo_rdevice = lo->lo_device ? stat.rdev : stat.dev;
info.lo_offset = lo->lo_offset; info->lo_offset = lo->lo_offset;
info.lo_flags = lo->lo_flags; info->lo_flags = lo->lo_flags;
strncpy(info.lo_name, lo->lo_name, LO_NAME_SIZE); strncpy(info->lo_name, lo->lo_name, LO_NAME_SIZE);
info.lo_encrypt_type = lo->lo_encrypt_type; info->lo_encrypt_type = lo->lo_encrypt_type;
if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) { if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
info.lo_encrypt_key_size = lo->lo_encrypt_key_size; info->lo_encrypt_key_size = lo->lo_encrypt_key_size;
memcpy(info.lo_encrypt_key, lo->lo_encrypt_key, memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
lo->lo_encrypt_key_size); 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, static int lo_ioctl(struct inode * inode, struct file * file,
...@@ -922,10 +1022,16 @@ 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); err = loop_clr_fd(lo, inode->i_bdev);
break; break;
case LOOP_SET_STATUS: case LOOP_SET_STATUS:
err = loop_set_status(lo, (struct loop_info *) arg); err = loop_set_status_old(lo, (struct loop_info *) arg);
break; break;
case LOOP_GET_STATUS: 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; break;
default: default:
err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL; err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
......
...@@ -40,6 +40,8 @@ typedef __kernel_gid_t __kernel_old_gid_t; ...@@ -40,6 +40,8 @@ typedef __kernel_gid_t __kernel_old_gid_t;
typedef __kernel_uid_t __kernel_uid32_t; typedef __kernel_uid_t __kernel_uid32_t;
typedef __kernel_gid_t __kernel_gid32_t; typedef __kernel_gid_t __kernel_gid32_t;
typedef unsigned int __kernel_old_dev_t;
#ifdef __KERNEL__ #ifdef __KERNEL__
#ifndef __GNUC__ #ifndef __GNUC__
......
...@@ -45,6 +45,7 @@ typedef unsigned int __kernel_gid32_t; ...@@ -45,6 +45,7 @@ typedef unsigned int __kernel_gid32_t;
typedef unsigned short __kernel_old_uid_t; typedef unsigned short __kernel_old_uid_t;
typedef unsigned short __kernel_old_gid_t; typedef unsigned short __kernel_old_gid_t;
typedef unsigned short __kernel_old_dev_t;
#ifdef __GNUC__ #ifdef __GNUC__
typedef long long __kernel_loff_t; typedef long long __kernel_loff_t;
......
...@@ -38,6 +38,7 @@ typedef unsigned int __kernel_gid32_t; ...@@ -38,6 +38,7 @@ typedef unsigned int __kernel_gid32_t;
typedef unsigned short __kernel_old_uid_t; typedef unsigned short __kernel_old_uid_t;
typedef unsigned short __kernel_old_gid_t; typedef unsigned short __kernel_old_gid_t;
typedef unsigned short __kernel_old_dev_t;
#ifdef __GNUC__ #ifdef __GNUC__
typedef long long __kernel_loff_t; typedef long long __kernel_loff_t;
......
...@@ -33,6 +33,7 @@ typedef unsigned int __kernel_gid32_t; ...@@ -33,6 +33,7 @@ typedef unsigned int __kernel_gid32_t;
typedef unsigned short __kernel_old_uid_t; typedef unsigned short __kernel_old_uid_t;
typedef unsigned short __kernel_old_gid_t; typedef unsigned short __kernel_old_gid_t;
typedef unsigned short __kernel_old_dev_t;
#ifdef __GNUC__ #ifdef __GNUC__
typedef long long __kernel_loff_t; typedef long long __kernel_loff_t;
......
...@@ -43,6 +43,8 @@ typedef __kernel_gid_t __kernel_old_gid_t; ...@@ -43,6 +43,8 @@ typedef __kernel_gid_t __kernel_old_gid_t;
typedef __kernel_uid_t __kernel_uid32_t; typedef __kernel_uid_t __kernel_uid32_t;
typedef __kernel_gid_t __kernel_gid32_t; typedef __kernel_gid_t __kernel_gid32_t;
typedef unsigned int __kernel_old_dev_t;
# ifdef __KERNEL__ # ifdef __KERNEL__
# ifndef __GNUC__ # ifndef __GNUC__
......
...@@ -33,6 +33,7 @@ typedef unsigned int __kernel_gid32_t; ...@@ -33,6 +33,7 @@ typedef unsigned int __kernel_gid32_t;
typedef unsigned short __kernel_old_uid_t; typedef unsigned short __kernel_old_uid_t;
typedef unsigned short __kernel_old_gid_t; typedef unsigned short __kernel_old_gid_t;
typedef unsigned short __kernel_old_dev_t;
#ifdef __GNUC__ #ifdef __GNUC__
typedef long long __kernel_loff_t; typedef long long __kernel_loff_t;
......
...@@ -39,6 +39,7 @@ typedef int __kernel_uid32_t; ...@@ -39,6 +39,7 @@ typedef int __kernel_uid32_t;
typedef int __kernel_gid32_t; typedef int __kernel_gid32_t;
typedef __kernel_uid_t __kernel_old_uid_t; typedef __kernel_uid_t __kernel_old_uid_t;
typedef __kernel_gid_t __kernel_old_gid_t; typedef __kernel_gid_t __kernel_old_gid_t;
typedef unsigned int __kernel_old_dev_t;
#ifdef __GNUC__ #ifdef __GNUC__
typedef long long __kernel_loff_t; typedef long long __kernel_loff_t;
......
...@@ -39,6 +39,7 @@ typedef int __kernel_uid32_t; ...@@ -39,6 +39,7 @@ typedef int __kernel_uid32_t;
typedef int __kernel_gid32_t; typedef int __kernel_gid32_t;
typedef __kernel_uid_t __kernel_old_uid_t; typedef __kernel_uid_t __kernel_old_uid_t;
typedef __kernel_gid_t __kernel_old_gid_t; typedef __kernel_gid_t __kernel_old_gid_t;
typedef unsigned int __kernel_old_dev_t;
#ifdef __GNUC__ #ifdef __GNUC__
typedef long long __kernel_loff_t; typedef long long __kernel_loff_t;
......
...@@ -45,6 +45,8 @@ typedef long long __kernel_off64_t; ...@@ -45,6 +45,8 @@ typedef long long __kernel_off64_t;
typedef unsigned long long __kernel_ino64_t; typedef unsigned long long __kernel_ino64_t;
#endif #endif
typedef unsigned int __kernel_old_dev_t;
typedef struct { typedef struct {
#if defined(__KERNEL__) || defined(__USE_ALL) #if defined(__KERNEL__) || defined(__USE_ALL)
int val[2]; int val[2];
......
...@@ -33,6 +33,7 @@ typedef unsigned int __kernel_gid32_t; ...@@ -33,6 +33,7 @@ typedef unsigned int __kernel_gid32_t;
typedef unsigned int __kernel_old_uid_t; typedef unsigned int __kernel_old_uid_t;
typedef unsigned int __kernel_old_gid_t; typedef unsigned int __kernel_old_gid_t;
typedef unsigned int __kernel_old_dev_t;
#ifdef __GNUC__ #ifdef __GNUC__
typedef long long __kernel_loff_t; typedef long long __kernel_loff_t;
......
...@@ -39,6 +39,7 @@ typedef unsigned int __kernel_gid32_t; ...@@ -39,6 +39,7 @@ typedef unsigned int __kernel_gid32_t;
typedef unsigned int __kernel_old_uid_t; typedef unsigned int __kernel_old_uid_t;
typedef unsigned int __kernel_old_gid_t; typedef unsigned int __kernel_old_gid_t;
typedef unsigned long __kernel_old_dev_t;
typedef struct { typedef struct {
int val[2]; int val[2];
......
...@@ -47,6 +47,7 @@ typedef unsigned int __kernel_uid32_t; ...@@ -47,6 +47,7 @@ typedef unsigned int __kernel_uid32_t;
typedef unsigned int __kernel_gid32_t; typedef unsigned int __kernel_gid32_t;
typedef unsigned short __kernel_old_uid_t; typedef unsigned short __kernel_old_uid_t;
typedef unsigned short __kernel_old_gid_t; typedef unsigned short __kernel_old_gid_t;
typedef unsigned short __kernel_old_dev_t;
#else /* __s390x__ */ #else /* __s390x__ */
......
...@@ -31,6 +31,7 @@ typedef unsigned int __kernel_gid32_t; ...@@ -31,6 +31,7 @@ typedef unsigned int __kernel_gid32_t;
typedef unsigned short __kernel_old_uid_t; typedef unsigned short __kernel_old_uid_t;
typedef unsigned short __kernel_old_gid_t; typedef unsigned short __kernel_old_gid_t;
typedef unsigned short __kernel_old_dev_t;
#ifdef __GNUC__ #ifdef __GNUC__
typedef long long __kernel_loff_t; typedef long long __kernel_loff_t;
......
...@@ -31,6 +31,7 @@ typedef unsigned int __kernel_uid32_t; ...@@ -31,6 +31,7 @@ typedef unsigned int __kernel_uid32_t;
typedef unsigned int __kernel_gid32_t; typedef unsigned int __kernel_gid32_t;
typedef unsigned short __kernel_old_uid_t; typedef unsigned short __kernel_old_uid_t;
typedef unsigned short __kernel_old_gid_t; typedef unsigned short __kernel_old_gid_t;
typedef unsigned short __kernel_old_dev_t;
typedef int __kernel_clockid_t; typedef int __kernel_clockid_t;
typedef int __kernel_timer_t; typedef int __kernel_timer_t;
......
...@@ -34,6 +34,8 @@ typedef __kernel_gid_t __kernel_old_gid_t; ...@@ -34,6 +34,8 @@ typedef __kernel_gid_t __kernel_old_gid_t;
typedef __kernel_uid_t __kernel_uid32_t; typedef __kernel_uid_t __kernel_uid32_t;
typedef __kernel_gid_t __kernel_gid32_t; typedef __kernel_gid_t __kernel_gid32_t;
typedef unsigned int __kernel_old_dev_t;
/* Note this piece of asymmetry from the v9 ABI. */ /* Note this piece of asymmetry from the v9 ABI. */
typedef int __kernel_suseconds_t; typedef int __kernel_suseconds_t;
......
...@@ -42,7 +42,7 @@ typedef unsigned int __kernel_gid32_t; ...@@ -42,7 +42,7 @@ typedef unsigned int __kernel_gid32_t;
/* Some bogus code depends on this; we don't care. */ /* Some bogus code depends on this; we don't care. */
typedef __kernel_uid_t __kernel_old_uid_t; typedef __kernel_uid_t __kernel_old_uid_t;
typedef unsigned int __kernel_old_dev_t;
typedef struct { typedef struct {
#if defined(__KERNEL__) || defined(__USE_ALL) #if defined(__KERNEL__) || defined(__USE_ALL)
......
...@@ -22,8 +22,8 @@ typedef long __kernel_ptrdiff_t; ...@@ -22,8 +22,8 @@ typedef long __kernel_ptrdiff_t;
typedef long __kernel_time_t; typedef long __kernel_time_t;
typedef long __kernel_suseconds_t; typedef long __kernel_suseconds_t;
typedef long __kernel_clock_t; typedef long __kernel_clock_t;
typedef int __kernel_timer_t; typedef int __kernel_timer_t;
typedef int __kernel_clockid_t; typedef int __kernel_clockid_t;
typedef int __kernel_daddr_t; typedef int __kernel_daddr_t;
typedef char * __kernel_caddr_t; typedef char * __kernel_caddr_t;
typedef unsigned short __kernel_uid16_t; typedef unsigned short __kernel_uid16_t;
...@@ -42,6 +42,8 @@ typedef __kernel_gid_t __kernel_old_gid_t; ...@@ -42,6 +42,8 @@ typedef __kernel_gid_t __kernel_old_gid_t;
typedef __kernel_uid_t __kernel_uid32_t; typedef __kernel_uid_t __kernel_uid32_t;
typedef __kernel_gid_t __kernel_gid32_t; typedef __kernel_gid_t __kernel_gid32_t;
typedef unsigned long __kernel_old_dev_t;
#ifdef __KERNEL__ #ifdef __KERNEL__
#undef __FD_SET #undef __FD_SET
......
#ifndef _LINUX_LOOP_H #ifndef _LINUX_LOOP_H
#define _LINUX_LOOP_H #define _LINUX_LOOP_H
#include <linux/kdev_t.h>
/* /*
* include/linux/loop.h * include/linux/loop.h
* *
...@@ -74,34 +72,37 @@ typedef int (* transfer_proc_t)(struct loop_device *, int cmd, ...@@ -74,34 +72,37 @@ typedef int (* transfer_proc_t)(struct loop_device *, int cmd,
#define LO_FLAGS_READ_ONLY 2 #define LO_FLAGS_READ_ONLY 2
#define LO_FLAGS_BH_REMAP 4 #define LO_FLAGS_BH_REMAP 4
/* #include <asm/posix_types.h> /* for __kernel_old_dev_t */
* Note that this structure gets the wrong offsets when directly used #include <asm/types.h> /* for __u64 */
* 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
*/
/* Backwards compatibility version */
struct loop_info { struct loop_info {
int lo_number; /* ioctl r/o */ int lo_number; /* ioctl r/o */
dev_t lo_device; /* ioctl r/o */ __kernel_old_dev_t lo_device; /* ioctl r/o */
unsigned long lo_inode; /* ioctl r/o */ unsigned long lo_inode; /* ioctl r/o */
dev_t lo_rdevice; /* ioctl r/o */ __kernel_old_dev_t lo_rdevice; /* ioctl r/o */
int lo_offset; int lo_offset;
int lo_encrypt_type; int lo_encrypt_type;
int lo_encrypt_key_size; /* ioctl w/o */ int lo_encrypt_key_size; /* ioctl w/o */
int lo_flags; /* ioctl r/o */ int lo_flags; /* ioctl r/o */
char lo_name[LO_NAME_SIZE]; char lo_name[LO_NAME_SIZE];
unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
unsigned long lo_init[2]; unsigned long lo_init[2];
char reserved[4]; 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 { ...@@ -125,7 +126,7 @@ struct loop_func_table {
int number; /* filter type */ int number; /* filter type */
int (*transfer)(struct loop_device *lo, int cmd, char *raw_buf, int (*transfer)(struct loop_device *lo, int cmd, char *raw_buf,
char *loop_buf, int size, sector_t real_block); 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 */ /* release is called from loop_unregister_transfer or clr_fd */
int (*release)(struct loop_device *); int (*release)(struct loop_device *);
int (*ioctl)(struct loop_device *, int cmd, unsigned long arg); int (*ioctl)(struct loop_device *, int cmd, unsigned long arg);
...@@ -134,7 +135,7 @@ struct loop_func_table { ...@@ -134,7 +135,7 @@ struct loop_func_table {
void (*unlock)(struct loop_device *); 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); int loop_unregister_transfer(int number);
#endif #endif
...@@ -142,9 +143,11 @@ int loop_unregister_transfer(int number); ...@@ -142,9 +143,11 @@ int loop_unregister_transfer(int number);
* IOCTL commands --- we will commandeer 0x4C ('L') * IOCTL commands --- we will commandeer 0x4C ('L')
*/ */
#define LOOP_SET_FD 0x4C00 #define LOOP_SET_FD 0x4C00
#define LOOP_CLR_FD 0x4C01 #define LOOP_CLR_FD 0x4C01
#define LOOP_SET_STATUS 0x4C02 #define LOOP_SET_STATUS 0x4C02
#define LOOP_GET_STATUS 0x4C03 #define LOOP_GET_STATUS 0x4C03
#define LOOP_SET_STATUS64 0x4C04
#define LOOP_GET_STATUS64 0x4C05
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment