IOBUF_FL_EOI = 0x00000010, /* A EOI was encountered on producer side */
};
+/* Flags used */
+enum nego_ff_flags {
+ NEGO_FF_FL_NONE = 0x00000000, /* For initialization purposes */
+ NEGO_FF_FL_MAY_SPLICE = 0x00000001, /* Consumer may choose to use kernel splicing if it supports it */
+};
+
struct iobuf {
struct pipe *pipe; /* non-NULL only when data present */
struct buffer *buf;
}
-static inline size_t se_nego_ff(struct sedesc *se, struct buffer *input, size_t count, unsigned int may_splice)
+static inline size_t se_nego_ff(struct sedesc *se, struct buffer *input, size_t count, unsigned int flags)
{
size_t ret = 0;
goto end;
}
- ret = mux->nego_fastfwd(se->sc, input, count, may_splice);
+ ret = mux->nego_fastfwd(se->sc, input, count, flags);
if (se->iobuf.flags & IOBUF_FL_FF_BLOCKED) {
sc_ep_report_blocked_send(se->sc, 0);
struct appctx *appctx = __sc_appctx(sc);
struct xref *peer;
struct sedesc *sdo = NULL;
- unsigned int len;
+ unsigned int len, nego_flags = NEGO_FF_FL_NONE;
int ret = 0;
TRACE_ENTER(APPLET_EV_RECV, appctx);
if (appctx->to_forward && count > appctx->to_forward)
count = appctx->to_forward;
- len = se_nego_ff(sdo, &BUF_NULL, count, 0);
+ len = se_nego_ff(sdo, &BUF_NULL, count, nego_flags);
if (sdo->iobuf.flags & IOBUF_FL_NO_FF) {
sc_ep_clr(sc, SE_FL_MAY_FASTFWD);
TRACE_DEVEL("Fast-forwarding not supported by opposite endpoint, disable it", APPLET_EV_RECV, appctx);
return sdo;
}
-static size_t h1_nego_ff(struct stconn *sc, struct buffer *input, size_t count, unsigned int may_splice)
+static size_t h1_nego_ff(struct stconn *sc, struct buffer *input, size_t count, unsigned int flags)
{
struct h1s *h1s = __sc_mux_strm(sc);
struct h1c *h1c = h1s->h1c;
* and then data in pipe, or the opposite. For now, it is not
* supported to mix data.
*/
- if (!b_data(input) && !b_data(&h1c->obuf) && may_splice) {
+ if (!b_data(input) && !b_data(&h1c->obuf) && (flags & NEGO_FF_FL_MAY_SPLICE)) {
#if defined(USE_LINUX_SPLICE)
if (h1c->conn->xprt->snd_pipe && (h1s->sd->iobuf.pipe || (pipes_used < global.maxpipes && (h1s->sd->iobuf.pipe = get_pipe())))) {
h1s->sd->iobuf.offset = 0;
struct h1m *h1m = (!(h1c->flags & H1C_F_IS_BACK) ? &h1s->req : &h1s->res);
struct sedesc *sdo = NULL;
size_t total = 0, try = 0;
+ unsigned int nego_flags = NEGO_FF_FL_NONE;
int ret = 0;
TRACE_ENTER(H1_EV_STRM_RECV, h1c->conn, h1s, 0, (size_t[]){count});
if (h1m->state == H1_MSG_DATA && (h1m->flags & (H1_MF_CHNK|H1_MF_CLEN)) && count > h1m->curr_len)
count = h1m->curr_len;
- try = se_nego_ff(sdo, &h1c->ibuf, count, h1c->conn->xprt->rcv_pipe && !!(flags & CO_RFL_MAY_SPLICE) && !(sdo->iobuf.flags & IOBUF_FL_NO_SPLICING));
+ if (h1c->conn->xprt->rcv_pipe && !!(flags & CO_RFL_MAY_SPLICE) && !(sdo->iobuf.flags & IOBUF_FL_NO_SPLICING))
+ nego_flags |= NEGO_FF_FL_MAY_SPLICE;
+
+ try = se_nego_ff(sdo, &h1c->ibuf, count, nego_flags);
if (b_room(&h1c->ibuf) && (h1c->flags & H1C_F_IN_FULL)) {
h1c->flags &= ~H1C_F_IN_FULL;
TRACE_STATE("h1c ibuf not full anymore", H1_EV_STRM_RECV|H1_EV_H1C_BLK);
return total;
}
-static size_t h2_nego_ff(struct stconn *sc, struct buffer *input, size_t count, unsigned int may_splice)
+static size_t h2_nego_ff(struct stconn *sc, struct buffer *input, size_t count, unsigned int flags)
{
struct h2s *h2s = __sc_mux_strm(sc);
struct h2c *h2c = h2s->h2c;
return sdo;
}
-static size_t mux_pt_nego_ff(struct stconn *sc, struct buffer *input, size_t count, unsigned int may_splice)
+static size_t mux_pt_nego_ff(struct stconn *sc, struct buffer *input, size_t count, unsigned int flags)
{
struct connection *conn = __sc_conn(sc);
struct mux_pt_ctx *ctx = conn->ctx;
* and then data in pipe, or the opposite. For now, it is not
* supported to mix data.
*/
- if (!b_data(input) && may_splice) {
+ if (!b_data(input) && (flags & NEGO_FF_FL_MAY_SPLICE)) {
if (conn->xprt->snd_pipe && (ctx->sd->iobuf.pipe || (pipes_used < global.maxpipes && (ctx->sd->iobuf.pipe = get_pipe())))) {
ctx->sd->iobuf.offset = 0;
ctx->sd->iobuf.data = 0;
struct mux_pt_ctx *ctx = conn->ctx;
struct sedesc *sdo = NULL;
size_t total = 0, try = 0;
+ unsigned int nego_flags = NEGO_FF_FL_NONE;
int ret = 0;
TRACE_ENTER(PT_EV_RX_DATA, conn, sc, 0, (size_t[]){count});
goto out;
}
- try = se_nego_ff(sdo, &BUF_NULL, count, conn->xprt->rcv_pipe && !!(flags & CO_RFL_MAY_SPLICE) && !(sdo->iobuf.flags & IOBUF_FL_NO_SPLICING));
+ if (conn->xprt->rcv_pipe && !!(flags & CO_RFL_MAY_SPLICE) && !(sdo->iobuf.flags & IOBUF_FL_NO_SPLICING))
+ nego_flags |= NEGO_FF_FL_MAY_SPLICE;
+
+ try = se_nego_ff(sdo, &BUF_NULL, count, nego_flags);
if (sdo->iobuf.flags & IOBUF_FL_NO_FF) {
/* Fast forwarding is not supported by the consumer */
se_fl_clr(ctx->sd, SE_FL_MAY_FASTFWD);
static size_t qmux_strm_nego_ff(struct stconn *sc, struct buffer *input,
- size_t count, unsigned int may_splice)
+ size_t count, unsigned int flags)
{
struct qcs *qcs = __sc_mux_strm(sc);
size_t ret = 0;