diff options
author | Vivek Goyal <vgoyal@redhat.com> | 2012-08-01 06:24:18 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2012-08-01 06:24:18 -0400 |
commit | c83f6bf98dc1f1a194118b3830706cebbebda8c4 (patch) | |
tree | ea8fbd925584f784164617964a9f025bda16ed15 /block/partition-generic.c | |
parent | 4638a83e8615de9c16c39dfed234951d0f468cf1 (diff) |
block: add partition resize function to blkpg ioctl
Add a new operation code (BLKPG_RESIZE_PARTITION) to the BLKPG ioctl that
allows altering the size of an existing partition, even if it is currently
in use.
This patch converts hd_struct->nr_sects into sequence counter because
One might extend a partition while IO is happening to it and update of
nr_sects can be non-atomic on 32bit machines with 64bit sector_t. This
can lead to issues like reading inconsistent size of a partition. Sequence
counter have been used so that readers don't have to take bdev mutex lock
as we call sector_in_part() very frequently.
Now all the access to hd_struct->nr_sects should happen using sequence
counter read/update helper functions part_nr_sects_read/part_nr_sects_write.
There is one exception though, set_capacity()/get_capacity(). I think
theoritically race should exist there too but this patch does not
modify set_capacity()/get_capacity() due to sheer number of call sites
and I am afraid that change might break something. I have left that as a
TODO item. We can handle it later if need be. This patch does not introduce
any new races as such w.r.t set_capacity()/get_capacity().
v2: Add CONFIG_LBDAF test to UP preempt case as suggested by Phillip.
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Phillip Susi <psusi@ubuntu.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/partition-generic.c')
-rw-r--r-- | block/partition-generic.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/block/partition-generic.c b/block/partition-generic.c index 6df5d6928a44..f1d14519cc04 100644 --- a/block/partition-generic.c +++ b/block/partition-generic.c | |||
@@ -84,7 +84,7 @@ ssize_t part_size_show(struct device *dev, | |||
84 | struct device_attribute *attr, char *buf) | 84 | struct device_attribute *attr, char *buf) |
85 | { | 85 | { |
86 | struct hd_struct *p = dev_to_part(dev); | 86 | struct hd_struct *p = dev_to_part(dev); |
87 | return sprintf(buf, "%llu\n",(unsigned long long)p->nr_sects); | 87 | return sprintf(buf, "%llu\n",(unsigned long long)part_nr_sects_read(p)); |
88 | } | 88 | } |
89 | 89 | ||
90 | static ssize_t part_ro_show(struct device *dev, | 90 | static ssize_t part_ro_show(struct device *dev, |
@@ -294,6 +294,8 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, | |||
294 | err = -ENOMEM; | 294 | err = -ENOMEM; |
295 | goto out_free; | 295 | goto out_free; |
296 | } | 296 | } |
297 | |||
298 | seqcount_init(&p->nr_sects_seq); | ||
297 | pdev = part_to_dev(p); | 299 | pdev = part_to_dev(p); |
298 | 300 | ||
299 | p->start_sect = start; | 301 | p->start_sect = start; |