1/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2/* 3 * Copyright 2014-2020 Couchbase, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18#include <libcouchbase/couchbase.h> 19#include <libcouchbase/pktfwd.h> 20#include "mc/mcreq.h" 21#include "mc/forward.h" 22#include "internal.h" 23#include "rdb/rope.h" 24 25LIBCOUCHBASE_API 26lcb_STATUS lcb_pktfwd3(lcb_INSTANCE *instance, const void *cookie, const lcb_CMDPKTFWD *cmd) 27{ 28 int fwdopts = 0; 29 mc_PIPELINE *pl; 30 mc_PACKET *packet; 31 nb_IOV *iov, iov_s; 32 unsigned niov; 33 mc_IOVINFO ioi = {{0}}; 34 lcb_STATUS err; 35 36 if (cmd->nomap) { 37 fwdopts |= MC_FWD_OPT_NOMAP; 38 if (cmd->server_index >= LCBT_NSERVERS(instance)) { 39 return LCB_ERR_NO_MATCHING_SERVER; 40 } else { 41 pl = (mc_PIPELINE *)LCBT_GET_SERVER(instance, cmd->server_index); 42 } 43 } 44 45 if (cmd->vb.vtype != LCB_KV_IOV) { 46 iov_s.iov_base = (void *)cmd->vb.u_buf.contig.bytes; 47 iov_s.iov_len = cmd->vb.u_buf.contig.nbytes; 48 iov = &iov_s; 49 niov = 1; 50 51 if (cmd->vb.vtype == LCB_KV_COPY) { 52 fwdopts |= MC_FWD_OPT_COPY; 53 } 54 } else { 55 iov = (nb_IOV *)cmd->vb.u_buf.multi.iov; 56 niov = cmd->vb.u_buf.multi.niov; 57 ioi.total = cmd->vb.u_buf.multi.total_length; 58 } 59 mc_iovinfo_init(&ioi, iov, niov); 60 61 err = mc_forward_packet(&instance->cmdq, &ioi, &packet, &pl, fwdopts); 62 if (err != LCB_SUCCESS) { 63 return err; 64 } 65 66 /* set the cookie */ 67 packet->u_rdata.reqdata.cookie = cookie; 68 packet->u_rdata.reqdata.start = gethrtime(); 69 packet->u_rdata.reqdata.deadline = 70 packet->u_rdata.reqdata.start + LCB_US2NS(LCBT_SETTING(instance, operation_timeout)); 71 return err; 72} 73 74LIBCOUCHBASE_API 75void lcb_backbuf_ref(lcb_BACKBUF buf) 76{ 77 rdb_seg_ref(buf); 78} 79 80LIBCOUCHBASE_API 81void lcb_backbuf_unref(lcb_BACKBUF buf) 82{ 83 rdb_seg_unref(buf); 84} 85