" -R -- write at random offsets in the specified range of bytes\n"
" -Z N -- zeed the random number generator (used when writing randomly)\n"
" (heh, zorry, the -s/-S arguments were already in use in pwrite)\n"
+" -V N -- use vectored IO with N iovecs of blocksize each (pwritev)\n"
"\n"));
}
+static int
+do_pwrite(
+ int fd,
+ off64_t offset,
+ ssize_t count,
+ ssize_t buffer_size)
+{
+ int vecs = 0;
+ ssize_t oldlen = 0;
+ ssize_t bytes = 0;
+
+
+ if (!vectors)
+ return pwrite64(fd, buffer, min(count, buffer_size), offset);
+
+ /* trim the iovec if necessary */
+ if (count < buffersize) {
+ size_t len = 0;
+ while (len + iov[vecs].iov_len < count) {
+ len += iov[vecs].iov_len;
+ vecs++;
+ }
+ oldlen = iov[vecs].iov_len;
+ iov[vecs].iov_len = count - len;
+ vecs++;
+ } else {
+ vecs = vectors;
+ }
+ bytes = pwritev(fd, iov, vectors, offset);
+
+ /* restore trimmed iov */
+ if (oldlen)
+ iov[vecs - 1].iov_len = oldlen;
+
+ return bytes;
+}
static int
write_random(
off64_t offset,
*total = 0;
while (count > 0) {
off = ((random() % range) / buffersize) * buffersize;
- bytes = pwrite64(file->fd, buffer, buffersize, off);
+ bytes = do_pwrite(file->fd, off, buffersize, buffersize);
if (bytes == 0)
break;
if (bytes < 0) {
if ((bytes_requested = (off % buffersize))) {
bytes_requested = min(cnt, bytes_requested);
off -= bytes_requested;
- bytes = pwrite(file->fd, buffer, bytes_requested, off);
+ bytes = do_pwrite(file->fd, off, bytes_requested, buffersize);
if (bytes == 0)
return ops;
if (bytes < 0) {
while (cnt > end) {
bytes_requested = min(cnt, buffersize);
off -= bytes_requested;
- bytes = pwrite64(file->fd, buffer, bytes_requested, off);
+ bytes = do_pwrite(file->fd, off, cnt, buffersize);
if (bytes == 0)
break;
if (bytes < 0) {
off64_t skip,
long long *total)
{
- size_t bytes_requested;
ssize_t bytes;
long long bar = min(bs, count);
int ops = 0;
if (read_buffer(fd, skip + *total, bs, &bar, 0, 1) < 0)
break;
}
- bytes_requested = min(bar, count);
- bytes = pwrite64(file->fd, buffer, bytes_requested, offset);
+ bytes = do_pwrite(file->fd, offset, count, bar);
if (bytes == 0)
break;
if (bytes < 0) {
}
ops++;
*total += bytes;
- if (bytes < bytes_requested)
+ if (bytes < min(count, bar))
break;
offset += bytes;
count -= bytes;
init_cvtnum(&fsblocksize, &fssectsize);
bsize = fsblocksize;
- while ((c = getopt(argc, argv, "b:Cdf:i:qs:S:uwWZ:")) != EOF) {
+ while ((c = getopt(argc, argv, "b:Cdf:i:qs:S:uV:wWZ:")) != EOF) {
switch (c) {
case 'b':
tmp = cvtnum(fsblocksize, fssectsize, optarg);
case 'u':
uflag = 1;
break;
+ case 'V':
+ vectors = strtoul(optarg, &sp, 0);
+ if (!sp || sp == optarg) {
+ printf(_("non-numberic vector count == %s\n"),
+ optarg);
+ return 0;
+ }
+ break;
case 'w':
wflag = 1;
break;
pwrite_cmd.argmax = -1;
pwrite_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
pwrite_cmd.args =
- _("[-i infile [-d] [-s skip]] [-b bs] [-S seed] [-wW] off len");
+_("[-i infile [-d] [-s skip]] [-b bs] [-S seed] [-wW] [-FBR [-Z N]] [-V N] off len");
pwrite_cmd.oneline =
_("writes a number of bytes at a specified offset");
pwrite_cmd.help = pwrite_help;
.B pread
command.
.TP
-.BI "pwrite [ \-i " file " ] [ \-d ] [ \-s " skip " ] [ \-b " size " ] [ \-S " seed " ] " "offset length"
+.BI "pwrite [ \-i " file " ] [ \-d ] [ \-s " skip " ] [ \-b " size " ] [ \-S " seed " ] [ \-FBR [ \-Z " zeed " ] ] [ \-wW ] [ \-V " vectors " ] " "offset length"
Writes a range of bytes in a specified blocksize from the given
.IR offset .
The bytes written can be either a set pattern or read in from another
used to set the (repeated) fill pattern which
is used when the data to write is not coming from a file.
The default buffer fill pattern value is 0xcdcdcdcd.
+.TP
+.B \-F
+write the buffers in a forwards sequential direction.
+.TP
+.B \-B
+write the buffers in a reserve sequential direction.
+.TP
+.B \-R
+write the buffers in the give range in a random order.
+.TP
+.B \-Z seed
+specify the random number seed used for random write
+.TP
+.B \-w
+call
+.BR fdatasync (2)
+once all writes are complete (included in timing results)
+.TP
+.B \-W
+call
+.BR fsync (2)
+once all writes are complete (included in timing results)
+.TP
+.B \-V vectors
+Use the vectored IO write syscall
+.BR pwritev (2)
+with a number of blocksize length iovecs. The number of iovecs is set by the
+.I vectors
+parameter.
.RE
.PD
.TP