+ * Write a chunk to disk, handling errors, interrupted writes, etc.
+ *
+ * If there is an IO error hit during the write, it is possible that
+ * this will just show up as a short write, and a subsequent write
+ * will return the actual error. We want to continue in the face of
+ * minor media errors so that we can validate the whole device if
+ * possible, but if there are many errors we don't want to loop forever.
+ *
+ * The error count will be returned upon exit to ensure that the
+ * media errors are detected even if nobody is looking at the output.
+ *
+ * Returns 0 on success, or -ve errno on failure.
+ */
+int write_retry(int fd, const char *chunk_buf, size_t nrequested,
+ unsigned long long offset, const char *file)
+{
+ long nwritten;
+
+retry:
+ nwritten = write(fd, chunk_buf, nrequested);
+ if (nwritten < 0) {
+ if (errno != ENOSPC) {
+ fprintf(stderr, "\n%s: write %s@%llu+%zi failed: %s\n",
+ progname, file, offset, nrequested,
+ strerror(errno));
+ if (error_count++ < 100)
+ return 0;
+ }
+ return -errno;
+ }
+ if (nwritten < nrequested) {
+ fprintf(stderr, "\n%s: write %s@%llu+%zi short: %ld written\n",
+ progname, file, offset, nrequested, nwritten);
+ offset += nwritten;
+ chunk_buf += nwritten;
+ nrequested -= nwritten;
+ goto retry;
+ }
+
+ return 0;
+}
+
+/*
+ * write_chunks: write the chunk_buf on the device. The number of write