fs: guard_bio_eod() needs to consider partitions
PATCH 1/1 fs: guard_bio_eod() needs to consider partitions
guard_bio_eod() needs to look at the partition capacity, not just the capacity of the whole device, when determining if truncation is necessary.
[ 60.268688] attempt to access beyond end of device [ 60.268690] unknown-block(9,1): rw=0, want=67103509, limit=67103506 [ 60.268693] buffer_io_error: 2 callbacks suppressed [ 60.268696] Buffer I/O error on dev md1p7, logical block 4524305, async page read
--- fs/buffer.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
fs/buffer.c +8 -1
@@ -3055,8 +3055,15 @@ void guard_bio_eod(int op, struct bio *bio)sector_t maxsector;struct bio_vec *bvec = &bio->bi_io_vec[bio->bi_vcnt -1 ];unsigned truncated_bytes; +struct hd_struct *part; + + part =disk_get_part (bio->bi_disk, bio->bi_partno); +if (part) + maxsector =part_nr_sects_read (part); +else + maxsector =get_capacity (bio->bi_disk); +disk_put_part (part); - maxsector =get_capacity (bio->bi_disk);if (!maxsector)return ;
Signature · 1 line
2.13.6
Al Viro
maintainerQuoted 11 lines · Greg Edwards
guard_bio_eod()needs to look at the partition capacity, not just the capacity of the whole device, when determining if truncation is necessary.[ 60.268688] attempt to access beyond end of device [ 60.268690] unknown-block(9,1): rw=0, want=67103509, limit=67103506 [ 60.268693] buffer_io_error: 2 callbacks suppressed [ 60.268696] Buffer I/O error on dev md1p7, logical block 4524305, async page readFixes 74d46992e0d9 ("block: replace bi_bdev with a gendisk pointer and partitions index")Signed-off-by Greg Edwards <[email protected]>
That smells like a nasty source of overhead, especially on SMP boxen...
Quoted 4 lines · Al Viro
Quoted 2 lines
Fixes 74d46992e0d9 ("block: replace bi_bdev with a gendisk pointer and partitions index")Signed-off-by Greg Edwards <[email protected]>That smells like a nasty source of overhead, especially on SMP boxen...
We could just use __disk_get_part similar to the partition remapping, or just pass the block_device to guard_bio_eod.
Quoted 8 lines · Christoph Hellwig
Quoted 4 lines · Al Viro
Quoted 2 lines
Fixes 74d46992e0d9 ("block: replace bi_bdev with a gendisk pointer and partitions index")Signed-off-by Greg Edwards <[email protected]>That smells like a nasty source of overhead, especially on SMP boxen...
We could just use
__disk_get_partsimilar to the partition remapping, or just pass theblock_devicetoguard_bio_eod.
Do you have a preference? __disk_get_part would be isolated to guard_bio_eod. If we pass in the block_device, it would also touch all the mpage_bio_submit callers.
PATCH v2 1/1 fs: guard_bio_eod() needs to consider partitions
In reply to Greg Edwardsguard_bio_eod() needs to look at the partition capacity, not just the capacity of the whole device, when determining if truncation is necessary.
[ 60.268688] attempt to access beyond end of device [ 60.268690] unknown-block(9,1): rw=0, want=67103509, limit=67103506 [ 60.268693] buffer_io_error: 2 callbacks suppressed [ 60.268696] Buffer I/O error on dev md1p7, logical block 4524305, async page read
---
Changes from v1:
* use __disk_get_part instead of disk_get_part, similar to what blk_partition_remap does
fs/buffer.c | 10 +++++++++- include/linux/genhd.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-)
fs/buffer.c +9 -1
@@ -3055,8 +3055,16 @@ void guard_bio_eod(int op, struct bio *bio)sector_t maxsector;struct bio_vec *bvec = &bio->bi_io_vec[bio->bi_vcnt -1 ];unsigned truncated_bytes; +struct hd_struct *part; + +rcu_read_lock (); + part =__disk_get_part (bio->bi_disk, bio->bi_partno); +if (part) + maxsector =part_nr_sects_read (part); +else + maxsector =get_capacity (bio->bi_disk); +rcu_read_unlock (); - maxsector =get_capacity (bio->bi_disk);if (!maxsector)return ;
include/linux/genhd.h +1 -0
@@ -242,6 +242,7 @@ static inline dev_t part_devt(struct hd_struct *part)return part_to_dev (part)->devt; } +extern struct hd_struct *__disk_get_part (struct gendisk *disk,int partno);extern struct hd_struct *disk_get_part (struct gendisk *disk,int partno);static inline void disk_put_part (struct hd_struct *part)
Signature · 1 line
2.13.6
Quoted 9 lines · Greg Edwards
guard_bio_eod()needs to look at the partition capacity, not just the capacity of the whole device, when determining if truncation is necessary.[ 60.268688] attempt to access beyond end of device [ 60.268690] unknown-block(9,1): rw=0, want=67103509, limit=67103506 [ 60.268693] buffer_io_error: 2 callbacks suppressed [ 60.268696] Buffer I/O error on dev md1p7, logical block 4524305, async page read
Quoted 6 lines
Fixes 74d46992e0d9 ("block: replace bi_bdev with a gendisk pointer and partitions index")Signed-off-by Greg Edwards <[email protected]>---
Changes from v1:
* use__disk_get_partinstead ofdisk_get_part, similar to whatblk_partition_remapdoes
Al, Christoph,
Any thoughts on this version?
It would be nice to get this fixed before 4.14 goes out, as this is a regression from previous releases.
Greg
This looks good to me:
Jens, can you pick it up through the block tree given that is where the issue was introduced?
Quoted 6 lines · Christoph Hellwig
This looks good to me:
Reviewed-by Christoph Hellwig <[email protected]>Jens, can you pick it up through the block tree given that is where the issue was introduced?
I picked it up, and marked it for 4.13 stable as well.
Signature · 1 line
Jens Axboe