diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 650b3fbb331ee..66a43913cc4b4 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -1489,6 +1489,12 @@ int buffer::list::read_file(const char *fn, std::string *error) ssize_t buffer::list::read_fd(int fd, size_t len) { + // try zero copy first + if (read_fd_zero_copy(fd, len) == 0) { + // TODO fix callers to not require correct read size, which is not + // available for raw_pipe until we actually inspect the data + return 0; + } int s = ROUND_UP_TO(len, CEPH_PAGE_SIZE); bufferptr bp = buffer::create_page_aligned(s); ssize_t ret = safe_read(fd, (void*)bp.c_str(), len); @@ -1507,6 +1513,8 @@ int buffer::list::read_fd_zero_copy(int fd, size_t len) append(bp); } catch (buffer::error_code e) { return e.code; + } catch (buffer::malformed_input) { + return -EIO; } return 0; #else diff --git a/src/test/bufferlist.cc b/src/test/bufferlist.cc index 4b3ae61672671..822b5b4c402a4 100644 --- a/src/test/bufferlist.cc +++ b/src/test/bufferlist.cc @@ -1763,9 +1763,14 @@ TEST(BufferList, read_fd) { bufferlist bl; EXPECT_EQ(-EBADF, bl.read_fd(fd, len)); fd = ::open("testfile", O_RDONLY); +#ifdef CEPH_HAVE_SPLICE + EXPECT_EQ(0, bl.read_fd(fd, len)); + EXPECT_EQ(0u, bl.buffers().front().unused_tail_length()); +#else EXPECT_EQ(len, (unsigned)bl.read_fd(fd, len)); - EXPECT_EQ(len, bl.length()); EXPECT_EQ(CEPH_PAGE_SIZE - len, bl.buffers().front().unused_tail_length()); +#endif + EXPECT_EQ(len, bl.length()); ::close(fd); ::unlink("testfile"); }