#include <linux/capability.h>
#include <linux/blkdev.h>
#include <linux/export.h>
#include <linux/backing-dev.h>
#include <linux/blktrace_api.h>
#include <linux/uaccess.h>
static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user *arg)
struct block_device *bdevp;
struct hd_struct *part, *lpart;
struct blkpg_ioctl_arg a;
struct blkpg_partition p;
struct disk_part_iter piter;
if (!capable(CAP_SYS_ADMIN))
if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg)))
if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
if (bdev != bdev->bd_contains)
case BLKPG_ADD_PARTITION:
if (sizeof(sector_t) == sizeof(long) &&
sizeof(long long) > sizeof(long)) {
long pstart = start, plength = length;
if (pstart != start || plength != length
|| pstart < 0 || plength < 0 || partno > 65535)
if (p.start & (bdev_logical_block_size(bdev) - 1))
mutex_lock(&bdev->bd_mutex);
disk_part_iter_init(&piter, disk,
while ((part = disk_part_iter_next(&piter))) {
if (!(start + length <= part->start_sect ||
start >= part->start_sect + part->nr_sects)) {
disk_part_iter_exit(&piter);
mutex_unlock(&bdev->bd_mutex);
disk_part_iter_exit(&piter);
part = add_partition(disk, partno, start, length,
ADDPART_FLAG_NONE, NULL);
mutex_unlock(&bdev->bd_mutex);
return PTR_ERR_OR_ZERO(part);
case BLKPG_DEL_PARTITION:
part = disk_get_part(disk, partno);
bdevp = bdget(part_devt(part));
mutex_lock(&bdevp->bd_mutex);
mutex_unlock(&bdevp->bd_mutex);