-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 66091 b: refs/heads/master c: f58c4c0 h: refs/heads/master i: 66089: 4883022 66087: 486787f v: v3
- Loading branch information
Arnd Bergmann
authored and
Jens Axboe
committed
Oct 10, 2007
1 parent
b6d9eb5
commit 304c9c3
Showing
5 changed files
with
127 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: d2bbf3da3759d04cd5836955cc59c8ae96092831 | ||
refs/heads/master: f58c4c0a17e500e767473598b3deafaa1d64051d |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
#include <linux/blkdev.h> | ||
#include <linux/blkpg.h> | ||
#include <linux/blktrace_api.h> | ||
#include <linux/cdrom.h> | ||
#include <linux/compat.h> | ||
#include <linux/elevator.h> | ||
#include <linux/fd.h> | ||
#include <linux/hdreg.h> | ||
#include <linux/syscalls.h> | ||
#include <linux/smp_lock.h> | ||
#include <linux/types.h> | ||
#include <linux/uaccess.h> | ||
|
||
static int compat_put_ushort(unsigned long arg, unsigned short val) | ||
{ | ||
return put_user(val, (unsigned short __user *)compat_ptr(arg)); | ||
} | ||
|
||
static int compat_put_int(unsigned long arg, int val) | ||
{ | ||
return put_user(val, (compat_int_t __user *)compat_ptr(arg)); | ||
} | ||
|
||
static int compat_put_long(unsigned long arg, long val) | ||
{ | ||
return put_user(val, (compat_long_t __user *)compat_ptr(arg)); | ||
} | ||
|
||
static int compat_put_ulong(unsigned long arg, compat_ulong_t val) | ||
{ | ||
return put_user(val, (compat_ulong_t __user *)compat_ptr(arg)); | ||
} | ||
|
||
static int compat_put_u64(unsigned long arg, u64 val) | ||
{ | ||
return put_user(val, (compat_u64 __user *)compat_ptr(arg)); | ||
} | ||
|
||
#define BLKBSZGET_32 _IOR(0x12, 112, int) | ||
#define BLKBSZSET_32 _IOW(0x12, 113, int) | ||
#define BLKGETSIZE64_32 _IOR(0x12, 114, int) | ||
|
||
static int compat_blkdev_locked_ioctl(struct inode *inode, struct file *file, | ||
struct block_device *bdev, | ||
unsigned cmd, unsigned long arg) | ||
{ | ||
struct backing_dev_info *bdi; | ||
|
||
switch (cmd) { | ||
case BLKRAGET: | ||
case BLKFRAGET: | ||
if (!arg) | ||
return -EINVAL; | ||
bdi = blk_get_backing_dev_info(bdev); | ||
if (bdi == NULL) | ||
return -ENOTTY; | ||
return compat_put_long(arg, | ||
(bdi->ra_pages * PAGE_CACHE_SIZE) / 512); | ||
case BLKROGET: /* compatible */ | ||
return compat_put_int(arg, bdev_read_only(bdev) != 0); | ||
case BLKBSZGET_32: /* get the logical block size (cf. BLKSSZGET) */ | ||
return compat_put_int(arg, block_size(bdev)); | ||
case BLKSSZGET: /* get block device hardware sector size */ | ||
return compat_put_int(arg, bdev_hardsect_size(bdev)); | ||
case BLKSECTGET: | ||
return compat_put_ushort(arg, | ||
bdev_get_queue(bdev)->max_sectors); | ||
case BLKRASET: /* compatible, but no compat_ptr (!) */ | ||
case BLKFRASET: | ||
if (!capable(CAP_SYS_ADMIN)) | ||
return -EACCES; | ||
bdi = blk_get_backing_dev_info(bdev); | ||
if (bdi == NULL) | ||
return -ENOTTY; | ||
bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; | ||
return 0; | ||
case BLKGETSIZE: | ||
if ((bdev->bd_inode->i_size >> 9) > ~0UL) | ||
return -EFBIG; | ||
return compat_put_ulong(arg, bdev->bd_inode->i_size >> 9); | ||
|
||
case BLKGETSIZE64_32: | ||
return compat_put_u64(arg, bdev->bd_inode->i_size); | ||
} | ||
return -ENOIOCTLCMD; | ||
} | ||
|
||
/* Most of the generic ioctls are handled in the normal fallback path. | ||
This assumes the blkdev's low level compat_ioctl always returns | ||
ENOIOCTLCMD for unknown ioctls. */ | ||
long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) | ||
{ | ||
int ret = -ENOIOCTLCMD; | ||
struct inode *inode = file->f_mapping->host; | ||
struct block_device *bdev = inode->i_bdev; | ||
struct gendisk *disk = bdev->bd_disk; | ||
|
||
switch (cmd) { | ||
case BLKFLSBUF: | ||
case BLKROSET: | ||
/* | ||
* the ones below are implemented in blkdev_locked_ioctl, | ||
* but we call blkdev_ioctl, which gets the lock for us | ||
*/ | ||
case BLKRRPART: | ||
return blkdev_ioctl(inode, file, cmd, | ||
(unsigned long)compat_ptr(arg)); | ||
case BLKBSZSET_32: | ||
return blkdev_ioctl(inode, file, BLKBSZSET, | ||
(unsigned long)compat_ptr(arg)); | ||
} | ||
|
||
lock_kernel(); | ||
ret = compat_blkdev_locked_ioctl(inode, file, bdev, cmd, arg); | ||
/* FIXME: why do we assume -> compat_ioctl needs the BKL? */ | ||
if (ret == -ENOIOCTLCMD && disk->fops->compat_ioctl) | ||
ret = disk->fops->compat_ioctl(file, cmd, arg); | ||
unlock_kernel(); | ||
|
||
return ret; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters