push_back(std::move(bp));
}
-
+int buffer::list::pread_file(const char *fn, uint64_t off, uint64_t len, std::string *error)
+{
+ int fd = TEMP_FAILURE_RETRY(::open(fn, O_RDONLY|O_CLOEXEC));
+ if (fd < 0) {
+ int err = errno;
+ std::ostringstream oss;
+ oss << "can't open " << fn << ": " << cpp_strerror(err);
+ *error = oss.str();
+ return -err;
+ }
+
+ struct stat st;
+ memset(&st, 0, sizeof(st));
+ if (::fstat(fd, &st) < 0) {
+ int err = errno;
+ std::ostringstream oss;
+ oss << "bufferlist::read_file(" << fn << "): stat error: "
+ << cpp_strerror(err);
+ *error = oss.str();
+ VOID_TEMP_FAILURE_RETRY(::close(fd));
+ return -err;
+ }
+
+ if (off > st.st_size) {
+ std::ostringstream oss;
+ oss << "bufferlist::read_file(" << fn << "): read error: size < offset";
+ VOID_TEMP_FAILURE_RETRY(::close(fd));
+ return -1;
+ }
+
+ if (len > st.st_size - off) {
+ len = st.st_size - off;
+ }
+ lseek(fd, off, SEEK_SET);
+ ssize_t ret = safe_read(fd, (void*)this->c_str(), len);
+ if (ret < 0) {
+ std::ostringstream oss;
+ oss << "bufferlist::read_file(" << fn << "): read error:"
+ << cpp_strerror(ret);
+ *error = oss.str();
+ VOID_TEMP_FAILURE_RETRY(::close(fd));
+ return ret;
+ } else if (ret != len) {
+ // Premature EOF.
+ // Perhaps the file changed between stat() and read()?
+ std::ostringstream oss;
+ oss << "bufferlist::read_file(" << fn << "): warning: got premature EOF.";
+ *error = oss.str();
+ // not actually an error, but weird
+ }
+ VOID_TEMP_FAILURE_RETRY(::close(fd));
+ return 0;
+}
int buffer::list::read_file(const char *fn, std::string *error)
{
void write_stream(std::ostream &out) const;
void hexdump(std::ostream &out, bool trailing_newline = true) const;
+ int pread_file(const char *fn, uint64_t off, uint64_t len, std::string *error);
int read_file(const char *fn, std::string *error);
ssize_t read_fd(int fd, size_t len);
int write_file(const char *fn, int mode=0644);
ldout(cct, 20) << "offset:" << object_off
<< ", length:" << object_len << dendl;
- bufferlist temp_bl;
std::string error_str;
- // TODO : current implements will drop sharely performance.
- int ret = temp_bl.read_file(m_name.c_str(), &error_str);
+ int ret = read_buf->pread_file(m_name.c_str(), object_off, object_len, &error_str);
if (ret < 0) {
lderr(cct)<<"read file fail:" << error_str << dendl;
return -1;
}
- if(object_off >= temp_bl.length()) {
- return 0;
- }
-
- if((temp_bl.length() - object_off) < object_len) {
- object_len = temp_bl.length() - object_off;
- }
-
- read_buf->substr_of(temp_bl, object_off, object_len);
-
return read_buf->length();
}