]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/cache: implementation for organizing data in ssd cache
authorPritha Srivastava <prsrivas@redhat.com>
Tue, 10 Sep 2024 14:38:53 +0000 (20:08 +0530)
committerPritha Srivastava <prsrivas@redhat.com>
Mon, 21 Apr 2025 04:04:07 +0000 (09:34 +0530)
into bucket directory, object directory and then versions
representing file names.

This commit for extracts bucket id, object name, version,
offset, and length from input key and organizes data into
directories - with bucket id, object name being used to
create directories and filenames within them using version
and offset and length.

Data can be restored back to in memory LFUDA and dirty object
data structure once rgw is restarted.

Updating unit tests.
test/rgw: Correct RedisDriver keys and add checks for cache blocks after
write

Signed-off-by: Pritha Srivastava <prsrivas@redhat.com>
Signed-off-by: Samarah <samarah.uriarte@ibm.com>
src/rgw/driver/d4n/rgw_sal_d4n.cc
src/rgw/rgw_ssd_driver.cc
src/rgw/rgw_ssd_driver.h
src/test/rgw/test_d4n_policy.cc
src/test/rgw/test_ssd_driver.cc

index b04e9ae4a02c88363ec5bb2dde815f83242a34d9..cd7a81dc6c26973ceb64124919ce2a20822bbd4d 100644 (file)
@@ -1932,12 +1932,6 @@ int D4NFilterObject::D4NFilterDeleteOp::delete_obj(const DoutPrefixProvider* dpp
          return ret;
        }
       }
-
-      if ((ret = source->driver->get_obj_dir()->del(dpp, &block.cacheObj, y)) < 0) {
-       ldpp_dout(dpp, 0) << "Failed to delete object directory entry for: " << block.cacheObj.objName << ", ret=" << ret << dendl;
-       return ret;
-      }
-      
       std::string size;
       if (attrs.find(RGW_CACHE_ATTR_OBJECT_SIZE) != attrs.end()) {
        size = attrs.find(RGW_CACHE_ATTR_OBJECT_SIZE)->second.to_str();
index 6aeb9b6bdf5db6e762fe0ea89bb8c19fd9d53b5d..01b913307eb4b25aae9cdc5b18c23bc64523b158 100644 (file)
@@ -13,9 +13,116 @@ namespace efs = std::filesystem;
 
 namespace rgw { namespace cache {
 
-static inline std::string get_file_path(const std::string& location, const std::string& key)
+static std::atomic<uint64_t> index{0};
+
+static std::vector<std::string> tokenize_key(std::string_view key)
 {
-    return location + "/" + key;
+    std::vector<std::string> tokens;
+    size_t start = 0, end = 0;
+    while ((end = key.find(CACHE_DELIM, start)) != std::string_view::npos) {
+        tokens.emplace_back(key.substr(start, end - start));
+        start = end + 1;
+    }
+    // Add the last token
+    if (start < key.length()) {
+        tokens.emplace_back(key.substr(start));
+    }
+    return tokens;
+}
+
+/*
+* Parses key to return directory path and file name
+*/
+static void parse_key(const DoutPrefixProvider* dpp, const std::string& location, const std::string& key, std::string& dir_path, std::string& file_name, bool& is_dirty, bool temp = false) {
+    ldpp_dout(dpp, 10) << __func__ << "() key is: " << key << dendl;
+    std::string bucket_id, object, version;
+    std::vector<std::string> parts = tokenize_key(key);
+    is_dirty = false;
+
+    ldpp_dout(dpp, 10) << __func__ << "() parts.size() is " << parts.size() << dendl;
+    //dirty blocks
+    if (parts.size() == 4 || parts.size() == 6) {
+        if (parts[0] == "D") {
+            is_dirty = true;
+            bucket_id = parts[1];
+            ldpp_dout(dpp, 10) <<  __func__ << "() bucket_id is " << bucket_id << dendl;
+            object = parts[3];
+            ldpp_dout(dpp, 10) << __func__  << "() object is " << object << dendl;
+            version = DIRTY_BLOCK_PREFIX + parts[2];
+            if (parts.size() == 6) { //has offset and length
+                version += CACHE_DELIM + parts[4] + CACHE_DELIM + parts[5];
+            }
+            if (temp) {
+                version += "_" + std::to_string(index++);
+            }
+            ldpp_dout(dpp, 10) <<  __func__ << "() version is " << version << dendl;
+            dir_path = location + "/" + bucket_id + "/" + object;
+            file_name = version;
+            ldpp_dout(dpp, 10) <<  __func__ << "() dir_path is " << dir_path << dendl;
+        }
+    }
+
+    //clean blocks
+    if (parts.size() == 3 || parts.size() == 5) {
+        bucket_id = parts[0];
+        ldpp_dout(dpp, 10) <<  __func__ << "() bucket_id is " << bucket_id << dendl;
+        object = parts[2];
+        ldpp_dout(dpp, 10) <<  __func__ << "() object is " << object << dendl;
+        version = parts[1];
+        if (parts.size() == 5) { //has offset and length
+            version += CACHE_DELIM + parts[3] + CACHE_DELIM + parts[4];
+        }
+        if (temp) {
+            version += "_" + std::to_string(index++);
+        }
+        ldpp_dout(dpp, 10) <<  __func__ << "() version is " << version << dendl;
+        dir_path = location + "/" + bucket_id + "/" + object;
+        file_name = version;
+        ldpp_dout(dpp, 10) <<  __func__ << "() dir_path is " << dir_path << dendl;
+    }
+    return;
+}
+
+static void create_directories(const DoutPrefixProvider* dpp, const std::string& dir_path)
+{
+    std::error_code ec;
+    if (!efs::exists(dir_path, ec)) {
+        if (!efs::create_directories(dir_path, ec)) {
+            ldpp_dout(dpp, 0) << "initialize::: ERROR creating directory: '" << dir_path <<
+                            "' : " << ec.value() << dendl;
+        } else {
+            uid_t uid = dpp->get_cct()->get_set_uid();
+            gid_t gid = dpp->get_cct()->get_set_gid();
+
+            ldpp_dout(dpp, 5) << "initialize:: uid is " << uid << " and gid is " << gid << dendl;
+            ldpp_dout(dpp, 5) << "initialize:: changing permissions for directory: " << dendl;
+
+            if (uid) { 
+                if (chown(dir_path.c_str(), uid, gid) == -1) {
+                    ldpp_dout(dpp, 5) << "initialize: chown return error: " << strerror(errno) << dendl;
+                }
+
+                if (chmod(dir_path.c_str(), S_IRWXU|S_IRWXG|S_IRWXO) == -1) {
+                    ldpp_dout(dpp, 5) << "initialize: chmod return error: " << strerror(errno) << dendl;
+                }
+            }
+        }
+    }
+}
+
+static inline std::string get_file_path(const DoutPrefixProvider* dpp, const std::string& dir_path, const std::string& file_name)
+{
+    return dir_path + "/" + file_name;
+}
+
+static std::string create_dirs_get_filepath_from_key(const DoutPrefixProvider* dpp, const std::string& location, const std::string& key, bool temp=false)
+{
+    std::string dir_path, file_name;
+    bool is_dirty;
+    parse_key(dpp, location, key, dir_path, file_name, is_dirty, temp);
+    create_directories(dpp, dir_path);
+    return get_file_path(dpp, dir_path, file_name);
+
 }
 
 int SSDDriver::initialize(const DoutPrefixProvider* dpp)
@@ -100,150 +207,172 @@ int SSDDriver::restore_blocks_objects(const DoutPrefixProvider* dpp, ObjectDataC
     if (dpp->get_cct()->_conf->rgw_d4n_l1_evict_cache_on_start) {
         return 0; //don't do anything as the cache directory must have been evicted during start-up
     }
-    for (auto const& dir_entry : std::filesystem::directory_iterator{partition_info.location}) {
-        ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): dir_entry.path: " << dir_entry.path() << dendl;
-        std::string file_name = dir_entry.path().filename();
-        std::vector<std::string> parts;
-        std::string part;
-        bool parsed = false;
-        ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): filename: " << file_name << dendl;
-        try {
-            std::stringstream ss(file_name);
-            while (std::getline(ss, part, CACHE_DELIM)) {
-                parts.push_back(part);
-            }
-            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): parts.size(): " << parts.size() << dendl;
-            //non-dirty or clean blocks - bucket_id, version, object_name in head block and offset, len in data blocks
-            if (parts.size() == 3 || parts.size() == 5) {
-                std::string key = file_name;
-                ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): file_name: " << file_name << dendl;
-
-                std::string version = url_decode(parts[1]);
-                ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): version: " << version << dendl;
-
-                uint64_t offset = 0, len = 0;
-                if (parts.size() == 5) {
-                    offset = std::stoull(parts[3]);
-                    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): offset: " << offset << dendl;
-
-                    len = std::stoull(parts[4]);
-                    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): len: " << len << dendl;
-                }
-                std::string localWeightStr;
-                auto ret = get_attr(dpp, file_name, RGW_CACHE_ATTR_LOCAL_WEIGHT, localWeightStr, null_yield);
-                if (ret < 0) {
-                    ldpp_dout(dpp, 0) << "SSDCache: " << __func__ << "(): Failed to get attr: " << RGW_CACHE_ATTR_LOCAL_WEIGHT << dendl;
-                } else {
-                    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): localWeightStr: " << localWeightStr << dendl;
-                }
-                block_func(dpp, key, offset, len, version, false, null_yield, localWeightStr);
-                parsed = true;
-            }
-            //dirty blocks - "D", bucket_id, version, object_name in head block and offset, len in data blocks
-            if ((parts.size() == 4 || parts.size() == 6) && parts[0] == "D") {
-                std::string prefix = DIRTY_BLOCK_PREFIX;
-                if (file_name.starts_with(prefix)) {
-                    std::string key = file_name.substr(prefix.length());
-                    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): key: " << key << dendl;
-
-                    bool dirty = true;
-
-                    std::string bucket_id = url_decode(parts[1]);
-                    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): bucket_id: " << bucket_id << dendl;
-
-                    std::string version = url_decode(parts[2]);
-                    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): version: " << version << dendl;
-
-                    std::string obj_name = url_decode(parts[3]);
-                    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): obj_name: " << obj_name << dendl;
-
-                    uint64_t len = 0, offset = 0;
-                    std::string localWeightStr;
-                    if (parts.size() == 4) {
-                        rgw::sal::Attrs attrs;
-                        get_attrs(dpp, file_name, attrs, null_yield);
-                        std::string etag, bucket_name;
-                        uint64_t size = 0;
-                        time_t creationTime = time_t(nullptr);
-                        rgw_user user;
-                        rgw_obj_key obj_key;
-                        if (attrs.find(RGW_ATTR_ETAG) != attrs.end()) {
-                            etag = attrs[RGW_ATTR_ETAG].to_str();
-                            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): etag: " << etag << dendl;
-                        }
-                        if (attrs.find(RGW_CACHE_ATTR_OBJECT_SIZE) != attrs.end()) {
-                            size = std::stoull(attrs[RGW_CACHE_ATTR_OBJECT_SIZE].to_str());
-                            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): size: " << size << dendl;
-                        }
-                        if (attrs.find(RGW_CACHE_ATTR_MTIME) != attrs.end()) {
-                            creationTime = ceph::real_clock::to_time_t(ceph::real_clock::from_double(std::stod(attrs[RGW_CACHE_ATTR_MTIME].to_str())));
-                            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): creationTime: " << creationTime << dendl;
-                        }
-                        if (attrs.find(RGW_ATTR_ACL) != attrs.end()) {
-                            bufferlist bl_acl = attrs[RGW_ATTR_ACL];
-                            RGWAccessControlPolicy policy;
-                            auto iter = bl_acl.cbegin();
-                            try {
-                                policy.decode(iter);
-                            } catch (buffer::error& err) {
-                                ldpp_dout(dpp, 0) << "ERROR: could not decode policy, caught buffer::error" << dendl;
-                                continue;
+    std::string cache_location = partition_info.location;
+    if (cache_location.back() == '/') {
+        ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): cache_location: " << cache_location << dendl;
+        cache_location.pop_back();
+    }
+    for (auto const& dir_entry : efs::directory_iterator{partition_info.location}) {
+        std::string bucket_id, object_name;
+        if (dir_entry.is_directory()) {
+            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): Is directory, path: " << dir_entry.path() << dendl;
+            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): File Name: " << dir_entry.path().filename() << dendl;
+            bucket_id = dir_entry.path().filename();
+            for (auto const& sub_dir_entry : efs::directory_iterator{dir_entry.path()}) {
+                if (sub_dir_entry.is_directory()) {
+                    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): Is directory, path: " << sub_dir_entry.path() << dendl;
+                    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): File Name: " << sub_dir_entry.path().filename() << dendl;
+                    object_name = sub_dir_entry.path().filename();
+                    for (auto const& file_entry : efs::directory_iterator{sub_dir_entry.path()}) {
+                        try {
+                            if (file_entry.is_regular_file()) {
+                                ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): filename: " << file_entry.path().filename() << dendl;
+                                std::string file_name = file_entry.path().filename();
+                                bool parsed = false;
+                                std::vector<std::string> parts;
+                                std::string part;
+                                std::stringstream ss(file_name);
+                                while (std::getline(ss, part, CACHE_DELIM)) {
+                                    parts.push_back(part);
+                                }
+                                ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): parts.size(): " << parts.size() << dendl;
+                                //non-dirty or clean blocks - version in head block and offset, len in data blocks
+                                if (parts.size() == 1 || parts.size() == 3) {
+                                    std::string version = url_decode(parts[0]);
+                                    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): version: " << version << dendl;
+
+                                    std::string key = url_encode(bucket_id, true) + CACHE_DELIM + url_encode(version, true) + CACHE_DELIM + url_encode(object_name, true);
+                                    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): key: " << key << dendl;
+
+                                    uint64_t offset = 0, len = 0;
+                                    if (parts.size() == 3) {
+                                        offset = std::stoull(parts[1]);
+                                        ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): offset: " << offset << dendl;
+
+                                        len = std::stoull(parts[2]);
+                                        ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): len: " << len << dendl;
+
+                                        key = key + CACHE_DELIM + std::to_string(offset) + CACHE_DELIM + std::to_string(len);
+                                        ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): key: " << key << dendl;
+                                    }
+                                    std::string localWeightStr;
+                                    auto ret = get_attr(dpp, file_entry.path(), RGW_CACHE_ATTR_LOCAL_WEIGHT, localWeightStr, null_yield);
+                                    if (ret < 0) {
+                                        ldpp_dout(dpp, 0) << "SSDCache: " << __func__ << "(): Failed to get attr: " << RGW_CACHE_ATTR_LOCAL_WEIGHT << dendl;
+                                    } else {
+                                        ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): localWeightStr: " << localWeightStr << dendl;
+                                    }
+                                    block_func(dpp, key, offset, len, version, false, null_yield, localWeightStr);
+                                    parsed = true;
+                                }
+                                //dirty blocks - "D", version in head block and offset, len in data blocks
+                                if ((parts.size() == 2 || parts.size() == 4) && parts[0] == "D") {
+                                    std::string prefix = DIRTY_BLOCK_PREFIX;
+                                    if (file_name.starts_with(prefix)) {
+                                        bool dirty = true;
+
+                                        std::string version = url_decode(parts[1]);
+                                        ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): version: " << version << dendl;
+
+                                        std::string key = url_encode(bucket_id, true) + CACHE_DELIM + url_encode(version, true) + CACHE_DELIM + url_encode(object_name, true);
+                                        ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): key: " << key << dendl;
+                    
+                                        uint64_t len = 0, offset = 0;
+                                        std::string localWeightStr;
+                                        if (parts.size() == 2) {
+                                            rgw::sal::Attrs attrs;
+                                            get_attrs(dpp, file_entry.path(), attrs, null_yield);
+                                            std::string etag, bucket_name;
+                                            uint64_t size = 0;
+                                            time_t creationTime = time_t(nullptr);
+                                            rgw_user user;
+                                            rgw_obj_key obj_key;
+                                            if (attrs.find(RGW_ATTR_ETAG) != attrs.end()) {
+                                                etag = attrs[RGW_ATTR_ETAG].to_str();
+                                                ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): etag: " << etag << dendl;
+                                            }
+                                            if (attrs.find(RGW_CACHE_ATTR_OBJECT_SIZE) != attrs.end()) {
+                                                size = std::stoull(attrs[RGW_CACHE_ATTR_OBJECT_SIZE].to_str());
+                                                ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): size: " << size << dendl;
+                                            }
+                                            if (attrs.find(RGW_CACHE_ATTR_MTIME) != attrs.end()) {
+                                                creationTime = ceph::real_clock::to_time_t(ceph::real_clock::from_double(std::stod(attrs[RGW_CACHE_ATTR_MTIME].to_str())));
+                                                ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): creationTime: " << creationTime << dendl;
+                                            }
+                                            if (attrs.find(RGW_ATTR_ACL) != attrs.end()) {
+                                                bufferlist bl_acl = attrs[RGW_ATTR_ACL];
+                                                RGWAccessControlPolicy policy;
+                                                auto iter = bl_acl.cbegin();
+                                                try {
+                                                    policy.decode(iter);
+                                                } catch (buffer::error& err) {
+                                                    ldpp_dout(dpp, 0) << "ERROR: could not decode policy, caught buffer::error" << dendl;
+                                                    continue;
+                                                }
+                                                user = std::get<rgw_user>(policy.get_owner().id);
+                                                ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): rgw_user: " << user.to_str() << dendl;
+                                            }
+                                            obj_key.name = object_name;
+                                            if (attrs.find(RGW_CACHE_ATTR_VERSION_ID) != attrs.end()) {
+                                                std::string instance = attrs[RGW_CACHE_ATTR_VERSION_ID].to_str();
+                                                if (instance != "null") {
+                                                    obj_key.instance = instance;
+                                                }
+                                            }
+                                            if (attrs.find(RGW_CACHE_ATTR_OBJECT_NS) != attrs.end()) {
+                                                obj_key.ns = attrs[RGW_CACHE_ATTR_OBJECT_NS].to_str();
+                                            }
+                                            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): rgw_obj_key: " << obj_key.get_oid() << dendl;
+                                            if (attrs.find(RGW_CACHE_ATTR_BUCKET_NAME) != attrs.end()) {
+                                                bucket_name = attrs[RGW_CACHE_ATTR_BUCKET_NAME].to_str();
+                                                ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): bucket_name: " << bucket_name << dendl;
+                                            }
+
+                                            if (attrs.find(RGW_CACHE_ATTR_LOCAL_WEIGHT) != attrs.end()) {
+                                                localWeightStr = attrs[RGW_CACHE_ATTR_LOCAL_WEIGHT].to_str();
+                                                ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): localWeightStr: " << localWeightStr << dendl;
+                                            }
+
+                                            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): calling func for: " << key << dendl;
+                                            obj_func(dpp, key, version, dirty, size, creationTime, user, etag, bucket_name, bucket_id, obj_key, null_yield);
+                                            block_func(dpp, key, offset, len, version, dirty, null_yield, localWeightStr);
+                                            parsed = true;
+                                        } //end-if part.size() == 2
+                                        if (parts.size() == 4) {
+                                            offset = std::stoull(parts[2]);
+                                            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): offset: " << offset << dendl;
+
+                                            len = std::stoull(parts[3]);
+                                            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): len: " << len << dendl;
+
+                                            key = key + CACHE_DELIM + std::to_string(offset) + CACHE_DELIM + std::to_string(len);
+                                            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): key: " << key << dendl;
+
+                                            std::string localWeightStr;
+                                            auto ret = get_attr(dpp, file_entry.path(), RGW_CACHE_ATTR_LOCAL_WEIGHT, localWeightStr, null_yield);
+                                            if (ret < 0) {
+                                                ldpp_dout(dpp, 0) << "SSDCache: " << __func__ << "(): Failed to get attr: " << RGW_CACHE_ATTR_LOCAL_WEIGHT << dendl;
+                                            } else {
+                                                ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): localWeightStr: " << localWeightStr << dendl;
+                                            }
+                                            block_func(dpp, key, offset, len, version, dirty, null_yield, localWeightStr);
+                                            parsed = true;
+                                        }
+                                    } //end-if file_name.starts_with
+                                } //end-if parts.size() == 2 || parts.size() == 4
+                                if (!parsed) {
+                                    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): Unable to parse file_name: " << file_name << dendl;
+                                    continue;
+                                }
                             }
-                            user = std::get<rgw_user>(policy.get_owner().id);
-                            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): rgw_user: " << user.to_str() << dendl;
-                        }
-                        obj_key.name = obj_name;
-                        if (attrs.find(RGW_CACHE_ATTR_VERSION_ID) != attrs.end()) {
-                            std::string instance = attrs[RGW_CACHE_ATTR_VERSION_ID].to_str();
-                            if (instance != "null") {
-                                obj_key.instance = instance;
-                            }
-                        }
-                        if (attrs.find(RGW_CACHE_ATTR_OBJECT_NS) != attrs.end()) {
-                            obj_key.ns = attrs[RGW_CACHE_ATTR_OBJECT_NS].to_str();
-                        }
-                        ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): rgw_obj_key: " << obj_key.get_oid() << dendl;
-                        if (attrs.find(RGW_CACHE_ATTR_BUCKET_NAME) != attrs.end()) {
-                            bucket_name = attrs[RGW_CACHE_ATTR_BUCKET_NAME].to_str();
-                            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): bucket_name: " << bucket_name << dendl;
-                        }
-
-                        if (attrs.find(RGW_CACHE_ATTR_LOCAL_WEIGHT) != attrs.end()) {
-                            localWeightStr = attrs[RGW_CACHE_ATTR_LOCAL_WEIGHT].to_str();
-                            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): localWeightStr: " << localWeightStr << dendl;
-                        }
-
-                        ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): calling func for: " << key << dendl;
-                        obj_func(dpp, key, version, dirty, size, creationTime, user, etag, bucket_name, bucket_id, obj_key, null_yield);
-                        block_func(dpp, key, offset, len, version, dirty, null_yield, localWeightStr);
-                        parsed = true;
-                    } //end-if part.size() == 4
-                    if (parts.size() == 6) {
-                        offset = std::stoull(parts[4]);
-                        ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): offset: " << offset << dendl;
-
-                        len = std::stoull(parts[5]);
-                        ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): len: " << len << dendl;
-                        std::string localWeightStr;
-                        auto ret = get_attr(dpp, file_name, RGW_CACHE_ATTR_LOCAL_WEIGHT, localWeightStr, null_yield);
-                        if (ret < 0) {
-                            ldpp_dout(dpp, 0) << "SSDCache: " << __func__ << "(): Failed to get attr: " << RGW_CACHE_ATTR_LOCAL_WEIGHT << dendl;
-                        } else {
-                            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): localWeightStr: " << localWeightStr << dendl;
+                        }//end - try
+                        catch(...) {
+                            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): Execption while parsing entry: " << file_entry.path() << dendl;
+                            continue;
                         }
-                        block_func(dpp, key, offset, len, version, dirty, null_yield, localWeightStr);
-                        parsed = true;
                     }
-                } //end-if file_name.starts_with
-            } //end-if parts.size() == 4 || parts.size() == 6
-            if (!parsed) {
-                ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): Unable to parse file_name: " << file_name << dendl;
-                continue;
+                }
             }
-        }//end-try
-        catch(...) {
-            ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): Execption while parsing file_name: " << file_name << dendl;
-            continue;
         }
     }
 
@@ -272,7 +401,7 @@ int SSDDriver::put(const DoutPrefixProvider* dpp, const std::string& key, const
 int SSDDriver::get(const DoutPrefixProvider* dpp, const std::string& key, off_t offset, uint64_t len, bufferlist& bl, rgw::sal::Attrs& attrs, optional_yield y)
 {
     char buffer[len];
-    std::string location = get_file_path(partition_info.location, key);
+    std::string location = create_dirs_get_filepath_from_key(dpp, partition_info.location, key);
     ldpp_dout(dpp, 20) << __func__ << "(): location=" << location << dendl;
     FILE *cache_file = nullptr;
     int r = 0;
@@ -313,7 +442,7 @@ int SSDDriver::get(const DoutPrefixProvider* dpp, const std::string& key, off_t
 int SSDDriver::append_data(const DoutPrefixProvider* dpp, const::std::string& key, const bufferlist& bl_data, optional_yield y)
 {
     bufferlist src = bl_data;
-    std::string location = get_file_path(partition_info.location, key);
+    std::string location = create_dirs_get_filepath_from_key(dpp, partition_info.location, key);
 
     ldpp_dout(dpp, 20) << __func__ << "(): location=" << location << dendl;
     FILE *cache_file = nullptr;
@@ -371,7 +500,7 @@ auto SSDDriver::get_async(const DoutPrefixProvider *dpp, const Executor& ex, con
     auto p = Op::create(ex, handler);
     auto& op = p->user_data;
 
-    std::string location = get_file_path(partition_info.location, key);
+    std::string location = create_dirs_get_filepath_from_key(dpp, partition_info.location, key);
     ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): location=" << location << dendl;
 
     int ret = op.prepare_libaio_read_op(dpp, location, read_ofs, read_len, p.get());
@@ -401,20 +530,19 @@ void SSDDriver::put_async(const DoutPrefixProvider *dpp, const Executor& ex, con
     auto p = Op::create(ex, handler);
     auto& op = p->user_data;
 
-    std::string location = get_file_path(partition_info.location, key);
-    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): location=" << location << dendl;
+    op.file_path = create_dirs_get_filepath_from_key(dpp, partition_info.location, key);
+    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): op.file_path=" << op.file_path << dendl;
+
+    op.temp_file_path = create_dirs_get_filepath_from_key(dpp, partition_info.location, key, true);
+    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): op.temp_file_path=" << op.temp_file_path << dendl;
 
     int r = 0;
     bufferlist src = bl;
-    std::string temp_key = key + "_" + std::to_string(index++);
-    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): temp key=" << temp_key << dendl;
-    r = op.prepare_libaio_write_op(dpp, src, len, temp_key, partition_info.location);
+    r = op.prepare_libaio_write_op(dpp, src, len, op.temp_file_path);
     op.cb->aio_sigevent.sigev_notify = SIGEV_THREAD;
     op.cb->aio_sigevent.sigev_notify_function = SSDDriver::AsyncWriteRequest::libaio_write_cb;
     op.cb->aio_sigevent.sigev_notify_attributes = nullptr;
     op.cb->aio_sigevent.sigev_value.sival_ptr = (void*)p.get();
-    op.key = key;
-    op.temp_key = temp_key;
     op.dpp = dpp;
     op.priv_data = this;
     op.attrs = std::move(attrs);
@@ -427,7 +555,7 @@ void SSDDriver::put_async(const DoutPrefixProvider *dpp, const Executor& ex, con
     ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): ::aio_write(), r=" << r << dendl;
     if(r < 0) {
         auto ec = boost::system::error_code{-r, boost::system::system_category()};
-        ceph::async::post(std::move(p), ec);
+        ceph::async::dispatch(std::move(p), ec);
     } else {
         (void)p.release();
     }
@@ -480,13 +608,39 @@ rgw::AioResultList SSDDriver::put_async(const DoutPrefixProvider* dpp, optional_
 
 int SSDDriver::delete_data(const DoutPrefixProvider* dpp, const::std::string& key, optional_yield y)
 {
-    std::string location = get_file_path(partition_info.location, key);
+    std::string dir_path, file_name;
+    bool is_dirty;
+    parse_key(dpp, partition_info.location, key, dir_path, file_name, is_dirty);
+    std::string location = get_file_path(dpp, dir_path, file_name);
+    ldpp_dout(dpp, 20) << "INFO: delete_data::file to remove: " << location << dendl;
 
+    //Remove file
     if (!efs::remove(location)) {
         ldpp_dout(dpp, 0) << "ERROR: delete_data::remove has failed to remove the file: " << location << dendl;
         return -EIO;
     }
 
+    //Remove directory if empty, removes object directory
+    if (efs::is_empty(dir_path)) {
+        ldpp_dout(dpp, 20) << "INFO: delete_data::object directory to remove: " << dir_path << dendl;
+        if (!efs::remove(dir_path)) {
+            ldpp_dout(dpp, 0) << "ERROR: delete_data::remove has failed to remove the directory: " << dir_path << dendl;
+            return -EIO;
+        }
+    }
+    auto pos = dir_path.find_last_of('/');
+    if (pos != std::string::npos) {
+        dir_path.erase(pos, (dir_path.length() - pos));
+
+        //Remove bucket directory
+        if (efs::is_empty(dir_path)) {
+            ldpp_dout(dpp, 20) << "INFO: delete_data::bucket directory to remove: " << dir_path << dendl;
+            if (!efs::remove(dir_path)) {
+                ldpp_dout(dpp, 0) << "ERROR: delete_data::remove has failed to remove the directory: " << dir_path << dendl;
+                return -EIO;
+            }
+        }
+    }
     efs::space_info space = efs::space(partition_info.location);
     this->free_space = space.available;
 
@@ -495,8 +649,8 @@ int SSDDriver::delete_data(const DoutPrefixProvider* dpp, const::std::string& ke
 
 int SSDDriver::rename(const DoutPrefixProvider* dpp, const::std::string& oldKey, const::std::string& newKey, optional_yield y)
 { 
-    std::string old_file_path = get_file_path(partition_info.location, oldKey);
-    std::string new_file_path = get_file_path(partition_info.location, newKey);
+    std::string old_file_path = create_dirs_get_filepath_from_key(dpp, partition_info.location, oldKey);
+    std::string new_file_path = create_dirs_get_filepath_from_key(dpp, partition_info.location, newKey);
     int ret = std::rename(old_file_path.c_str(), new_file_path.c_str());
     if (ret < 0) {
         ldpp_dout(dpp, 0) << "SSDDriver: ERROR: failed to rename the file: " << old_file_path << dendl;
@@ -507,17 +661,16 @@ int SSDDriver::rename(const DoutPrefixProvider* dpp, const::std::string& oldKey,
 }
 
 
-int SSDDriver::AsyncWriteRequest::prepare_libaio_write_op(const DoutPrefixProvider *dpp, bufferlist& bl, unsigned int len, std::string key, std::string cache_location)
+int SSDDriver::AsyncWriteRequest::prepare_libaio_write_op(const DoutPrefixProvider *dpp, bufferlist& bl, unsigned int len, std::string file_path)
 {
-    std::string location = get_file_path(cache_location, key);
     int r = 0;
-    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): Write To Cache, location=" << location << dendl;
+    ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): Write To Cache, location=" << file_path << dendl;
     cb.reset(new struct aiocb);
     memset(cb.get(), 0, sizeof(struct aiocb));
     mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
-    r = fd = TEMP_FAILURE_RETRY(::open(location.c_str(), O_WRONLY | O_CREAT | O_TRUNC, mode));
+    r = fd = TEMP_FAILURE_RETRY(::open(file_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, mode));
     if (fd < 0) {
-        ldpp_dout(dpp, 0) << "ERROR: AsyncWriteRequest::prepare_libaio_write_op: open file failed, errno=" << errno << ", location='" << location.c_str() << "'" << dendl;
+        ldpp_dout(dpp, 0) << "ERROR: AsyncWriteRequest::prepare_libaio_write_op: open file failed, errno=" << errno << ", location='" << file_path.c_str() << "'" << dendl;
         return r;
     }
     if (dpp->get_cct()->_conf->rgw_d4n_l1_fadvise != POSIX_FADV_NORMAL)
@@ -539,7 +692,7 @@ int SSDDriver::AsyncWriteRequest::prepare_libaio_write_op(const DoutPrefixProvid
 void SSDDriver::AsyncWriteRequest::libaio_write_cb(sigval sigval) {
     auto p = std::unique_ptr<Completion>{static_cast<Completion*>(sigval.sival_ptr)};
     auto op = std::move(p->user_data);
-    ldpp_dout(op.dpp, 20) << "INFO: AsyncWriteRequest::libaio_write_cb: key: " << op.key << dendl;
+    ldpp_dout(op.dpp, 20) << "INFO: AsyncWriteRequest::libaio_write_cb: key: " << op.file_path << dendl;
     int ret = -aio_error(op.cb.get());
     boost::system::error_code ec;
     if (ret < 0) {
@@ -551,7 +704,7 @@ void SSDDriver::AsyncWriteRequest::libaio_write_cb(sigval sigval) {
     if (op.attrs.size() > 0) {
         //TODO - fix yield_context
         optional_yield y{null_yield};
-        attr_ret = op.priv_data->set_attrs(op.dpp, op.temp_key, op.attrs, y);
+        attr_ret = op.priv_data->set_attrs(op.dpp, op.temp_file_path, op.attrs, y);
         if (attr_ret < 0) {
             ldpp_dout(op.dpp, 0) << "ERROR: AsyncWriteRequest::libaio_write_yield_cb::set_attrs: failed to set attrs, ret = " << attr_ret << dendl;
             ec.assign(-ret, boost::system::system_category());
@@ -564,11 +717,10 @@ void SSDDriver::AsyncWriteRequest::libaio_write_cb(sigval sigval) {
     efs::space_info space = efs::space(partition_info.location);
     op.priv_data->set_free_space(op.dpp, space.available);
 
-    std::string new_path = get_file_path(partition_info.location, op.key);
-    std::string old_path = get_file_path(partition_info.location, op.temp_key);
-    ldpp_dout(op.dpp, 20) << "INFO: AsyncWriteRequest::libaio_write_yield_cb: temp_key: " << op.temp_key << dendl;
+    ldpp_dout(op.dpp, 20) << "INFO: AsyncWriteRequest::libaio_write_yield_cb: new_path: " << op.file_path << dendl;
+    ldpp_dout(op.dpp, 20) << "INFO: AsyncWriteRequest::libaio_write_yield_cb: old_path: " << op.temp_file_path << dendl;
 
-    ret = std::rename(old_path.c_str(), new_path.c_str());
+    ret = std::rename(op.temp_file_path.c_str(), op.file_path.c_str());
     if (ret < 0) {
         ret = errno;
         ldpp_dout(op.dpp, 0) << "ERROR: put::rename: failed to rename file: " << ret << dendl;
@@ -621,7 +773,7 @@ void SSDDriver::AsyncReadOp::libaio_cb_aio_dispatch(sigval sigval)
 
 int SSDDriver::update_attrs(const DoutPrefixProvider* dpp, const std::string& key, const rgw::sal::Attrs& attrs, optional_yield y)
 {
-    std::string location = get_file_path(partition_info.location, key);
+    std::string location = create_dirs_get_filepath_from_key(dpp, partition_info.location, key);
     ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): location=" << location << dendl;
 
     for (auto& it : attrs) {
@@ -646,7 +798,7 @@ int SSDDriver::update_attrs(const DoutPrefixProvider* dpp, const std::string& ke
 
 int SSDDriver::delete_attrs(const DoutPrefixProvider* dpp, const std::string& key, rgw::sal::Attrs& del_attrs, optional_yield y)
 {
-    std::string location = get_file_path(partition_info.location, key);
+    std::string location = create_dirs_get_filepath_from_key(dpp, partition_info.location, key);
     ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): location=" << location << dendl;
 
     for (auto& it : del_attrs) {
@@ -665,7 +817,14 @@ int SSDDriver::delete_attrs(const DoutPrefixProvider* dpp, const std::string& ke
 
 int SSDDriver::get_attrs(const DoutPrefixProvider* dpp, const std::string& key, rgw::sal::Attrs& attrs, optional_yield y)
 {
-    std::string location = get_file_path(partition_info.location, key);
+    std::string location;
+    // a hack to avoid calling create_dirs_get_filepath_from_key in case the path is already formed
+    if(key.find(partition_info.location, 0) == 0) {
+        location = key;
+    } else {
+        location = create_dirs_get_filepath_from_key(dpp, partition_info.location, key);
+    }
+
     ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): location=" << location << dendl;
 
     char namebuf[64 * 1024];
@@ -689,7 +848,7 @@ int SSDDriver::get_attrs(const DoutPrefixProvider* dpp, const std::string& key,
             continue;
         }
         std::string attr_value;
-        get_attr(dpp, key, attr_name, attr_value, y);
+        get_attr(dpp, location, attr_name, attr_value, y);
         bufferlist bl_value;
         bl_value.append(attr_value);
         attrs.emplace(std::move(attr_name), std::move(bl_value));
@@ -699,7 +858,14 @@ int SSDDriver::get_attrs(const DoutPrefixProvider* dpp, const std::string& key,
 
 int SSDDriver::set_attrs(const DoutPrefixProvider* dpp, const std::string& key, const rgw::sal::Attrs& attrs, optional_yield y)
 {
-    std::string location = get_file_path(partition_info.location, key);
+    std::string location;
+    // a hack to avoid calling create_dirs_get_filepath_from_key in case the path is already formed
+    if(key.find(partition_info.location, 0) == 0) {
+        location = key;
+    } else {
+        location = create_dirs_get_filepath_from_key(dpp, partition_info.location, key);
+    }
+
     ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): location=" << location << dendl;
 
     for (auto& [attr_name, attr_val_bl] : attrs) {
@@ -721,7 +887,14 @@ int SSDDriver::set_attrs(const DoutPrefixProvider* dpp, const std::string& key,
 
 int SSDDriver::get_attr(const DoutPrefixProvider* dpp, const std::string& key, const std::string& attr_name, std::string& attr_val, optional_yield y)
 {
-    std::string location = get_file_path(partition_info.location, key);
+    std::string location;
+    // a hack to avoid calling create_dirs_get_filepath_from_key in case the path is already formed
+    if(key.find(partition_info.location, 0) == 0) {
+        location = key;
+    } else {
+        location = create_dirs_get_filepath_from_key(dpp, 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;
@@ -752,7 +925,14 @@ int SSDDriver::get_attr(const DoutPrefixProvider* dpp, const std::string& key, c
 
 int SSDDriver::set_attr(const DoutPrefixProvider* dpp, const std::string& key, const std::string& attr_name, const std::string& attr_val, optional_yield y)
 {
-    std::string location = get_file_path(partition_info.location, key);
+    std::string location;
+    // a hack to avoid calling create_dirs_get_filepath_from_key in case the path is already formed
+    if(key.find(partition_info.location, 0) == 0) {
+        location = key;
+    } else {
+        location = create_dirs_get_filepath_from_key(dpp, 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;
@@ -771,7 +951,7 @@ int SSDDriver::set_attr(const DoutPrefixProvider* dpp, const std::string& key, c
 
 int SSDDriver::delete_attr(const DoutPrefixProvider* dpp, const std::string& key, const std::string& attr_name)
 {
-    std::string location = get_file_path(partition_info.location, key);
+    std::string location = create_dirs_get_filepath_from_key(dpp, partition_info.location, key);
     ldpp_dout(dpp, 20) << "SSDCache: " << __func__ << "(): location=" << location << dendl;
 
     auto ret = removexattr(location.c_str(), attr_name.c_str());
index e610e8e3872c2a7956d4229e1040e59dcd501d44..1df7ba842f6176878e04316d52845901748594dc 100644 (file)
@@ -39,7 +39,6 @@ private:
   Partition partition_info;
   uint64_t free_space;
   CephContext* cct;
-  inline static std::atomic<uint64_t> index{0};
 
   struct libaio_read_handler {
     rgw::Aio* throttle = nullptr;
@@ -104,8 +103,8 @@ private:
 
   struct AsyncWriteRequest {
     const DoutPrefixProvider* dpp;
-         std::string key;
-    std::string temp_key;
+         std::string file_path;
+    std::string temp_file_path;
          void *data;
          int fd;
          unique_aio_cb_ptr cb;
@@ -115,7 +114,7 @@ private:
     using Signature = void(boost::system::error_code);
     using Completion = ceph::async::Completion<Signature, AsyncWriteRequest>;
 
-         int prepare_libaio_write_op(const DoutPrefixProvider *dpp, bufferlist& bl, unsigned int len, std::string key, std::string cache_location);
+         int prepare_libaio_write_op(const DoutPrefixProvider *dpp, bufferlist& bl, unsigned int len, std::string file_path);
     static void libaio_write_cb(sigval sigval);
 
     template <typename Executor1, typename CompletionHandler>
index f50e42bc9c7a03d3550d2f5fe06889318718b0fd..7bbd962ac91c47217b49535d4f7605bc3895548f 100644 (file)
@@ -44,6 +44,14 @@ class Environment : public ::testing::Environment {
     DoutPrefixProvider* dpp;
 };
 
+static inline std::string get_prefix(const std::string& bucketName, const std::string& oid, std::string& version) {
+  if (version.empty()) {
+    return fmt::format("{}{}{}", bucketName, CACHE_DELIM, oid);
+  } else {
+    return fmt::format("{}{}{}{}{}", bucketName, CACHE_DELIM, version, CACHE_DELIM, oid);
+  }
+}
+
 class LFUDAPolicyFixture : public ::testing::Test {
   protected:
     virtual void SetUp() {
@@ -56,7 +64,7 @@ class LFUDAPolicyFixture : public ::testing::Test {
          .hostsList = { env->redisHost }
        },
         .blockID = 0,
-       .version = "",
+       .version = "version",
        .deleteMarker = false,
        .size = bl.length(),
        .globalWeight = 0
@@ -98,15 +106,12 @@ class LFUDAPolicyFixture : public ::testing::Test {
        delete policyDriver;
     }
 
-    std::string build_index(std::string bucketName, std::string oid, uint64_t offset, uint64_t size) {
-      return bucketName + "_" + oid + "_" + std::to_string(offset) + "_" + std::to_string(size);
-    }
-
     int lfuda(const DoutPrefixProvider* dpp, rgw::d4n::CacheBlock* block, rgw::cache::CacheDriver* cacheDriver, optional_yield y) {
       int age = 1;  
-      std::string oid = build_index(block->cacheObj.bucketName, block->cacheObj.objName, block->blockID, block->size);
+      std::string version;
+      std::string oid = rgw::sal::get_key_in_cache(get_prefix(block->cacheObj.bucketName, block->cacheObj.objName, version), std::to_string(block->blockID), std::to_string(block->size));
 
-      if (this->policyDriver->get_cache_policy()->exist_key(build_index(block->cacheObj.bucketName, block->cacheObj.objName, block->blockID, block->size))) { /* Local copy */
+      if (this->policyDriver->get_cache_policy()->exist_key(oid)) { /* Local copy */
        policyDriver->get_cache_policy()->update(env->dpp, oid, 0, bl.length(), "", false, y);
         return 0;
       } else {
@@ -169,7 +174,8 @@ TEST_F(LFUDAPolicyFixture, LocalGetBlockYield)
     dynamic_cast<rgw::d4n::LFUDAPolicy*>(policyDriver->get_cache_policy())->save_y(optional_yield{yield});
     policyDriver->get_cache_policy()->init(env->cct, env->dpp, io, driver);
 
-    std::string key = block->cacheObj.bucketName + "_" + block->cacheObj.objName + "_" + std::to_string(block->blockID) + "_" + std::to_string(block->size);
+    std::string version;
+    std::string key = rgw::sal::get_key_in_cache(get_prefix(block->cacheObj.bucketName, block->cacheObj.objName, version), std::to_string(block->blockID), std::to_string(block->size));
     ASSERT_EQ(0, cacheDriver->put(env->dpp, key, bl, bl.length(), attrs, optional_yield{yield}));
     policyDriver->get_cache_policy()->update(env->dpp, key, 0, bl.length(), "", false, optional_yield{yield});
 
@@ -179,7 +185,7 @@ TEST_F(LFUDAPolicyFixture, LocalGetBlockYield)
 
     boost::system::error_code ec;
     request req;
-    req.push("HGET", "RedisCache/testBucket_testName_0_0", RGW_CACHE_ATTR_LOCAL_WEIGHT);
+    req.push("HGET", "RedisCache/testBucket#testName#0#0", RGW_CACHE_ATTR_LOCAL_WEIGHT);
     req.push("FLUSHALL");
 
     response<std::string, boost::redis::ignore_t> resp;
@@ -210,7 +216,7 @@ TEST_F(LFUDAPolicyFixture, RemoteGetBlockYield)
        .hostsList = { env->redisHost }
       },
       .blockID = 0,
-      .version = "",
+      .version = "version",
       .deleteMarker = false,
       .prevVersion = {},
       .size = bl.length(),
@@ -229,9 +235,14 @@ TEST_F(LFUDAPolicyFixture, RemoteGetBlockYield)
     policyDriver->get_cache_policy()->init(env->cct, env->dpp, io, driver);
 
     ASSERT_EQ(0, dir->set(env->dpp, &victim, optional_yield{yield}));
-    std::string victimKey = victim.cacheObj.bucketName + "_version_" + victim.cacheObj.objName + "_" + std::to_string(victim.blockID) + "_" + std::to_string(victim.size);
-    ASSERT_EQ(0, cacheDriver->put(env->dpp, victimKey, bl, bl.length(), attrs, optional_yield{yield}));
-    policyDriver->get_cache_policy()->update(env->dpp, victimKey, 0, bl.length(), "", false, optional_yield{yield});
+    std::string victimKeyInCache = rgw::sal::get_key_in_cache(get_prefix(victim.cacheObj.bucketName, victim.cacheObj.objName, victim.version), std::to_string(victim.blockID), std::to_string(victim.size));
+    ASSERT_EQ(0, cacheDriver->put(env->dpp, victimKeyInCache, bl, bl.length(), attrs, optional_yield{yield}));
+    policyDriver->get_cache_policy()->update(env->dpp, victimKeyInCache, 0, bl.length(), "", false, optional_yield{yield});
+
+    /* Set head blocks */
+    std::string victimHeadObj = get_prefix(victim.cacheObj.bucketName, victim.cacheObj.objName, victim.version);
+    ASSERT_EQ(0, cacheDriver->put(env->dpp, victimHeadObj, bl, bl.length(), attrs, optional_yield{yield}));
+    policyDriver->get_cache_policy()->update(env->dpp, victimHeadObj, 0, bl.length(), "", false, optional_yield{yield});
 
     /* Remote block */
     block->size = cacheDriver->get_free_space(env->dpp) + 1; /* To trigger eviction */
@@ -256,15 +267,16 @@ TEST_F(LFUDAPolicyFixture, RemoteGetBlockYield)
 
     cacheDriver->shutdown();
 
+    std::string victimKey = victim.cacheObj.bucketName + "_version_" + victim.cacheObj.objName + "_" + std::to_string(victim.blockID) + "_" + std::to_string(victim.size);
     std::string key = block->cacheObj.bucketName + "_" + block->cacheObj.objName + "_" + std::to_string(block->blockID) + "_" + std::to_string(block->size);
     boost::system::error_code ec;
     request req;
-    req.push("EXISTS", "RedisCache/" + victimKey);
+    req.push("EXISTS", "RedisCache/" + victimKeyInCache);
     req.push("EXISTS", victimKey, "globalWeight");
     req.push("HGET", key, "globalWeight");
     req.push("FLUSHALL");
 
-    response<int, int, std::string, std::string, 
+    response<int, int, std::string, 
              boost::redis::ignore_t> resp;
 
     conn->async_exec(req, resp, yield[ec]);
index bbd394a0096ea6616f95d03de02f64e7cae09a8e..e0cdace51a2526938711a12ebc6611d64a8ab6b4 100644 (file)
@@ -51,6 +51,15 @@ int drain(const DoutPrefixProvider* dpp, rgw::Aio* aio) {
   return flush(dpp, std::move(c));
 }
 
+int flush(const DoutPrefixProvider* dpp, rgw::AioResultList&& results, optional_yield y) {
+  int r = rgw::check_for_errors(results);
+
+  if (r < 0) {
+    return r;
+  }
+  return 0;
+}
+
 class Environment* env;
 
 class Environment : public ::testing::Environment {
@@ -120,10 +129,10 @@ TEST_F(SSDDriverFixture, PutAndGet)
 {
     boost::asio::spawn(io, [this] (boost::asio::yield_context yield) {
         rgw::sal::Attrs attrs = {};
-        ASSERT_EQ(0, cacheDriver->put(env->dpp, "testPutGet", bl, bl.length(), attrs, yield));
+        ASSERT_EQ(0, cacheDriver->put(env->dpp, "bucketid#version#objName#0#4096", bl, bl.length(), attrs, yield));
         bufferlist ret;
         rgw::sal::Attrs get_attrs;
-        ASSERT_EQ(0, cacheDriver->get(env->dpp, "testPutGet", 0, bl.length(), ret, get_attrs, yield));
+        ASSERT_EQ(0, cacheDriver->get(env->dpp, "bucketid#version#objName#0#4096", 0, bl.length(), ret, get_attrs, yield));
         EXPECT_EQ(ret, bl);
         EXPECT_EQ(get_attrs.size(), 0);
     }, rethrow);
@@ -135,16 +144,16 @@ TEST_F(SSDDriverFixture, AppendData)
 {
     boost::asio::spawn(io, [this] (boost::asio::yield_context yield) {
         rgw::sal::Attrs attrs = {};
-        ASSERT_EQ(0, cacheDriver->put(env->dpp, "testAppend", bl, bl.length(), attrs, yield));
+        ASSERT_EQ(0, cacheDriver->put(env->dpp, "bucketid#version#testAppend#0#4096", bl, bl.length(), attrs, yield));
     
         bufferlist bl_append;
         bl_append.append(" xyz");
-        ASSERT_EQ(0, cacheDriver->append_data(env->dpp, "testAppend", bl_append, yield));
+        ASSERT_EQ(0, cacheDriver->append_data(env->dpp, "bucketid#version#testAppend#0#4096", bl_append, yield));
     
         bufferlist ret;
         bl.append(bl_append);
         rgw::sal::Attrs get_attrs;
-        ASSERT_EQ(0, cacheDriver->get(env->dpp, "testAppend", 0, bl.length(), ret, get_attrs, yield));
+        ASSERT_EQ(0, cacheDriver->get(env->dpp, "bucketid#version#testAppend#0#4096", 0, bl.length(), ret, get_attrs, yield));
         EXPECT_EQ(ret, bl);
         EXPECT_EQ(get_attrs.size(), 0);
     }, rethrow);
@@ -155,10 +164,10 @@ TEST_F(SSDDriverFixture, AppendData)
 TEST_F(SSDDriverFixture, SetGetAttrs)
 {
     boost::asio::spawn(io, [this] (boost::asio::yield_context yield) {
-        ASSERT_EQ(0, cacheDriver->put(env->dpp, "testSetGetAttrs", bl, bl.length(), attrs, yield));
+        ASSERT_EQ(0, cacheDriver->put(env->dpp, "bucketid#version#testSetGetAttrs", bl, bl.length(), attrs, yield));
         bufferlist ret;
         rgw::sal::Attrs ret_attrs;
-        ASSERT_EQ(0, cacheDriver->get(env->dpp, "testSetGetAttrs", 0, bl.length(), ret, ret_attrs, yield));
+        ASSERT_EQ(0, cacheDriver->get(env->dpp, "bucketid#version#testSetGetAttrs", 0, bl.length(), ret, ret_attrs, yield));
         EXPECT_EQ(ret, bl);
         EXPECT_EQ(ret_attrs.size(), 1);
         for (auto& it : ret_attrs) {
@@ -173,10 +182,10 @@ TEST_F(SSDDriverFixture, SetGetAttrs)
 TEST_F(SSDDriverFixture, UpdateAttrs)
 {
     boost::asio::spawn(io, [this] (boost::asio::yield_context yield) {
-        ASSERT_EQ(0, cacheDriver->put(env->dpp, "testUpdateAttrs", bl, bl.length(), attrs, yield));
-        ASSERT_EQ(0, cacheDriver->update_attrs(env->dpp, "testUpdateAttrs", update_attrs, yield));
+        ASSERT_EQ(0, cacheDriver->put(env->dpp, "bucketid#version#testUpdateAttrs", bl, bl.length(), attrs, yield));
+        ASSERT_EQ(0, cacheDriver->update_attrs(env->dpp, "bucketid#version#testUpdateAttrs", update_attrs, yield));
         rgw::sal::Attrs get_attrs;
-        ASSERT_EQ(0, cacheDriver->get_attrs(env->dpp, "testUpdateAttrs", get_attrs, yield));
+        ASSERT_EQ(0, cacheDriver->get_attrs(env->dpp, "bucketid#version#testUpdateAttrs", get_attrs, yield));
         EXPECT_EQ(get_attrs.size(), 2);
         EXPECT_EQ(get_attrs["user.rgw.attrName"], updateAttrVal1);
         EXPECT_EQ(get_attrs["user.rgw.testAttr"], updateAttrVal2);
@@ -189,12 +198,12 @@ TEST_F(SSDDriverFixture, SetGetAttr)
 {
     boost::asio::spawn(io, [this] (boost::asio::yield_context yield) {
       rgw::sal::Attrs attrs = {};
-      ASSERT_EQ(0, cacheDriver->put(env->dpp, "testSetGetAttr", bl, bl.length(), attrs, yield));
+      ASSERT_EQ(0, cacheDriver->put(env->dpp, "bucketid#version#testSetGetAttr", bl, bl.length(), attrs, yield));
       std::string attr_name = "user.ssd.testattr";
       std::string attr_val = "testattrVal";
-      ASSERT_EQ(0, cacheDriver->set_attr(env->dpp, "testSetGetAttr", attr_name, attr_val, yield));
+      ASSERT_EQ(0, cacheDriver->set_attr(env->dpp, "bucketid#version#testSetGetAttr", attr_name, attr_val, yield));
       std::string attr_val_ret;
-      ASSERT_EQ(0, cacheDriver->get_attr(env->dpp, "testSetGetAttr", attr_name, attr_val_ret, yield));
+      ASSERT_EQ(0, cacheDriver->get_attr(env->dpp, "bucketid#version#testSetGetAttr", attr_name, attr_val_ret, yield));
       ASSERT_EQ(attr_val, attr_val_ret);
     }, rethrow);
 
@@ -205,17 +214,17 @@ TEST_F(SSDDriverFixture, DeleteAttr)
 {
     boost::asio::spawn(io, [this] (boost::asio::yield_context yield) {
       rgw::sal::Attrs attrs = {};
-      ASSERT_EQ(0, cacheDriver->put(env->dpp, "testDeleteAttr", bl, bl.length(), attrs, yield));
+      ASSERT_EQ(0, cacheDriver->put(env->dpp, "bucketid#version#testDeleteAttr", bl, bl.length(), attrs, yield));
       std::string attr_name = "user.ssd.testattr";
       std::string attr_val = "testattrVal";
-      ASSERT_EQ(0, cacheDriver->set_attr(env->dpp, "testDeleteAttr", attr_name, attr_val, yield));
+      ASSERT_EQ(0, cacheDriver->set_attr(env->dpp, "bucketid#version#testDeleteAttr", attr_name, attr_val, yield));
       std::string attr_val_ret;
-      ASSERT_EQ(0, cacheDriver->get_attr(env->dpp, "testDeleteAttr", attr_name, attr_val_ret, yield));
+      ASSERT_EQ(0, cacheDriver->get_attr(env->dpp, "bucketid#version#testDeleteAttr", attr_name, attr_val_ret, yield));
       ASSERT_EQ(attr_val, attr_val_ret);
 
       attr_val_ret.clear();
-      ASSERT_EQ(0, cacheDriver->delete_attr(env->dpp, "testDeleteAttr", attr_name));
-      ASSERT_EQ(ENODATA, cacheDriver->get_attr(env->dpp, "testDeleteAttr", attr_name, attr_val_ret, yield));
+      ASSERT_EQ(0, cacheDriver->delete_attr(env->dpp, "bucketid#version#testDeleteAttr", attr_name));
+      ASSERT_EQ(ENODATA, cacheDriver->get_attr(env->dpp, "bucketid#version#testDeleteAttr", attr_name, attr_val_ret, yield));
       ASSERT_EQ("", attr_val_ret);
     }, rethrow);
 
@@ -225,18 +234,18 @@ TEST_F(SSDDriverFixture, DeleteAttr)
 TEST_F(SSDDriverFixture, DeleteAttrs)
 {
     boost::asio::spawn(io, [this] (boost::asio::yield_context yield) {
-      ASSERT_EQ(0, cacheDriver->put(env->dpp, "testDeleteAttr", bl, bl.length(), attrs, yield));
+      ASSERT_EQ(0, cacheDriver->put(env->dpp, "bucketid#version#testDeleteAttr", bl, bl.length(), attrs, yield));
       rgw::sal::Attrs ret_attrs;
-      ASSERT_EQ(0, cacheDriver->get_attrs(env->dpp, "testDeleteAttr", ret_attrs, yield));
+      ASSERT_EQ(0, cacheDriver->get_attrs(env->dpp, "bucketid#version#testDeleteAttr", ret_attrs, yield));
       EXPECT_EQ(ret_attrs.size(), 1);
       for (auto& it : ret_attrs) {
         EXPECT_EQ(it.first, "user.rgw.attrName");
         EXPECT_EQ(it.second, attrVal);
       }
 
-      ASSERT_EQ(0, cacheDriver->delete_attrs(env->dpp, "testDeleteAttr", del_attrs, yield));
+      ASSERT_EQ(0, cacheDriver->delete_attrs(env->dpp, "bucketid#version#testDeleteAttr", del_attrs, yield));
       ret_attrs.clear();
-      ASSERT_EQ(0, cacheDriver->get_attrs(env->dpp, "testDeleteAttr", del_attrs, yield));
+      ASSERT_EQ(0, cacheDriver->get_attrs(env->dpp, "bucketid#version#testDeleteAttr", del_attrs, yield));
       EXPECT_EQ(ret_attrs.size(), 0);
     }, rethrow);
 
@@ -247,14 +256,14 @@ TEST_F(SSDDriverFixture, DeleteData)
 {
     boost::asio::spawn(io, [this] (boost::asio::yield_context yield) {
         rgw::sal::Attrs attrs = {};
-        ASSERT_EQ(0, cacheDriver->put(env->dpp, "testDeleteData", bl, bl.length(), attrs, yield));
+        ASSERT_EQ(0, cacheDriver->put(env->dpp, "bucketid#version#testDeleteData", bl, bl.length(), attrs, yield));
         bufferlist ret;
         rgw::sal::Attrs get_attrs;
-        ASSERT_EQ(0, cacheDriver->get(env->dpp, "testDeleteData", 0, bl.length(), ret, get_attrs, yield));
+        ASSERT_EQ(0, cacheDriver->get(env->dpp, "bucketid#version#testDeleteData", 0, bl.length(), ret, get_attrs, yield));
         EXPECT_EQ(ret, bl);
         EXPECT_EQ(get_attrs.size(), 0);
-        ASSERT_EQ(0, cacheDriver->delete_data(env->dpp, "testDeleteData", yield));
-        ASSERT_EQ(-ENOENT, cacheDriver->get(env->dpp, "testDeleteData", 0, bl.length(), ret, get_attrs, yield));
+        ASSERT_EQ(0, cacheDriver->delete_data(env->dpp, "bucketid#version#testDeleteData", yield));
+        ASSERT_EQ(-ENOENT, cacheDriver->get(env->dpp, "bucketid#version#testDeleteData", 0, bl.length(), ret, get_attrs, yield));
     }, rethrow);
 
     io.run();
@@ -266,8 +275,10 @@ TEST_F(SSDDriverFixture, PutAsync)
         rgw::sal::Attrs attrs = {};
         const uint64_t window_size = env->cct->_conf->rgw_put_obj_min_window_size;
         std::unique_ptr<rgw::Aio> aio = rgw::make_throttle(window_size, yield);
-        auto results = cacheDriver->put_async(env->dpp, yield, aio.get(), "testPutAsync", bl, bl.length(), attrs, bl.length(), 0);
+        auto results = cacheDriver->put_async(env->dpp, yield, aio.get(), "bucketid#version#testPutAsync", bl, bl.length(), attrs, bl.length(), 0);
+        auto r = flush(env->dpp, std::move(results), yield);
         drain(env->dpp, aio.get());
+        EXPECT_EQ(r, 0);
     }, rethrow);
 
     io.run();