]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - io/pwrite.c
2 * Copyright (c) 2003-2005 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 static cmdinfo_t pwrite_cmd
;
32 " writes a range of bytes (in block size increments) from the given offset\n"
35 " 'pwrite 512 20' - writes 20 bytes at 512 bytes into the open file\n"
37 " Writes into a segment of the currently open file, using either a buffer\n"
38 " filled with a set pattern (0xcdcdcdcd) or data read from an input file.\n"
39 " The writes are performed in sequential blocks starting at offset, with the\n"
40 " blocksize tunable using the -b option (default blocksize is 4096 bytes),\n"
41 " unless a different write pattern is requested.\n"
42 " -S -- use an alternate seed number for filling the write buffer\n"
43 " -i -- input file, source of data to write (used when writing forward)\n"
44 " -d -- open the input file for direct IO\n"
45 " -s -- skip a number of bytes at the start of the input file\n"
46 " -w -- call fdatasync(2) at the end (included in timing results)\n"
47 " -W -- call fsync(2) at the end (included in timing results)\n"
48 " -B -- write backwards through the range from offset (backwards N bytes)\n"
49 " -F -- write forwards through the range of bytes from offset (default)\n"
50 " -R -- write at random offsets in the specified range of bytes\n"
51 " -Z N -- zeed the random number generator (used when writing randomly)\n"
52 " (heh, zorry, the -s/-S arguments were already in use in pwrite)\n"
54 " -V N -- use vectored IO with N iovecs of blocksize each (pwritev)\n"
71 /* trim the iovec if necessary */
72 if (count
< buffersize
) {
74 while (len
+ iov
[vecs
].iov_len
< count
) {
75 len
+= iov
[vecs
].iov_len
;
78 oldlen
= iov
[vecs
].iov_len
;
79 iov
[vecs
].iov_len
= count
- len
;
84 bytes
= pwritev(fd
, iov
, vectors
, offset
);
86 /* restore trimmed iov */
88 iov
[vecs
- 1].iov_len
= oldlen
;
93 #define do_pwritev(fd, offset, count, buffer_size) (0)
104 return pwrite(fd
, buffer
, min(count
, buffer_size
), offset
);
106 return do_pwritev(fd
, offset
, count
, buffer_size
);
121 if ((bytes
= (offset
% buffersize
)))
123 offset
= max(0, offset
);
124 if ((bytes
= (count
% buffersize
)))
126 count
= max(buffersize
, count
);
127 range
= count
- buffersize
;
132 off
= ((offset
+ (random() % range
)) / buffersize
) *
136 bytes
= do_pwrite(file
->fd
, off
, buffersize
, buffersize
);
145 if (bytes
< buffersize
)
158 off64_t end
, off
= offset
;
159 ssize_t bytes
= 0, bytes_requested
;
160 long long cnt
= *count
;
163 if ((end
= off
- cnt
) < 0) {
164 cnt
+= end
; /* subtraction, end is negative */
170 /* Do initial unaligned write if needed */
171 if ((bytes_requested
= (off
% buffersize
))) {
172 bytes_requested
= min(cnt
, bytes_requested
);
173 off
-= bytes_requested
;
174 bytes
= do_pwrite(file
->fd
, off
, bytes_requested
, buffersize
);
183 if (bytes
< bytes_requested
)
188 /* Iterate backward through the rest of the range */
190 bytes_requested
= min(cnt
, buffersize
);
191 off
-= bytes_requested
;
192 bytes
= do_pwrite(file
->fd
, off
, cnt
, buffersize
);
201 if (bytes
< bytes_requested
)
218 long long bar
= min(bs
, count
);
223 if (fd
> 0) { /* input file given, read buffer first */
224 if (read_buffer(fd
, skip
+ *total
, bs
, &bar
, 0, 1) < 0)
227 bytes
= do_pwrite(file
->fd
, offset
, count
, bar
);
236 if (bytes
< min(count
, bar
))
252 off64_t offset
, skip
= 0;
253 long long count
, total
, tmp
;
254 unsigned int zeed
= 0, seed
= 0xcdcdcdcd;
255 size_t fsblocksize
, fssectsize
;
256 struct timeval t1
, t2
;
257 char *sp
, *infile
= NULL
;
258 int Cflag
, qflag
, uflag
, dflag
, wflag
, Wflag
;
259 int direction
= IO_FORWARD
;
262 Cflag
= qflag
= uflag
= dflag
= wflag
= Wflag
= 0;
263 init_cvtnum(&fsblocksize
, &fssectsize
);
266 while ((c
= getopt(argc
, argv
, "b:BCdf:Fi:qRs:S:uV:wWZ:")) != EOF
) {
269 tmp
= cvtnum(fsblocksize
, fssectsize
, optarg
);
271 printf(_("non-numeric bsize -- %s\n"), optarg
);
280 direction
= IO_FORWARD
;
283 direction
= IO_BACKWARD
;
286 direction
= IO_RANDOM
;
296 skip
= cvtnum(fsblocksize
, fssectsize
, optarg
);
298 printf(_("non-numeric skip -- %s\n"), optarg
);
303 seed
= strtoul(optarg
, &sp
, 0);
304 if (!sp
|| sp
== optarg
) {
305 printf(_("non-numeric seed -- %s\n"), optarg
);
316 vectors
= strtoul(optarg
, &sp
, 0);
317 if (!sp
|| sp
== optarg
) {
318 printf(_("non-numeric vector count == %s\n"),
330 zeed
= strtoul(optarg
, &sp
, 0);
331 if (!sp
|| sp
== optarg
) {
332 printf(_("non-numeric seed -- %s\n"), optarg
);
337 return command_usage(&pwrite_cmd
);
340 if (((skip
|| dflag
) && !infile
) || (optind
!= argc
- 2))
341 return command_usage(&pwrite_cmd
);
342 if (infile
&& direction
!= IO_FORWARD
)
343 return command_usage(&pwrite_cmd
);
344 offset
= cvtnum(fsblocksize
, fssectsize
, argv
[optind
]);
346 printf(_("non-numeric offset argument -- %s\n"), argv
[optind
]);
350 count
= cvtnum(fsblocksize
, fssectsize
, argv
[optind
]);
352 printf(_("non-numeric length argument -- %s\n"), argv
[optind
]);
356 if (alloc_buffer(bsize
, uflag
, seed
) < 0)
359 c
= IO_READONLY
| (dflag
? IO_DIRECT
: 0);
360 if (infile
&& ((fd
= openfile(infile
, NULL
, c
, 0, NULL
)) < 0))
363 gettimeofday(&t1
, NULL
);
366 if (!zeed
) /* srandom seed */
368 c
= write_random(offset
, count
, zeed
, &total
);
371 c
= write_buffer(offset
, count
, bsize
, fd
, skip
, &total
);
374 c
= write_backward(offset
, &count
, &total
);
388 gettimeofday(&t2
, NULL
);
391 report_io_times("wrote", &t2
, (long long)offset
, count
, total
, c
,
402 pwrite_cmd
.name
= "pwrite";
403 pwrite_cmd
.altname
= "w";
404 pwrite_cmd
.cfunc
= pwrite_f
;
405 pwrite_cmd
.argmin
= 2;
406 pwrite_cmd
.argmax
= -1;
407 pwrite_cmd
.flags
= CMD_NOMAP_OK
| CMD_FOREIGN_OK
;
409 _("[-i infile [-d] [-s skip]] [-b bs] [-S seed] [-wW] [-FBR [-Z N]] [-V N] off len");
411 _("writes a number of bytes at a specified offset");
412 pwrite_cmd
.help
= pwrite_help
;
414 add_command(&pwrite_cmd
);