Thanks to Kefu Chai <kchai@redhat.com> for assistance.
Signed-off-by: Adam C. Emerson <aemerson@redhat.com>
}
break;
default:
- throw ceph::buffer::error();
+ throw ceph::buffer::malformed_input();
}
}
#include "armor.h"
#include "common/environment.h"
#include "common/errno.h"
+#include "common/error_code.h"
#include "common/safe_io.h"
#include "common/strtol.h"
#include "common/likely.h"
#include "common/valgrind.h"
#include "common/deleter.h"
#include "common/RWLock.h"
+#include "common/error_code.h"
#include "include/spinlock.h"
#include "include/scope_guard.h"
return buffer_missed_crc;
}
- const char * buffer::error::what() const throw () {
- return "buffer::exception";
- }
- const char * buffer::bad_alloc::what() const throw () {
- return "buffer::bad_alloc";
- }
- const char * buffer::end_of_buffer::what() const throw () {
- return "buffer::end_of_buffer";
- }
- const char * buffer::malformed_input::what() const throw () {
- return buf;
- }
- buffer::error_code::error_code(int error) :
- buffer::malformed_input(cpp_strerror(error).c_str()), code(error) {}
-
/*
* raw_combined is always placed within a single allocation along
* with the data buffer. the data goes at the beginning, and
memset(c_str()+o, 0, l);
}
+ template<bool B>
+ buffer::ptr::iterator_impl<B>& buffer::ptr::iterator_impl<B>::operator +=(size_t len) {
+ pos += len;
+ if (pos > end_ptr)
+ throw end_of_buffer();
+ return *this;
+ }
+
+ template buffer::ptr::iterator_impl<false>&
+ buffer::ptr::iterator_impl<false>::operator +=(size_t len);
+ template buffer::ptr::iterator_impl<true>&
+ buffer::ptr::iterator_impl<true>::operator +=(size_t len);
+
// -- buffer::list::iterator --
/*
buffer::list::iterator operator=(const buffer::list::iterator& other)
return out;
}
-std::ostream& buffer::operator<<(std::ostream& out, const buffer::error& e)
-{
- return out << e.what();
-}
-
MEMPOOL_DEFINE_OBJECT_FACTORY(buffer::raw_malloc, buffer_raw_malloc,
buffer_meta);
MEMPOOL_DEFINE_OBJECT_FACTORY(buffer::raw_posix_aligned,
MEMPOOL_DEFINE_OBJECT_FACTORY(buffer::raw_static, buffer_raw_static,
buffer_meta);
+
+namespace ceph::buffer {
+inline namespace v15_2_0 {
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+class buffer_error_category : public ceph::converting_category {
+public:
+ buffer_error_category(){}
+ const char* name() const noexcept override;
+ const char* message(int ev, char*, std::size_t) const noexcept override;
+ std::string message(int ev) const override;
+ boost::system::error_condition default_error_condition(int ev) const noexcept
+ override;
+ using ceph::converting_category::equivalent;
+ bool equivalent(int ev, const boost::system::error_condition& c) const
+ noexcept override;
+ int from_code(int ev) const noexcept override;
+};
+#pragma GCC diagnostic pop
+#pragma clang diagnostic pop
+
+const char* buffer_error_category::name() const noexcept {
+ return "buffer";
+}
+
+const char*
+buffer_error_category::message(int ev, char*, std::size_t) const noexcept {
+ using ceph::buffer::errc;
+ if (ev == 0)
+ return "No error";
+
+ switch (static_cast<errc>(ev)) {
+ case errc::bad_alloc:
+ return "Bad allocation";
+
+ case errc::end_of_buffer:
+ return "End of buffer";
+
+ case errc::malformed_input:
+ return "Malformed input";
+ }
+
+ return "Unknown error";
+}
+
+std::string buffer_error_category::message(int ev) const {
+ return message(ev, nullptr, 0);
+}
+
+boost::system::error_condition
+buffer_error_category::default_error_condition(int ev)const noexcept {
+ using ceph::buffer::errc;
+ switch (static_cast<errc>(ev)) {
+ case errc::bad_alloc:
+ return boost::system::errc::not_enough_memory;
+ case errc::end_of_buffer:
+ case errc::malformed_input:
+ return boost::system::errc::io_error;
+ }
+ return { ev, *this };
+}
+
+bool buffer_error_category::equivalent(int ev, const boost::system::error_condition& c) const noexcept {
+ return default_error_condition(ev) == c;
+}
+
+int buffer_error_category::from_code(int ev) const noexcept {
+ using ceph::buffer::errc;
+ switch (static_cast<errc>(ev)) {
+ case errc::bad_alloc:
+ return -ENOMEM;
+
+ case errc::end_of_buffer:
+ return -EIO;
+
+ case errc::malformed_input:
+ return -EIO;
+ }
+ return -EDOM;
+}
+
+const boost::system::error_category& buffer_category() noexcept {
+ static const buffer_error_category c;
+ return c;
+}
+}
+}
#include <seastar/core/temporary_buffer.hh>
#include "include/buffer.h"
+#include "common/error_code.h"
namespace details {
#pragma GCC diagnostic pop
#pragma clang diagnostic pop
+// Moved here from buffer.h so librados doesn't gain a dependency on
+// Boost.System
+
+namespace ceph::buffer {
+inline namespace v15_2_0 {
+const boost::system::error_category& buffer_category() noexcept;
+enum class errc { bad_alloc = 1,
+ end_of_buffer,
+ malformed_input };
+}
+}
+
+namespace boost::system {
+template<>
+struct is_error_code_enum<::ceph::buffer::errc> {
+ static const bool value = true;
+};
+
+template<>
+struct is_error_condition_enum<::ceph::buffer::errc> {
+ static const bool value = false;
+};
+}
+
+namespace ceph::buffer {
+inline namespace v15_2_0 {
+
+// implicit conversion:
+inline boost::system::error_code make_error_code(errc e) noexcept {
+ return { static_cast<int>(e), buffer_category() };
+}
+
+// explicit conversion:
+inline boost::system::error_condition
+make_error_condition(errc e) noexcept {
+ return { static_cast<int>(e), buffer_category() };
+}
+
+struct error : boost::system::system_error {
+ using system_error::system_error;
+};
+
+struct bad_alloc : public error {
+ bad_alloc() : error(errc::bad_alloc) {}
+ bad_alloc(const char* what_arg) : error(errc::bad_alloc, what_arg) {}
+ bad_alloc(const std::string& what_arg) : error(errc::bad_alloc, what_arg) {}
+};
+struct end_of_buffer : public error {
+ end_of_buffer() : error(errc::end_of_buffer) {}
+ end_of_buffer(const char* what_arg) : error(errc::end_of_buffer, what_arg) {}
+ end_of_buffer(const std::string& what_arg)
+ : error(errc::end_of_buffer, what_arg) {}
+};
+
+struct malformed_input : public error {
+ malformed_input() : error(errc::malformed_input) {}
+ malformed_input(const char* what_arg)
+ : error(errc::malformed_input, what_arg) {}
+ malformed_input(const std::string& what_arg)
+ : error(errc::malformed_input, what_arg) {}
+};
+struct error_code : public error {
+ error_code(int r) : error(-r, boost::system::system_category()) {}
+ error_code(int r, const char* what_arg)
+ : error(-r, boost::system::system_category(), what_arg) {}
+ error_code(int r, const std::string& what_arg)
+ : error(-r, boost::system::system_category(), what_arg) {}
+};
+}
+}
+
#endif // COMMON_CEPH_ERROR_CODE
#include "common/dout.h"
-#include <boost/function.hpp>
+#include <functional>
#include <list>
-#include <set>
#include <memory>
+#include <set>
+
+#include <boost/function.hpp>
+#include <boost/system/error_code.hpp>
+
+#include "common/error_code.h"
#include "include/ceph_assert.h"
#include "common/ceph_mutex.h"
finish(std::forward<C>(t));
delete this;
}
+
+ template <typename C>
+ void operator()(C &&t) noexcept {
+ complete(std::forward<C>(t));
+ }
+
+ template<typename U = T>
+ auto operator()() noexcept
+ -> typename std::enable_if<std::is_default_constructible<U>::value,
+ void>::type {
+ complete(T{});
+ }
+
+
+ std::reference_wrapper<GenContext> func() {
+ return std::ref(*this);
+ }
};
template <typename T>
}
return false;
}
+ void complete(boost::system::error_code ec) {
+ complete(ceph::from_error_code(ec));
+ }
+ void operator()(boost::system::error_code ec) noexcept {
+ complete(ec);
+ }
+
+ void operator()() noexcept {
+ complete({});
+ }
+
+ std::reference_wrapper<Context> func() {
+ return std::ref(*this);
+ }
};
/**
public:
LambdaContext(T &&t) : t(std::forward<T>(t)) {}
void finish(int r) override {
- t(r);
+ if constexpr (std::is_invocable_v<T, int>)
+ t(r);
+ else
+ t();
}
private:
T t;
virtual ContextType *build() = 0;
};
+inline auto lambdafy(Context *c) {
+ return [fin = std::unique_ptr<Context>(c)]
+ (boost::system::error_code ec) mutable {
+ fin.release()->complete(ceph::from_error_code(ec));
+ };
+}
+
+
#undef mydout
#endif
#include "crc32c.h"
#include "buffer_fwd.h"
+
#ifdef __CEPH__
# include "include/ceph_assert.h"
#else
namespace buffer CEPH_BUFFER_API {
inline namespace v15_2_0 {
- /*
- * exceptions
- */
-
- struct error : public std::exception{
- const char *what() const throw () override;
- };
- struct bad_alloc : public error {
- const char *what() const throw () override;
- };
- struct end_of_buffer : public error {
- const char *what() const throw () override;
- };
- struct malformed_input : public error {
- explicit malformed_input(const std::string& w) {
- snprintf(buf, sizeof(buf), "buffer::malformed_input: %s", w.c_str());
- }
- const char *what() const throw () override;
- private:
- char buf[256];
- };
- struct error_code : public malformed_input {
- explicit error_code(int error);
- int code;
- };
-
+/// Actual definitions in common/error_code.h
+struct error;
+struct bad_alloc;
+struct end_of_buffer;
+struct malformed_input;
+struct error_code;
/// count of cached crc hits (matching input)
int get_cached_crc();
}
}
- iterator_impl& operator+=(size_t len) {
- pos += len;
- if (pos > end_ptr)
- throw end_of_buffer();
- return *this;
- }
+ iterator_impl& operator+=(size_t len);
const char *get_pos() {
return pos;
std::ostream& operator<<(std::ostream& out, const buffer::list& bl);
-std::ostream& operator<<(std::ostream& out, const buffer::error& e);
-
inline bufferhash& operator<<(bufferhash& l, const bufferlist &r) {
l.update(r);
return l;
} // namespace ceph
+
#endif
#include "byteorder.h"
#include "common/convenience.h"
+#include "common/error_code.h"
template<typename T, typename=void>
struct denc_traits {
decode(client_data, bl_it);
} catch (const buffer::error &err) {
lderr(cct) << this << " " << __func__ << ": "
- << "failed to decode client data: " << err << dendl;
+ << "failed to decode client data: " << err.what() << dendl;
return -EINVAL;
}
decode(got_fnode, p);
} catch (const buffer::error &err) {
derr << "Corrupt fnode in dirfrag " << dirfrag()
- << ": " << err << dendl;
+ << ": " << err.what() << dendl;
clog->warn() << "Corrupt fnode header in " << dirfrag() << ": "
- << err << " (" << get_path() << ")";
+ << err.what() << " (" << get_path() << ")";
go_bad(complete);
return;
}
} catch (const buffer::error &err) {
cache->mds->clog->warn() << "Corrupt dentry '" << dname << "' in "
"dir frag " << dirfrag() << ": "
- << err << "(" << get_path() << ")";
+ << err.what() << "(" << get_path() << ")";
// Remember that this dentry is damaged. Subsequent operations
// that try to act directly on it will get their EIOs, but this
fin->complete(0);
}
} catch (buffer::error &err) {
- derr << "Corrupt inode " << ino() << ": " << err << dendl;
+ derr << "Corrupt inode " << ino() << ": " << err.what() << dendl;
fin->complete(-EINVAL);
return;
}
decode(backtrace, bl);
} catch (const buffer::error &decode_exc) {
derr << "corrupt backtrace on ino x0" << std::hex << ino
- << std::dec << ": " << decode_exc << dendl;
+ << std::dec << ": " << decode_exc.what() << dendl;
open_ino_finish(ino, info, -EIO);
return;
}
using namespace seastar;
-future<> MonMap::read_monmap(const std::string& monmap)
+seastar::future<> MonMap::read_monmap(const std::string& monmap)
{
return open_file_dma(monmap, open_flags::ro).then([this] (file f) {
return f.size().then([this, f = std::move(f)](size_t s) {
});
}
-future<> MonMap::init_with_dns_srv(bool for_mkfs, const std::string& name)
+seastar::future<> MonMap::init_with_dns_srv(bool for_mkfs, const std::string& name)
{
string domain;
string service = name;
});
}
-future<> MonMap::build_initial(const crimson::common::ConfigProxy& conf, bool for_mkfs)
+seastar::future<> MonMap::build_initial(const crimson::common::ConfigProxy& conf, bool for_mkfs)
{
// file?
if (const auto monmap = conf.get_val<std::string>("monmap");
try {
CONTINUATION_RUN(continuation)
} catch (const ceph::buffer::error &e) {
- lderr(cct) << __func__ << " failed decoding of frame header: " << e
+ lderr(cct) << __func__ << " failed decoding of frame header: " << e.what()
<< dendl;
_fault();
} catch (const ceph::crypto::onwire::MsgAuthError &e) {
bufferlist::const_iterator bvp = bv.begin();
try {
ssc->snapset.decode(bvp);
- } catch (ceph::buffer::error& e) {
- dout(0) << __func__ << " Can't decode snapset: " << e << dendl;
+ } catch (const ceph::buffer::error& e) {
+ dout(0) << __func__ << " Can't decode snapset: " << e.what() << dendl;
return NULL;
}
ssc->exists = true;
decode(policy, bl);
owner = policy.get_owner();
} catch (buffer::error& err) {
- ldout(store->ctx(), 0) << "ERROR: decode policy failed" << err << dendl;
+ ldout(store->ctx(), 0) << "ERROR: decode policy failed" << err.what()
+ << dendl;
return -EIO;
}
} else {
ssize_t pos = key.name.find('_', 1);
if (pos < 0) {
- throw buffer::error();
+ throw buffer::malformed_input();
}
key.name = key.name.substr(pos + 1);
}
}
const char* expected_what[] = {
- "buffer::malformed_input: void lame_decoder(int) no longer understand old encoding version 100 < 200",
- "buffer::malformed_input: void lame_decoder(int) decode past end of struct encoding",
+ "void lame_decoder(int) no longer understand old encoding version 100 < 200: Malformed input",
+ "void lame_decoder(int) decode past end of struct encoding: Malformed input"
};
void lame_decoder(int which) {
*/
#include "include/buffer.h"
+#include "common/error_code.h"
using namespace ceph;
} else {
ssize_t pos = object.find('_', 1);
if (pos < 0) {
- throw buffer::error();
+ throw buffer::malformed_input();
}
orig_obj = object.substr(pos);
}
}
} catch (const buffer::error &err) {
std::cerr << "Could not decode for human readable output (you may still"
- " use non-readable mode). Detail: " << err << std::endl;
+ " use non-readable mode). Detail: " << err.what() << std::endl;
}
out.append(ss);
try {
e.decode_with_checksum(bp);
} catch (const buffer::error &e) {
- cerr << "Error reading pg log entry: " << e << std::endl;
+ cerr << "Error reading pg log entry: " << e.what() << std::endl;
}
if (debug) {
cerr << "read entry " << e << std::endl;
auto q = parent_bl.cbegin();
backtrace.decode(q);
} catch (buffer::error &e) {
- dout(4) << "Corrupt backtrace on '" << oid << "': " << e << dendl;
+ dout(4) << "Corrupt backtrace on '" << oid << "': " << e.what() << dendl;
if (!force_corrupt) {
return -EINVAL;
} else {
auto q = layout_bl.cbegin();
decode(loaded_layout, q);
} catch (buffer::error &e) {
- dout(4) << "Corrupt layout on '" << oid << "': " << e << dendl;
+ dout(4) << "Corrupt layout on '" << oid << "': " << e.what() << dendl;
if (!force_corrupt) {
return -EINVAL;
}
backtrace.decode(q);
have_backtrace = true;
} catch (buffer::error &e) {
- dout(4) << "Corrupt backtrace on '" << root_frag_oid << "': " << e << dendl;
+ dout(4) << "Corrupt backtrace on '" << root_frag_oid << "': "
+ << e.what() << dendl;
}
}
}
}catch (const buffer::error &err){
cerr << "corrupt decode in snap_blob"
- << ": " << err << std::endl;
+ << ": " << err.what() << std::endl;
return -1;
}
::decode(got_fnode, p);
}catch (const buffer::error &err){
cerr << "corrupt fnode header in " << oid
- << ": " << err << std::endl;
+ << ": " << err.what() << std::endl;
return -1;
}
}
} catch (const buffer::error &err) {
derr << "Corrupt dentry '" << dname << "' : "
- << err << "(" << "" << ")" << dendl;
+ << err.what() << "(" << "" << ")" << dendl;
return -1;
}
}
}
} catch (const buffer::error &err) {
derr << "Corrupt dentry '" << dname << "' : "
- << err << "(" << "" << ")" << dendl;
+ << err.what() << "(" << "" << ")" << dendl;
return -1;
}
}
}
}catch (const buffer::error &err){
cerr << "corrupt decode in snap_blob"
- << ": " << err << std::endl;
+ << ": " << err.what() << std::endl;
}
f->close_section();
f->close_section();