| 101 | |
| 102 | private: |
| 103 | ssize_t zero_copy_read(bufferptr &data) { |
| 104 | auto err = _conn.get_errno(); |
| 105 | if (err <= 0) |
| 106 | return err; |
| 107 | |
| 108 | if (!_buf) { |
| 109 | _buf = std::move(_conn.read()); |
| 110 | if (!_buf) |
| 111 | return -EAGAIN; |
| 112 | } |
| 113 | |
| 114 | fragment &f = _buf->frag(_cur_frag); |
| 115 | Packet p = _buf->share(_cur_off, f.size); |
| 116 | auto del = std::bind( |
| 117 | [](Packet &p) {}, std::move(p)); |
| 118 | data = buffer::claim_buffer( |
| 119 | f.size, f.base, make_deleter(std::move(del))); |
| 120 | if (++_cur_frag == _buf->nr_frags()) { |
| 121 | _cur_frag = 0; |
| 122 | _cur_off = 0; |
| 123 | _buf.reset(); |
| 124 | } else { |
| 125 | _cur_off += f.size; |
| 126 | } |
| 127 | ceph_assert(data.length()); |
| 128 | return data.length(); |
| 129 | } |
| 130 | virtual ssize_t send(bufferlist &bl, bool more) override { |
| 131 | auto err = _conn.get_errno(); |
| 132 | if (err < 0) |