summaryrefslogtreecommitdiff
path: root/block/partitions
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2020-11-26 20:43:37 +0300
committerJens Axboe <axboe@kernel.dk>2020-12-02 00:53:40 +0300
commita782483cc1f875355690625d8253a232f2581418 (patch)
tree492d3bf67cdd2535afd826dde93aa35dcfb42180 /block/partitions
parente6cb53827ed60019bbbc5cf189dd204b3b0e8121 (diff)
downloadlinux-a782483cc1f875355690625d8253a232f2581418.tar.xz
block: remove the nr_sects field in struct hd_struct
Now that the hd_struct always has a block device attached to it, there is no need for having two size field that just get out of sync. Additionally the field in hd_struct did not use proper serialization, possibly allowing for torn writes. By only using the block_device field this problem also gets fixed. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Hannes Reinecke <hare@suse.de> Acked-by: Coly Li <colyli@suse.de> [bcache] Acked-by: Chao Yu <yuchao0@huawei.com> [f2fs] Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/partitions')
-rw-r--r--block/partitions/core.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/block/partitions/core.c b/block/partitions/core.c
index 696bd9ff63c6..bcfa8215bd5e 100644
--- a/block/partitions/core.c
+++ b/block/partitions/core.c
@@ -85,6 +85,13 @@ static int (*check_part[])(struct parsed_partitions *) = {
NULL
};
+static void bdev_set_nr_sectors(struct block_device *bdev, sector_t sectors)
+{
+ spin_lock(&bdev->bd_size_lock);
+ i_size_write(bdev->bd_inode, (loff_t)sectors << SECTOR_SHIFT);
+ spin_unlock(&bdev->bd_size_lock);
+}
+
static struct parsed_partitions *allocate_partitions(struct gendisk *hd)
{
struct parsed_partitions *state;
@@ -295,7 +302,7 @@ static void hd_struct_free_work(struct work_struct *work)
put_device(disk_to_dev(disk));
part->start_sect = 0;
- part->nr_sects = 0;
+ bdev_set_nr_sectors(part->bdev, 0);
part_stat_set_all(part, 0);
put_device(part_to_dev(part));
}
@@ -412,11 +419,10 @@ static struct hd_struct *add_partition(struct gendisk *disk, int partno,
goto out_free_stats;
p->bdev = bdev;
- hd_sects_seq_init(p);
pdev = part_to_dev(p);
p->start_sect = start;
- p->nr_sects = len;
+ bdev_set_nr_sectors(bdev, len);
p->partno = partno;
p->policy = get_disk_ro(disk);
@@ -509,7 +515,7 @@ static bool partition_overlaps(struct gendisk *disk, sector_t start,
disk_part_iter_init(&piter, disk, DISK_PITER_INCL_EMPTY);
while ((part = disk_part_iter_next(&piter))) {
if (part->partno == skip_partno ||
- start >= part->start_sect + part->nr_sects ||
+ start >= part->start_sect + bdev_nr_sectors(part->bdev) ||
start + length <= part->start_sect)
continue;
overlap = true;
@@ -600,8 +606,7 @@ int bdev_resize_partition(struct block_device *bdev, int partno,
if (partition_overlaps(bdev->bd_disk, start, length, partno))
goto out_unlock;
- part_nr_sects_write(part, length);
- bd_set_nr_sectors(bdevp, length);
+ bdev_set_nr_sectors(bdevp, length);
ret = 0;
out_unlock: