Beispiel #1
0
static void lo_read(fuse_req_t req, fuse_ino_t ino, size_t size,
			  off_t offset, struct fuse_file_info *fi)
{
	struct fuse_bufvec buf = FUSE_BUFVEC_INIT(size);

	(void) ino;

	buf.buf[0].flags = FUSE_BUF_IS_FD | FUSE_BUF_FD_SEEK;
	buf.buf[0].fd = fi->fh;
	buf.buf[0].pos = offset;

	fuse_reply_data(req, &buf, FUSE_BUF_SPLICE_MOVE);
}
Beispiel #2
0
static bool
read_bulk_cb(struct dfuse_request *request)
{
	struct dfuse_rb *rb = container_of(request, struct dfuse_rb, rb_req);
	struct dfuse_readx_out *out = request->out;
	int rc = 0;
	size_t bytes_read = 0;
	void *buff = NULL;

	if (out->err) {
		DFUSE_TRA_ERROR(rb, "Error from target %d", out->err);
		rb->failure = true;
		D_GOTO(out, request->rc = EIO);
	}

	DFUSE_REQUEST_RESOLVE(request, out);
	if (request->rc)
		D_GOTO(out, 0);

	if (out->iov_len > 0) {
		if (out->data.iov_len != out->iov_len)
			D_GOTO(out, request->rc = EIO);
		buff = out->data.iov_buf;
		bytes_read = out->data.iov_len;
	} else if (out->bulk_len > 0) {
		bytes_read = out->bulk_len;
	}

out:
	if (request->rc) {
		DFUSE_REPLY_ERR(request, request->rc);
	} else {

		/* It's not clear without benchmarking which approach is better
		 * here, fuse_reply_buf() is a small wrapper around writev()
		 * which is a much shorter code-path however fuse_reply_data()
		 * attempts to use splice which may well be faster.
		 *
		 * For now it's easy to pick between them, and both of them are
		 * passing valgrind tests.
		 */
		if (request->fsh->flags & DFUSE_FUSE_READ_BUF) {
			rc = fuse_reply_buf(request->req, buff, bytes_read);
			if (rc != 0)
				DFUSE_TRA_ERROR(rb,
						"fuse_reply_buf returned %d:%s",
						rc, strerror(-rc));

		} else {
			rb->fbuf.buf[0].size = bytes_read;
			rb->fbuf.buf[0].mem = buff;
			rc = fuse_reply_data(request->req, &rb->fbuf, 0);
			if (rc != 0)
				DFUSE_TRA_ERROR(rb,
						"fuse_reply_data returned %d:%s",
						rc, strerror(-rc));
		}
	}
	dfuse_da_release(rb->pt, rb);
	return false;
}