| /* |
| * Copyright (c) 2013 Linux Box Corporation. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR |
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef XDR_IOQ_H |
| #define XDR_IOQ_H |
| |
| #include <stdint.h> |
| #include <stdbool.h> |
| #include <misc/opr.h> |
| #include <misc/queue.h> |
| #include <rpc/pool_queue.h> |
| #include <rpc/xdr.h> |
| |
| struct xdr_ioq_uv |
| { |
| struct poolq_entry uvq; |
| |
| /* spliced buffers, if any */ |
| struct xdr_uio u; |
| |
| /* Each xdr_ioq_uv can have a different kind of buffer or data source, |
| * as indicated by the uio_flags, needing different release techniques. |
| * Note: overloads uio_release with uio_p1 for pool. |
| */ |
| struct xdr_vio v; /* immediately follows u (uio_vio[0]) */ |
| }; |
| |
| #define IOQ_(p) (opr_containerof((p), struct xdr_ioq_uv, uvq)) |
| #define IOQU(p) (opr_containerof((p), struct xdr_ioq_uv, u)) |
| #define IOQV(p) (opr_containerof((p), struct xdr_ioq_uv, v)) |
| |
| #define ioquv_length(uv) \ |
| ((uintptr_t)((uv)->v.vio_tail) - (uintptr_t)((uv)->v.vio_head)) |
| #define ioquv_size(uv) \ |
| ((uintptr_t)((uv)->v.vio_wrap) - (uintptr_t)((uv)->v.vio_base)) |
| |
| struct xdr_ioq; |
| |
| struct xdr_ioq_uv_head { |
| struct poolq_head uvqh; |
| |
| /* Each xdr_ioq_uv can have a different kind of buffer or data source, |
| * as indicated by the uio_flags, needing different create techniques. |
| */ |
| struct poolq_entry *(*uvq_fetch)(struct xdr_ioq *xioq, |
| struct poolq_head *ioqh, |
| char *comment, u_int count, |
| u_int ioq_flags); |
| |
| u_int plength; /* sub-total of previous lengths, not including |
| * any length in this xdr_ioq_uv */ |
| u_int pcount; /* fill index (0..m) in the current stream */ |
| u_int min_bsize; /* multiple of pagesize */ |
| u_int max_bsize; /* multiple of min_bsize */ |
| }; |
| |
| struct xdr_ioq { |
| XDR xdrs[1]; |
| struct poolq_entry ioq_s; /* segment of stream */ |
| pthread_cond_t ioq_cond; |
| |
| struct poolq_head *ioq_pool; |
| void *ioq_p2; |
| void *ioq_u1; |
| void *ioq_u2; |
| struct xdr_ioq_uv_head ioq_uv; /* header/vectors */ |
| |
| uint64_t id; |
| }; |
| |
| #define _IOQ(p) (opr_containerof((p), struct xdr_ioq, ioq_s)) |
| #define XIOQ(p) (opr_containerof((p), struct xdr_ioq, xdrs)) |
| |
| /* avoid conflicts with UIO_FLAG */ |
| #define IOQ_FLAG_NONE 0x0000 |
| #define IOQ_FLAG_BALLOC 0x4000 |
| #define IOQ_FLAG_XTENDQ 0x8000 |
| |
| extern struct xdr_ioq_uv *xdr_ioq_uv_create(u_int size, u_int uio_flags); |
| extern struct poolq_entry *xdr_ioq_uv_fetch(struct xdr_ioq *xioq, |
| struct poolq_head *ioqh, |
| char *comment, |
| u_int count, |
| u_int ioq_flags); |
| extern struct poolq_entry *xdr_ioq_uv_fetch_nothing(struct xdr_ioq *xioq, |
| struct poolq_head *ioqh, |
| char *comment, |
| u_int count, |
| u_int ioq_flags); |
| extern void xdr_ioq_uv_release(struct xdr_ioq_uv *uv); |
| |
| extern XDR *xdr_ioq_create(u_int min_bsize, u_int max_bsize, u_int uio_flags); |
| extern void xdr_ioq_release(struct poolq_head *ioqh); |
| extern void xdr_ioq_reset(struct xdr_ioq *xioq, u_int wh_pos); |
| extern void xdr_ioq_setup(struct xdr_ioq *xioq); |
| |
| extern void xdr_ioq_destroy(struct xdr_ioq *xioq, size_t qsize); |
| extern void xdr_ioq_destroy_pool(struct poolq_head *ioqh); |
| |
| extern const struct xdr_ops xdr_ioq_ops; |
| |
| #endif /* XDR_IOQ_H */ |