> MNT=/mnt > IMG=./DISK.img > DEV=/dev/loop0 > My apologies. I forgot to mention I had ./DISK.img already created in my working tree, it's a simple `dd if=/dev/zero of=./DISK.img bs=1m count=20`. The image should be slighter larger than 16247280, so the FS attempts to step out of the device. > mkfs.vfat $IMG > mount $IMG $MNT > cp -R /etc $MNT &> /dev/null > umount $MNT > > losetup -D > > losetup --find --show --sizelimit 16247280 $IMG > mount $DEV $MNT > > find $MNT -type f -exec cat {} + >/dev/null > > Kudos to Eric Sandeen for coming up with the reproducer above > > Signed-off-by: Carlos Maiolino <cmaiolino@xxxxxxxxxx> > --- > > P.S. I'm not 100% proficient in bio internals, so I'm not sure if this is the > right fix, so comments are much appreciated. > Thanks > > fs/buffer.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/fs/buffer.c b/fs/buffer.c > index 784de3dbcf28..32dc5cd2f6ba 100644 > --- a/fs/buffer.c > +++ b/fs/buffer.c > @@ -3063,6 +3063,13 @@ void guard_bio_eod(int op, struct bio *bio) > /* Uhhuh. We've got a bio that straddles the device size! */ > truncated_bytes = bio->bi_iter.bi_size - (maxsector << 9); > > + /* > + * The bio contains more than one segment which spans EOD, just return > + * and let IO layer turn it into an EIO > + */ > + if (truncated_bytes > PAGE_SIZE) > + return; > + > /* Truncate the bio.. */ > bio->bi_iter.bi_size -= truncated_bytes; > bvec->bv_len -= truncated_bytes; > -- > 2.17.2 > -- Carlos