Example #1
0
ssize_t
fiob_write(void *cookie, const char *buf, size_t len)
#endif
{
	struct fiob *f = (struct fiob *)cookie;

	if (len == 0)
		return 0;

	if (!f->buf)
		return fiob_writef(f, buf, len);

	ssize_t bytes_left = len;
	ssize_t tocopy;

	if (f->bfill < f->bsize) {
		ssize_t available_buf_size = f->bsize - f->bfill;
		tocopy = available_buf_size > bytes_left ?
			bytes_left : available_buf_size;

		memcpy(f->buf + f->bfill, buf, tocopy);
		bytes_left -= tocopy;
		buf += tocopy;
		f->bfill += tocopy;
	}
	while (bytes_left > 0) {
		assert(f->bfill == f->bsize);
		ssize_t res = fiob_writef(f, f->buf, f->bsize);
		if (res < 0)
			return res;
		tocopy = f->bsize > bytes_left ? bytes_left : f->bsize;
		/*
		 * We must memcpy because O_DIRECT requires
		 * an aligned chunk.
		 */
		memcpy(f->buf, buf, tocopy);
		bytes_left -= tocopy;
		buf += tocopy;
		f->bfill = tocopy;
	}
	return len;
}
Example #2
0
static int
fiob_flushb(struct fiob *f)
{
	if (!f->bfill)
		return 0;

	size_t tlen = fiob_ceil(f->bfill);

	if (fiob_writef(f, f->buf, tlen) < 0) {
		return -1;
	}

	off_t size = lseek(f->fd, (off_t)(f->bfill) - tlen, SEEK_CUR);
	if (size == (off_t)-1) {
		return -1;
	}
	int res = ftruncate(f->fd, size);

	f->bfill = 0;
	return res;
}