Gather writes to larger chunks (MAXPHYS) instead of issuing them in
sectors. On my SanDisk Cruzer Blade 16GB USB stick this made formatting much faster: x before + after +--------------------------------------------------------------------------+ |+ | |+ x | |+ x x| |A MA|| +--------------------------------------------------------------------------+ N Min Max Median Avg Stddev x 3 15.89 16.38 16 16.09 0.2570992 + 3 0.32 0.37 0.35 0.34666667 0.025166115 Difference at 95.0% confidence -15.7433 +/- 0.414029 -97.8455% +/- 0.25668% (Student's t, pooled s = 0.182665) Reviewed by: emaste MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D24508
This commit is contained in:
parent
6ef8f9d28a
commit
33c2d974d0
@ -64,6 +64,7 @@ static const char rcsid[] =
|
|||||||
|
|
||||||
#define DOSMAGIC 0xaa55 /* DOS magic number */
|
#define DOSMAGIC 0xaa55 /* DOS magic number */
|
||||||
#define MINBPS 512 /* minimum bytes per sector */
|
#define MINBPS 512 /* minimum bytes per sector */
|
||||||
|
#define MAXBPS 4096 /* maximum bytes per sector */
|
||||||
#define MAXSPC 128 /* maximum sectors per cluster */
|
#define MAXSPC 128 /* maximum sectors per cluster */
|
||||||
#define MAXNFT 16 /* maximum number of FATs */
|
#define MAXNFT 16 /* maximum number of FATs */
|
||||||
#define DEFBLK 4096 /* default block size */
|
#define DEFBLK 4096 /* default block size */
|
||||||
@ -77,6 +78,25 @@ static const char rcsid[] =
|
|||||||
#define MAXCLS16 0xfff4U /* maximum FAT16 clusters */
|
#define MAXCLS16 0xfff4U /* maximum FAT16 clusters */
|
||||||
#define MAXCLS32 0xffffff4U /* maximum FAT32 clusters */
|
#define MAXCLS32 0xffffff4U /* maximum FAT32 clusters */
|
||||||
|
|
||||||
|
#ifndef CTASSERT
|
||||||
|
#define CTASSERT(x) _CTASSERT(x, __LINE__)
|
||||||
|
#define _CTASSERT(x, y) __CTASSERT(x, y)
|
||||||
|
#define __CTASSERT(x, y) typedef char __assert_ ## y [(x) ? 1 : -1]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For better performance, we want to write larger chunks instead of
|
||||||
|
* individual sectors (the size can only be 512, 1024, 2048 or 4096
|
||||||
|
* bytes). Assert that MAXPHYS can always hold an integer number of
|
||||||
|
* sectors by asserting that both are power of two numbers and the
|
||||||
|
* MAXPHYS is greater than MAXBPS.
|
||||||
|
*/
|
||||||
|
CTASSERT(powerof2(MAXPHYS));
|
||||||
|
CTASSERT(powerof2(MAXBPS));
|
||||||
|
CTASSERT(MAXPHYS > MAXBPS);
|
||||||
|
|
||||||
|
const static ssize_t chunksize = MAXPHYS;
|
||||||
|
|
||||||
#define mincls(fat) ((fat) == 12 ? MINCLS12 : \
|
#define mincls(fat) ((fat) == 12 ? MINCLS12 : \
|
||||||
(fat) == 16 ? MINCLS16 : \
|
(fat) == 16 ? MINCLS16 : \
|
||||||
MINCLS32)
|
MINCLS32)
|
||||||
@ -243,6 +263,7 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
|
|||||||
struct bsx *bsx;
|
struct bsx *bsx;
|
||||||
struct de *de;
|
struct de *de;
|
||||||
u_int8_t *img;
|
u_int8_t *img;
|
||||||
|
u_int8_t *physbuf, *physbuf_end;
|
||||||
const char *bname;
|
const char *bname;
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
time_t now;
|
time_t now;
|
||||||
@ -252,7 +273,7 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
|
|||||||
int fd, fd1, rv;
|
int fd, fd1, rv;
|
||||||
struct msdos_options o = *op;
|
struct msdos_options o = *op;
|
||||||
|
|
||||||
img = NULL;
|
physbuf = NULL;
|
||||||
rv = -1;
|
rv = -1;
|
||||||
fd = fd1 = -1;
|
fd = fd1 = -1;
|
||||||
|
|
||||||
@ -343,13 +364,11 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
|
|||||||
bpb.bpbSecPerClust = 64; /* otherwise 32k */
|
bpb.bpbSecPerClust = 64; /* otherwise 32k */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!powerof2(bpb.bpbBytesPerSec)) {
|
if (bpb.bpbBytesPerSec < MINBPS ||
|
||||||
warnx("bytes/sector (%u) is not a power of 2", bpb.bpbBytesPerSec);
|
bpb.bpbBytesPerSec > MAXBPS ||
|
||||||
goto done;
|
!powerof2(bpb.bpbBytesPerSec)) {
|
||||||
}
|
warnx("Invalid bytes/sector (%u): must be 512, 1024, 2048 or 4096",
|
||||||
if (bpb.bpbBytesPerSec < MINBPS) {
|
bpb.bpbBytesPerSec);
|
||||||
warnx("bytes/sector (%u) is too small; minimum is %u",
|
|
||||||
bpb.bpbBytesPerSec, MINBPS);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,11 +640,14 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
|
|||||||
tm = localtime(&now);
|
tm = localtime(&now);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
physbuf = malloc(chunksize);
|
||||||
if (!(img = malloc(bpb.bpbBytesPerSec))) {
|
if (physbuf == NULL) {
|
||||||
warn(NULL);
|
warn(NULL);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
physbuf_end = physbuf + chunksize;
|
||||||
|
img = physbuf;
|
||||||
|
|
||||||
dir = bpb.bpbResSectors + (bpb.bpbFATsecs ? bpb.bpbFATsecs :
|
dir = bpb.bpbResSectors + (bpb.bpbFATsecs ? bpb.bpbFATsecs :
|
||||||
bpb.bpbBigFATsecs) * bpb.bpbFATs;
|
bpb.bpbBigFATsecs) * bpb.bpbFATs;
|
||||||
memset(&si_sa, 0, sizeof(si_sa));
|
memset(&si_sa, 0, sizeof(si_sa));
|
||||||
@ -750,19 +772,37 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
|
|||||||
(u_int)tm->tm_mday;
|
(u_int)tm->tm_mday;
|
||||||
mk2(de->deMDate, x);
|
mk2(de->deMDate, x);
|
||||||
}
|
}
|
||||||
if ((n = write(fd, img, bpb.bpbBytesPerSec)) == -1) {
|
/*
|
||||||
warn("%s", fname);
|
* Issue a write of chunksize once we have collected
|
||||||
goto done;
|
* enough sectors.
|
||||||
}
|
*/
|
||||||
if ((unsigned)n != bpb.bpbBytesPerSec) {
|
img += bpb.bpbBytesPerSec;
|
||||||
warnx("%s: can't write sector %u", fname, lsn);
|
if (img >= physbuf_end) {
|
||||||
goto done;
|
n = write(fd, physbuf, chunksize);
|
||||||
|
if (n != chunksize) {
|
||||||
|
warnx("%s: can't write sector %u", fname, lsn);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
img = physbuf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Write remaining sectors, if the last write didn't end
|
||||||
|
* up filling a whole chunk.
|
||||||
|
*/
|
||||||
|
if (img != physbuf) {
|
||||||
|
ssize_t tailsize = img - physbuf;
|
||||||
|
|
||||||
|
n = write(fd, physbuf, tailsize);
|
||||||
|
if (n != tailsize) {
|
||||||
|
warnx("%s: can't write sector %u", fname, lsn);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rv = 0;
|
rv = 0;
|
||||||
done:
|
done:
|
||||||
free(img);
|
free(physbuf);
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
close(fd);
|
close(fd);
|
||||||
if (fd1 != -1)
|
if (fd1 != -1)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user