Skip to content

Commit 1692959

Browse files
committed
common/buffer: adding pread_file method
pread_file allows to read length of contents at a given offset using pread_file instead of read_file to reduce extra reads in ObjectCacheFile Signed-off-by: Yuan Zhou <yuan.zhou@intel.com>
1 parent 2a931cd commit 1692959

File tree

3 files changed

+55
-14
lines changed

3 files changed

+55
-14
lines changed

src/common/buffer.cc

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1781,7 +1781,59 @@ void buffer::list::decode_base64(buffer::list& e)
17811781
push_back(std::move(bp));
17821782
}
17831783

1784-
1784+
int buffer::list::pread_file(const char *fn, uint64_t off, uint64_t len, std::string *error)
1785+
{
1786+
int fd = TEMP_FAILURE_RETRY(::open(fn, O_RDONLY|O_CLOEXEC));
1787+
if (fd < 0) {
1788+
int err = errno;
1789+
std::ostringstream oss;
1790+
oss << "can't open " << fn << ": " << cpp_strerror(err);
1791+
*error = oss.str();
1792+
return -err;
1793+
}
1794+
1795+
struct stat st;
1796+
memset(&st, 0, sizeof(st));
1797+
if (::fstat(fd, &st) < 0) {
1798+
int err = errno;
1799+
std::ostringstream oss;
1800+
oss << "bufferlist::read_file(" << fn << "): stat error: "
1801+
<< cpp_strerror(err);
1802+
*error = oss.str();
1803+
VOID_TEMP_FAILURE_RETRY(::close(fd));
1804+
return -err;
1805+
}
1806+
1807+
if (off > st.st_size) {
1808+
std::ostringstream oss;
1809+
oss << "bufferlist::read_file(" << fn << "): read error: size < offset";
1810+
VOID_TEMP_FAILURE_RETRY(::close(fd));
1811+
return -1;
1812+
}
1813+
1814+
if (len > st.st_size - off) {
1815+
len = st.st_size - off;
1816+
}
1817+
lseek(fd, off, SEEK_SET);
1818+
ssize_t ret = safe_read(fd, (void*)this->c_str(), len);
1819+
if (ret < 0) {
1820+
std::ostringstream oss;
1821+
oss << "bufferlist::read_file(" << fn << "): read error:"
1822+
<< cpp_strerror(ret);
1823+
*error = oss.str();
1824+
VOID_TEMP_FAILURE_RETRY(::close(fd));
1825+
return ret;
1826+
} else if (ret != len) {
1827+
// Premature EOF.
1828+
// Perhaps the file changed between stat() and read()?
1829+
std::ostringstream oss;
1830+
oss << "bufferlist::read_file(" << fn << "): warning: got premature EOF.";
1831+
*error = oss.str();
1832+
// not actually an error, but weird
1833+
}
1834+
VOID_TEMP_FAILURE_RETRY(::close(fd));
1835+
return 0;
1836+
}
17851837

17861838
int buffer::list::read_file(const char *fn, std::string *error)
17871839
{

src/include/buffer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,7 @@ inline namespace v14_2_0 {
12161216

12171217
void write_stream(std::ostream &out) const;
12181218
void hexdump(std::ostream &out, bool trailing_newline = true) const;
1219+
int pread_file(const char *fn, uint64_t off, uint64_t len, std::string *error);
12191220
int read_file(const char *fn, std::string *error);
12201221
ssize_t read_fd(int fd, size_t len);
12211222
int write_file(const char *fn, int mode=0644);

src/tools/immutable_object_cache/ObjectCacheFile.cc

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,26 +56,14 @@ int ObjectCacheFile::read_object_from_file(ceph::bufferlist* read_buf, uint64_t
5656
ldout(cct, 20) << "offset:" << object_off
5757
<< ", length:" << object_len << dendl;
5858

59-
bufferlist temp_bl;
6059
std::string error_str;
6160

62-
// TODO : current implements will drop sharely performance.
63-
int ret = temp_bl.read_file(m_name.c_str(), &error_str);
61+
int ret = read_buf->pread_file(m_name.c_str(), object_off, object_len, &error_str);
6462
if (ret < 0) {
6563
lderr(cct)<<"read file fail:" << error_str << dendl;
6664
return -1;
6765
}
6866

69-
if(object_off >= temp_bl.length()) {
70-
return 0;
71-
}
72-
73-
if((temp_bl.length() - object_off) < object_len) {
74-
object_len = temp_bl.length() - object_off;
75-
}
76-
77-
read_buf->substr_of(temp_bl, object_off, object_len);
78-
7967
return read_buf->length();
8068
}
8169

0 commit comments

Comments
 (0)