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 main(int argc, char **argv) { u64 total_size = sizeof(struct header_s); char *basename = pparm_common_name("index"); char *iname = NULL; int fd = 0; u64 offs = sizeof(struct header_s); uint i; struct header_s header; dub_init(); PPARM_INT_D(iblock, IBLOCK); PPARM_INT_D(segment_size, SEGMENT_SIZE); asprintf(&iname, "%s.%u", basename, iblock); fill_parameters(&header); for (i = 0; i < DEX_NOF_SECT; i++){ header.toc_offs[i] = total_size; total_size += append_sect(0, 0, i, 1); } for (i = 0; i < DEX_NOF_SECT; i++){ header.data_offs[i] = total_size; total_size += append_sect(0, 0, i, 0); } if ((fd = open(iname, O_CREAT | O_TRUNC | O_RDWR | O_LARGEFILE, S_IREAD | S_IWRITE)) == -1) dub_sysdie("Couldn't open file %s", iname); if (fio_truncate(fd, total_size)) dub_sysdie("Couldn't truncate index to %llu bytes", total_size); write(fd, &header, sizeof(struct header_s)); for (i = 0; i < DEX_NOF_SECT; i++) offs += append_sect(fd, offs, i, 1); for (i = 0; i < DEX_NOF_SECT; i++) offs += append_sect(fd, offs, i, 0); close(fd); print_structure(&header); printf(" In total %llu bytes.\n\n", total_size); return 0; }
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; }
void create_ixicon(const char *fname, const Pvoid_t ixicon) { void *mm_idx = NULL; void *mm_body = NULL; void *mm_start = NULL; Word_t *xid = NULL; u32 ixeme_cnt = 0; u64 ixicon_sze = ixicon_mem(ixicon, &ixeme_cnt); uint ix_pos = 0; static char ix[MAX_TOK_LEN]; int fd; if ((fd = open(fname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE)) == -1) dub_sysdie("Couldn't open ixicon %s", fname); ixicon_sze += (ixeme_cnt + 1) * 4; /* space needed by the index */ if (ixicon_sze > INT32_MAX) dub_die("Ixicon would take %llu but we support only " "32bit offsets.", ixicon_sze); if (fio_truncate(fd, PAGE_ALIGN(ixicon_sze))) dub_sysdie("Couldn't truncate ixicon to %llu bytes.", ixicon_sze); mm_idx = mm_start = mmap(0, PAGE_ALIGN(ixicon_sze), PROT_WRITE, MAP_SHARED, fd, 0); if (mm_start == MAP_FAILED) dub_sysdie("Couldn't mmap ixicon %s", fname); mm_body = mm_start + (ixeme_cnt + 1) * 4 + 4; /* first write the number of ixemes */ memcpy(mm_idx, &ixeme_cnt, 4); mm_idx += 4; strcpy(ix, ""); JSLF(xid, ixicon, ix); while(xid != NULL){ uint ix_len = strlen(ix) + 1; /* ixeme */ memcpy(mm_body, ix, ix_len); mm_body += ix_len; /* ixeme id */ memcpy(mm_body, (u32*)xid, 4); mm_body += 4; /* write the index entry */ memcpy(mm_idx, &ix_pos, 4); mm_idx += 4; ix_pos += ix_len + 4; JSLN(xid, ixicon, ix); } memcpy(mm_idx, &ix_pos, 4); if (munmap(mm_start, ixicon_sze)) dub_sysdie("Couldn't munmap ixicon. Disk full?"); close(fd); dub_dbg("Ixicon created"); }