buffer: abstract raw data related methods

Create a virtual function that returns the raw data instead of
accessing it directly, so raw buffers backed by pipes can be used as
buffer::ptrs. Make raw::is_page_aligned() virtual so it will not need
to look at the raw data for a pipe-based buffer.

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
buffer: remove unused raw::length() method

This was accidentally introduced in
0c23a5624a80903fba7e635e8c44f38a79caf223

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
safe_io: add functions for handling splice

Like the other functions, these don't handle non-blocking I/O.

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
buffer: add an exception with an error code

This allows e.g. raw buffer constructors to provide more specific
information about what failed, as well as a useful error string
automatically.

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
buffer: create raw pipe-based buffer

This uses a pipe to reference kernel memory so we can use splice(2) to
avoid extra data copies. Take an fd in the factory to create it, since
that's the only way to use it efficiently, which is its whole purpose.

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
buffer: add methods to read and write using zero copy

Create explicit methods for testing. Make buffer::list::write_fd() use
zero-copy if all the buffers support it.  Don't automatically handle
reads yet, since we need better detection of read length first.

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
buffer: attempt to size raw_pipe buffers

Make sure the requested length is below the maximum pipe size for now,
since we're only using one pipe and splicing once into and out of
it. The default max is 1MB on recent kernels, so this isn't such a
terrible limitation.

To get around this we could use multiple pipes, or keep both source and
destination fds open at the same time and call splice many times. This
is more usual usage for splice, but would require a lot more work to
restructure the filestore and messenger to handle it.

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
buffer: try to do zero copy in read_fd

Leave the explicit read_fd_zero_copy around as well for testing.

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
buffer: enable tracking of calls to c_str()

Track buffer::ptr::c_str() to catch internal calls that use it, like
buffer::ptr::cmp(). buffer::list::c_str() will be captured by this as
well, since it will do a final buffer::ptr::c_str() and possibly
several more if it needs to rebuild into a single raw buffer.

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
buffer: turn off zero-copy reads for now

Some users will need to be changed to handle getting the correct
length from bufferlist::read_fd.

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
Merge branch 'wip-zero-copy-bufferlist-last'

Reviewed-by: Samuel Just <sam.just@inktank.com>