int fio_batch_write(struct fio_batch *batch, int fd) { ssize_t bytes_written = fio_writev(fd, batch->iov, batch->iovcnt); if (bytes_written <= 0) return 0; if (bytes_written == batch->bytes) return batch->rows; /* returns the number of written rows */ say_warn("fio_batch_write, [%s]: partial write," " wrote %jd out of %jd bytes", fio_filename(fd), (intmax_t) bytes_written, (intmax_t) batch->bytes); /* Iterate over end of row flags */ struct bit_iterator bit_it; bit_iterator_init(&bit_it, batch->rowflag, batch->max_iov / CHAR_BIT + 1, 1); size_t row_last_iov = bit_iterator_next(&bit_it); int good_rows = 0; /* the number of fully written rows */ ssize_t good_bytes = 0; /* the number of bytes in fully written rows */ ssize_t row_bytes = 0; /* the number of bytes in the current row */ struct iovec *iov = batch->iov; while (iov < batch->iov + batch->iovcnt) { if (good_bytes + row_bytes + iov->iov_len > bytes_written) break; row_bytes += iov->iov_len; if ((iov - batch->iov) == row_last_iov) { /* the end of current row */ good_bytes += row_bytes; row_bytes = 0; good_rows++; row_last_iov = bit_iterator_next(&bit_it); } iov++; } /* * Unwind file position back to ensure we do not leave * partially written rows. */ off_t good_offset = fio_lseek(fd, good_bytes - bytes_written, SEEK_CUR); /* * The caller may choose to close the file right after * a partial write. Don't take chances and make sure that * there is no garbage at the end of file if it happens. */ if (good_offset != -1) (void) fio_truncate(fd, good_offset); /* * writev() doesn't set errno in case of a partial write. * If nothing else from the above failed, set errno to * EAGAIN. */ if (! errno) errno = EAGAIN; return good_rows; /* returns the number of written rows */ }
int fio_batch_write(struct fio_batch *batch, int fd) { ssize_t bytes_written = fio_writev(fd, batch->iov, batch->rows); if (bytes_written <= 0) return 0; if (bytes_written == batch->bytes) return batch->rows; say_warn("fio_batch_write, [%s]: partial write," " wrote %jd out of %jd bytes", fio_filename(fd), (intmax_t) bytes_written, (intmax_t) batch->bytes); ssize_t good_bytes = 0; struct iovec *iov = batch->iov; while (iov < batch->iov + batch->rows) { if (good_bytes + iov->iov_len > bytes_written) break; good_bytes += iov->iov_len; iov++; } /* * Unwind file position back to ensure we do not leave * partially written rows. */ off_t good_offset = fio_lseek(fd, good_bytes - bytes_written, SEEK_CUR); /* * The caller may choose to close the file right after * a partial write. Don't take chances and make sure that * there is no garbage at the end of file if it happens. */ if (good_offset != -1) (void) fio_truncate(fd, good_offset); /* * writev() doesn't set errno in case of a partial write. * If nothing else from the above failed, set errno to * EAGAIN. */ if (! errno) errno = EAGAIN; return iov - batch->iov; }