On 11/29/2011 11:02 AM, Petr Uzel wrote:
I was also thinking about some new BLKPG-like ioctl()s. Could you please elaborate more on your new ioctl() proposal? Perhaps we could combine the ideas...
I just added one to update the length of the partition. Attaching the patch so far ( untested ).
Features of the new ioctl()/s I was thinking about are: - get largest number of partition known to the kernel - atomically add/remove more than one partition
What benefit would those provide?
>From 4c533c3198031378eb80c919e00d7875db466ac8 Mon Sep 17 00:00:00 2001 From: Phillip Susi <[email protected]> Date: Tue, 29 Nov 2011 16:01:29 -0500 Subject: [PATCH] Add partition resize function to BLKPG ioctl Add a new operation code ( BLKPG_RES_PARTITION ) to the BLKPG ioctl that allows altering the size of an existing partition, even if it is currently in use. --- block/ioctl.c | 42 ++++++++++++++++++++++++++++++++++++++++++ include/linux/blkpg.h | 1 + 2 files changed, 43 insertions(+), 0 deletions(-) diff --git a/block/ioctl.c b/block/ioctl.c index ca939fc..3787f59 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -92,6 +92,48 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user bdput(bdevp); return 0; + case BLKPG_RES_PARTITION: + start = p.start >> 9; + length = p.length >> 9; + /* check for fit in a hd_struct */ + 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) + return -EINVAL; + } + + mutex_lock(&bdev->bd_mutex); + + /* overlap? */ + disk_part_iter_init(&piter, disk, + DISK_PITER_INCL_EMPTY); + while ((part = disk_part_iter_next(&piter))) { + if (part->partno != partno && !(start + length <= part->start_sect || + start >= part->start_sect + part->nr_sects)) { + disk_part_iter_exit(&piter); + mutex_unlock(&bdev->bd_mutex); + return -EBUSY; + } + } + disk_part_iter_exit(&piter); + part = disk_get_part(disk, partno); + if (!part) + { + mutex_unlock(&bdev->bd_mutex); + return -ENXIO; + } + if (start != part->start_sect) + { + mutex_unlock(&bdev->bd_mutex); + disk_put_part(part); + return -EINVAL; + } + part->nr_sects = length; + disk_put_part(part); + mutex_unlock(&bdev->bd_mutex); + return 0; default: return -EINVAL; } diff --git a/include/linux/blkpg.h b/include/linux/blkpg.h index faf8a45..103da38 100644 --- a/include/linux/blkpg.h +++ b/include/linux/blkpg.h @@ -40,6 +40,7 @@ struct blkpg_ioctl_arg { /* The subfunctions (for the op field) */ #define BLKPG_ADD_PARTITION 1 #define BLKPG_DEL_PARTITION 2 +#define BLKPG_RES_PARTITION 3 /* Sizes of name fields. Unused at present. */ #define BLKPG_DEVNAMELTH 64 -- 1.7.5.4

