#include "rgw_ssd_driver.h"
#if defined(__linux__)
#include <features.h>
+#include <sys/xattr.h>
#endif
#if __has_include(<filesystem>)
namespace rgw { namespace cache {
+constexpr std::string_view ATTR_PREFIX = "user.rgw.";
+
std::optional<Partition> SSDDriver::get_partition_info(const DoutPrefixProvider* dpp, const std::string& name, const std::string& type)
{
std::string key = name + type;
efs::space_info space = efs::space(location);
this->free_space = space.available;
+ if (attrs.size() > 0) {
+ r = set_attrs(dpp, key, attrs);
+ if (r < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: put::set_attrs: failed to set attrs, r = " << r << dendl;
+ return r;
+ }
+ }
+
return insert_entry(dpp, key, 0, len);
}
ceph::encode(buffer, bl);
+ if (attrs.size() > 0) {
+ r = get_attrs(dpp, key, attrs);
+ if (r < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: put::get_attrs: failed to get attrs, r = " << r << dendl;
+ return r;
+ }
+ }
return 0;
}
return init.result.get();
}
+int SSDDriver::update_attrs(const DoutPrefixProvider* dpp, const std::string& key, rgw::sal::Attrs& attrs)
+{
+ std::string location = partition_info.location + key;
+ ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): location=" << location << dendl;
+
+ for (auto& it : attrs) {
+ std::string attr_name, attr_val;
+ ceph::decode(attr_val, it.second);
+ attr_name = it.first;
+ auto ret = setxattr(location.c_str(), attr_name.c_str(), attr_val.c_str(), attr_val.size(), XATTR_REPLACE);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "SSDCache: " << __func__ << "(): could not modify attr value for attr name: " << attr_name << " key: " << key << dendl;
+ return ret;
+ }
+ }
+ return 0;
+}
+
+int SSDDriver::delete_attrs(const DoutPrefixProvider* dpp, const std::string& key, rgw::sal::Attrs& del_attrs)
+{
+ std::string location = partition_info.location + key;
+ ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): location=" << location << dendl;
+
+ for (auto& it : del_attrs) {
+ auto ret = delete_attr(dpp, key, it.first);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "SSDCache: " << __func__ << "(): could not remove attr value for attr name: " << it.first << " key: " << key << dendl;
+ return ret;
+ }
+ }
+ return 0;
+}
+
+int SSDDriver::get_attrs(const DoutPrefixProvider* dpp, const std::string& key, rgw::sal::Attrs& attrs)
+{
+ std::string location = partition_info.location + key;
+ ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): location=" << location << dendl;
+
+ char namebuf[64 * 1024];
+ int ret;
+ ssize_t buflen = listxattr(location.c_str(), namebuf, sizeof(namebuf));
+ if (buflen < 0) {
+ ret = errno;
+ ldpp_dout(dpp, 0) << "ERROR: could not get attributes for key: " << key << ": " << ret << dendl;
+ return -ret;
+ }
+ char *keyptr = namebuf;
+ while (buflen > 0) {
+ ssize_t keylen;
+
+ keylen = strlen(keyptr) + 1;
+ std::string attr_name(keyptr);
+ std::string::size_type prefixloc = key.find(ATTR_PREFIX);
+ if (prefixloc == std::string::npos) {
+ buflen -= keylen;
+ keyptr += keylen;
+ continue;
+ }
+ std::string attr_value = get_attr(dpp, key, attr_name);
+ bufferlist bl_value;
+ ceph::encode(attr_value, bl_value);
+ attrs.emplace(std::move(attr_name), std::move(bl_value));
+
+ }
+ return 0;
+}
+
+int SSDDriver::set_attrs(const DoutPrefixProvider* dpp, const std::string& key, rgw::sal::Attrs& attrs)
+{
+ std::string location = partition_info.location + key;
+ ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): location=" << location << dendl;
+
+ for (auto& [attr_name, attr_val_bl] : attrs) {
+ ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): attr_name = " << attr_name << " attr_val_bl length: " << attr_val_bl.length() << dendl;
+ if (attr_val_bl.length() != 0) {
+ auto ret = set_attr(dpp, key, attr_name, attr_val_bl.c_str());
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "SSDCache: " << __func__ << "(): could not set attr value for attr name: " << attr_name << " key: " << key << dendl;
+ return ret;
+ }
+ }
+ }
+ return 0;
+}
+
+std::string SSDDriver::get_attr(const DoutPrefixProvider* dpp, const std::string& key, const std::string& attr_name)
+{
+ std::string location = partition_info.location + key;
+ ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): location=" << location << dendl;
+
+ ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): get_attr: key: " << attr_name << dendl;
+
+ int attr_size = getxattr(location.c_str(), attr_name.c_str(), nullptr, 0);
+
+ std::string attr_val;
+ attr_val.reserve(attr_size + 1);
+ char* attr_val_ptr = &attr_val[0];
+
+ attr_size = getxattr(location.c_str(), attr_name.c_str(), attr_val_ptr, attr_size);
+ if (attr_size < 0) {
+ ldpp_dout(dpp, 0) << "SSDCache: " << __func__ << "(): could not get attr value for attr name: " << attr_name << " key: " << key << dendl;
+ }
+
+ return attr_val;
+}
+
+int SSDDriver::set_attr(const DoutPrefixProvider* dpp, const std::string& key, const std::string& attr_name, const std::string& attr_val)
+{
+ std::string location = partition_info.location + key;
+ ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): location=" << location << dendl;
+
+ ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): set_attr: key: " << attr_name << " val: " << attr_val << dendl;
+
+ return setxattr(location.c_str(), attr_name.c_str(), attr_val.c_str(), attr_val.size(), 0);
+}
+
+int SSDDriver::delete_attr(const DoutPrefixProvider* dpp, const std::string& key, const std::string& attr_name)
+{
+ std::string location = partition_info.location + key;
+ ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): location=" << location << dendl;
+
+ return removexattr(location.c_str(), attr_name.c_str());
+}
+
+
void SSDCacheAioRequest::cache_aio_read(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, off_t ofs, uint64_t len, rgw::Aio* aio, rgw::AioResult& r)
{
using namespace boost::asio;
virtual rgw::AioResultList get_async (const DoutPrefixProvider* dpp, optional_yield y, rgw::Aio* aio, const std::string& key, off_t ofs, uint64_t len, uint64_t cost, uint64_t id) override;
virtual int append_data(const DoutPrefixProvider* dpp, const::std::string& key, bufferlist& bl_data) = 0;
virtual int delete_data(const DoutPrefixProvider* dpp, const::std::string& key) override;
- virtual int get_attrs(const DoutPrefixProvider* dpp, const std::string& key, rgw::sal::Attrs& attrs) = 0;
- virtual int set_attrs(const DoutPrefixProvider* dpp, const std::string& key, rgw::sal::Attrs& attrs) = 0;
- virtual int update_attrs(const DoutPrefixProvider* dpp, const std::string& key, rgw::sal::Attrs& attrs) = 0;
- virtual int delete_attrs(const DoutPrefixProvider* dpp, const std::string& key, rgw::sal::Attrs& del_attrs) = 0;
- virtual std::string get_attr(const DoutPrefixProvider* dpp, const std::string& key, const std::string& attr_name) = 0;
- virtual int set_attr(const DoutPrefixProvider* dpp, const std::string& key, const std::string& attr_name, const std::string& attr_val) = 0;
+ virtual int get_attrs(const DoutPrefixProvider* dpp, const std::string& key, rgw::sal::Attrs& attrs) override;
+ virtual int set_attrs(const DoutPrefixProvider* dpp, const std::string& key, rgw::sal::Attrs& attrs) override;
+ virtual int update_attrs(const DoutPrefixProvider* dpp, const std::string& key, rgw::sal::Attrs& attrs) override;
+ virtual int delete_attrs(const DoutPrefixProvider* dpp, const std::string& key, rgw::sal::Attrs& del_attrs) override;
+ virtual std::string get_attr(const DoutPrefixProvider* dpp, const std::string& key, const std::string& attr_name) override;
+ virtual int set_attr(const DoutPrefixProvider* dpp, const std::string& key, const std::string& attr_name, const std::string& attr_val) override;
+ int delete_attr(const DoutPrefixProvider* dpp, const std::string& key, const std::string& attr_name);
/* Entry */
virtual bool key_exists(const DoutPrefixProvider* dpp, const std::string& key) override { return entries.count(key) != 0; }