From d9fac9c655acec29a6662bc0aafdaaccbd435e1a Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 10 Jun 2014 23:06:12 -0700 Subject: [PATCH] rgw: chain to multiple cache entries in one call This ensures that chained cache entries that depend on more than one raw cache entry (bucket info cache depends on both the bucket entry point and on the bucket info object), are chained and created atomically. Signed-off-by: Yehuda Sadeh --- src/rgw/rgw_cache.cc | 43 +++++++++++++++++++++++++++++++------------ src/rgw/rgw_cache.h | 6 +++--- src/rgw/rgw_rados.cc | 9 +++++++-- src/rgw/rgw_rados.h | 6 +++--- src/rgw/rgw_user.cc | 5 ++++- 5 files changed, 48 insertions(+), 21 deletions(-) diff --git a/src/rgw/rgw_cache.cc b/src/rgw/rgw_cache.cc index 9eb4a4bb765a..66ee123f41b0 100644 --- a/src/rgw/rgw_cache.cc +++ b/src/rgw/rgw_cache.cc @@ -57,26 +57,45 @@ int ObjectCache::get(string& name, ObjectCacheInfo& info, uint32_t mask, rgw_cac return 0; } -bool ObjectCache::chain_cache_entry(rgw_cache_entry_info& cache_info, RGWChainedCache::Entry *chained_entry) +bool ObjectCache::chain_cache_entry(list& cache_info_entries, RGWChainedCache::Entry *chained_entry) { RWLock::WLocker l(lock); - ldout(cct, 10) << "chain_cache_entry: cache_locator=" << cache_info.cache_locator << dendl; - map::iterator iter = cache_map.find(cache_info.cache_locator); - if (iter == cache_map.end()) { - ldout(cct, 20) << "chain_cache_entry: couldn't find cachce locator" << dendl; - return false; - } + list::iterator citer; - ObjectCacheEntry& entry = iter->second; - if (entry.gen != cache_info.gen) { - ldout(cct, 20) << "chain_cache_entry: entry.gen (" << entry.gen << ") != cache_info.gen (" << cache_info.gen << ")" << dendl; - return false; + list cache_entry_list; + + /* first verify that all entries are still valid */ + for (citer = cache_info_entries.begin(); citer != cache_info_entries.end(); ++citer) { + rgw_cache_entry_info *cache_info = *citer; + + ldout(cct, 10) << "chain_cache_entry: cache_locator=" << cache_info->cache_locator << dendl; + map::iterator iter = cache_map.find(cache_info->cache_locator); + if (iter == cache_map.end()) { + ldout(cct, 20) << "chain_cache_entry: couldn't find cachce locator" << dendl; + return false; + } + + ObjectCacheEntry *entry = &iter->second; + + if (entry->gen != cache_info->gen) { + ldout(cct, 20) << "chain_cache_entry: entry.gen (" << entry->gen << ") != cache_info.gen (" << cache_info->gen << ")" << dendl; + return false; + } + + cache_entry_list.push_back(entry); } + chained_entry->cache->chain_cb(chained_entry->key, chained_entry->data); - entry.chained_entries.push_back(make_pair(chained_entry->cache, chained_entry->key)); + list::iterator liter; + + for (liter = cache_entry_list.begin(); liter != cache_entry_list.end(); ++liter) { + ObjectCacheEntry *entry = *liter; + + entry->chained_entries.push_back(make_pair(chained_entry->cache, chained_entry->key)); + } return true; } diff --git a/src/rgw/rgw_cache.h b/src/rgw/rgw_cache.h index e5f349961b1c..f8120e20e99e 100644 --- a/src/rgw/rgw_cache.h +++ b/src/rgw/rgw_cache.h @@ -154,7 +154,7 @@ public: cct = _cct; lru_window = cct->_conf->rgw_cache_lru_size / 2; } - bool chain_cache_entry(rgw_cache_entry_info& cache_info, RGWChainedCache::Entry *chained_entry); + bool chain_cache_entry(list& cache_info_entries, RGWChainedCache::Entry *chained_entry); }; template @@ -224,8 +224,8 @@ public: int delete_obj_impl(void *ctx, const string& bucket_owner, rgw_obj& obj, RGWObjVersionTracker *objv_tracker); - bool chain_cache_entry(rgw_cache_entry_info& cache_info, RGWChainedCache::Entry *chained_entry) { - return cache.chain_cache_entry(cache_info, chained_entry); + bool chain_cache_entry(list& cache_info_entries, RGWChainedCache::Entry *chained_entry) { + return cache.chain_cache_entry(cache_info_entries, chained_entry); } }; diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 468c932532db..17e60ea614ae 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -5522,9 +5522,14 @@ int RGWRados::get_bucket_info(void *ctx, const string& bucket_name, RGWBucketInf if (pattrs) *pattrs = e.attrs; + list cache_info_entries; + cache_info_entries.push_back(&entry_cache_info); + cache_info_entries.push_back(&cache_info); + + /* chain to both bucket entry point and bucket instance */ - if (binfo_cache.put(this, bucket_name, &e, entry_cache_info)) { - binfo_cache.put(this, bucket_name, &e, cache_info); + if (!binfo_cache.put(this, bucket_name, &e, cache_info_entries)) { + ldout(cct, 20) << "couldn't put binfo cache entry, might have raced with data changes" << dendl; } return 0; diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 04128e0fd836..046b515f806e 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1667,7 +1667,7 @@ public: virtual void finish_get_obj(void **handle); - virtual bool chain_cache_entry(rgw_cache_entry_info& cache_info, RGWChainedCache::Entry *chained_entry) { return false; } + virtual bool chain_cache_entry(list& cache_info_entries, RGWChainedCache::Entry *chained_entry) { return false; } int iterate_obj(void *ctx, rgw_obj& obj, off_t ofs, off_t end, @@ -1957,11 +1957,11 @@ public: return true; } - bool put(RGWRados *store, const string& key, T *entry, rgw_cache_entry_info& cache_info) { + bool put(RGWRados *store, const string& key, T *entry, list& cache_info_entries) { Entry chain_entry(this, key, entry); /* we need the store cache to call us under its lock to maintain lock ordering */ - return store->chain_cache_entry(cache_info, &chain_entry); + return store->chain_cache_entry(cache_info_entries, &chain_entry); } void chain_cb(const string& key, void *data) { diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc index c1bf275828b5..d391f44713ea 100644 --- a/src/rgw/rgw_user.cc +++ b/src/rgw/rgw_user.cc @@ -235,7 +235,10 @@ int rgw_get_user_info_from_index(RGWRados *store, string& key, rgw_bucket& bucke return -EIO; } - uinfo_cache.put(store, key, &e, cache_info); + list cache_info_entries; + cache_info_entries.push_back(&cache_info); + + uinfo_cache.put(store, key, &e, cache_info_entries); info = e.info; if (objv_tracker) -- 2.47.3