Skip to content

Commit

Permalink
Fail early on bio corruption confirmed on 5.2-rc1
Browse files Browse the repository at this point in the history
Unable to import zpool with "Large kmem_alloc" warning due to
corrupted bio's with invalid # of page vectors.
See #8867 for details.

Fail early with ENOMEM.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Tomohiro Kusumi <kusumi.tomohiro@gmail.com>
Closes #8867 
Closes #8961
  • Loading branch information
kusumi authored and behlendorf committed Jul 3, 2019
1 parent 46db9d6 commit aa7aab6
Showing 1 changed file with 6 additions and 4 deletions.
10 changes: 6 additions & 4 deletions module/zfs/vdev_disk.c
Expand Up @@ -621,6 +621,7 @@ __vdev_disk_physio(struct block_device *bdev, zio_t *zio,
bio_offset = io_offset;
bio_size = io_size;
for (i = 0; i <= dr->dr_bio_count; i++) {
unsigned int nr_iovecs;

/* Finished constructing bio's for given buffer */
if (bio_size <= 0)
Expand All @@ -638,10 +639,11 @@ __vdev_disk_physio(struct block_device *bdev, zio_t *zio,
}

/* bio_alloc() with __GFP_WAIT never returns NULL */
dr->dr_bio[i] = bio_alloc(GFP_NOIO,
MIN(abd_nr_pages_off(zio->io_abd, bio_size, abd_offset),
BIO_MAX_PAGES));
if (unlikely(dr->dr_bio[i] == NULL)) {
nr_iovecs = MIN(abd_nr_pages_off(zio->io_abd, bio_size,
abd_offset), BIO_MAX_PAGES);
dr->dr_bio[i] = bio_alloc(GFP_NOIO, nr_iovecs);
if (unlikely(dr->dr_bio[i] == NULL ||
(unsigned int)dr->dr_bio[i]->bi_max_vecs != nr_iovecs)) {
vdev_disk_dio_free(dr);
return (SET_ERROR(ENOMEM));
}
Expand Down

0 comments on commit aa7aab6

Please sign in to comment.