On Thu, Dec 13, 2018 at 04:26:27PM -0500, Ted Unangst wrote: > Otto Moerbeek wrote: > > int > > biosd_diskio(int rw, struct diskinfo *dip, u_int off, int nsect, void *buf) > > { > > - return biosd_io(rw, &dip->bios_info, off, nsect, buf); > > + int i, n, ret; > > + > > + /* > > + * Avoid doing too large reads, the bounce buffer used by biosd_io() > > + * might run us out-of-mem. > > + */ > > + for (i = 0, ret = 0; ret == 0 && nsect > 0; > > + i += MAXSECTS, nsect -= MAXSECTS) { > > + n = nsect >= MAXSECTS ? MAXSECTS : nsect; > > + ret = biosd_io(rw, &dip->bios_info, off + i, n, > > + buf + i * DEV_BSIZE); > > you're doing pointer arithmetic on a void here. needs a cast. > > or perhaps something like this, eliminating i. > > char *dest = buf; > > for (ret = 0; ret == 0; off += MAXSECTS, dest += MAXSECTS * DEV_BSIZE) >
That would boil down to this, ok? -Otto Index: arch/amd64/stand/libsa/biosdev.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/stand/libsa/biosdev.c,v retrieving revision 1.32 diff -u -p -r1.32 biosdev.c --- arch/amd64/stand/libsa/biosdev.c 10 Aug 2018 16:41:35 -0000 1.32 +++ arch/amd64/stand/libsa/biosdev.c 15 Dec 2018 10:36:30 -0000 @@ -340,11 +340,26 @@ biosd_io(int rw, bios_diskinfo_t *bd, u_ return error; } +#define MAXSECTS 32 + int biosd_diskio(int rw, struct diskinfo *dip, u_int off, int nsect, void *buf) { - return biosd_io(rw, &dip->bios_info, off, nsect, buf); + char *dest = buf; + int n, ret; + + /* + * Avoid doing too large reads, the bounce buffer used by biosd_io() + * might run us out-of-mem. + */ + for (ret = 0; ret == 0 && nsect > 0; + off += MAXSECTS, dest += MAXSECTS * DEV_BSIZE, nsect -= MAXSECTS) { + n = nsect >= MAXSECTS ? MAXSECTS : nsect; + ret = biosd_io(rw, &dip->bios_info, off, n, dest); + } + return ret; } + /* * Try to read the bsd label on the given BIOS device. */ @@ -715,7 +730,6 @@ biosstrategy(void *devdata, int rw, dadd size_t *rsize) { struct diskinfo *dip = (struct diskinfo *)devdata; - bios_diskinfo_t *bd = &dip->bios_info; u_int8_t error = 0; size_t nsect; @@ -732,7 +746,7 @@ biosstrategy(void *devdata, int rw, dadd if (blk < 0) error = EINVAL; else - error = biosd_io(rw, bd, blk, nsect, buf); + error = biosd_diskio(rw, dip, blk, nsect, buf); #ifdef BIOS_DEBUG if (debug) { Index: arch/i386/stand/libsa/biosdev.c =================================================================== RCS file: /cvs/src/sys/arch/i386/stand/libsa/biosdev.c,v retrieving revision 1.98 diff -u -p -r1.98 biosdev.c --- arch/i386/stand/libsa/biosdev.c 6 Sep 2018 11:50:54 -0000 1.98 +++ arch/i386/stand/libsa/biosdev.c 15 Dec 2018 10:36:30 -0000 @@ -341,11 +341,26 @@ biosd_io(int rw, bios_diskinfo_t *bd, u_ return error; } +#define MAXSECTS 32 + int biosd_diskio(int rw, struct diskinfo *dip, u_int off, int nsect, void *buf) { - return biosd_io(rw, &dip->bios_info, off, nsect, buf); + char *dest = buf; + int n, ret; + + /* + * Avoid doing too large reads, the bounce buffer used by biosd_io() + * might run us out-of-mem. + */ + for (ret = 0; ret == 0 && nsect > 0; + off += MAXSECTS, dest += MAXSECTS * DEV_BSIZE, nsect -= MAXSECTS) { + n = nsect >= MAXSECTS ? MAXSECTS : nsect; + ret = biosd_io(rw, &dip->bios_info, off, n, dest); + } + return ret; } + /* * Try to read the bsd label on the given BIOS device. */ @@ -716,7 +731,6 @@ biosstrategy(void *devdata, int rw, dadd size_t *rsize) { struct diskinfo *dip = (struct diskinfo *)devdata; - bios_diskinfo_t *bd = &dip->bios_info; u_int8_t error = 0; size_t nsect; @@ -733,7 +747,7 @@ biosstrategy(void *devdata, int rw, dadd if (blk < 0) error = EINVAL; else - error = biosd_io(rw, bd, blk, nsect, buf); + error = biosd_diskio(rw, dip, blk, nsect, buf); #ifdef BIOS_DEBUG if (debug) { Index: lib/libsa/alloc.c =================================================================== RCS file: /cvs/src/sys/lib/libsa/alloc.c,v retrieving revision 1.12 diff -u -p -r1.12 alloc.c --- lib/libsa/alloc.c 14 Mar 2016 23:08:06 -0000 1.12 +++ lib/libsa/alloc.c 15 Dec 2018 10:36:31 -0000 @@ -169,7 +169,7 @@ alloc(unsigned int size) } /* no match in freelist if bestsize unchanged */ - failed = (bestsize == 0xffffffff); + failed = (bestsize == 0xffffffff || bestsize >= size * 2); #endif if (failed) { /* nothing found */