diff options
author | pasko@google.com <pasko@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-23 17:33:04 +0000 |
---|---|---|
committer | pasko@google.com <pasko@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-23 17:33:04 +0000 |
commit | 1aae0c60a9f05fe360ff5331f81b422952a6d680 (patch) | |
tree | 43f35447492755a599953c14dd8685d6ced34013 /net/disk_cache | |
parent | 2e61a4b22558048a6b07a4d18a7c4e9fa8af7792 (diff) | |
download | chromium_src-1aae0c60a9f05fe360ff5331f81b422952a6d680.zip chromium_src-1aae0c60a9f05fe360ff5331f81b422952a6d680.tar.gz chromium_src-1aae0c60a9f05fe360ff5331f81b422952a6d680.tar.bz2 |
Disallow the Simple Cache to coexist with the Blockfile Cache.
BUG=229437
BUG=230332
Review URL: https://chromiumcodereview.appspot.com/14417007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195830 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/disk_cache')
-rw-r--r-- | net/disk_cache/backend_unittest.cc | 63 | ||||
-rw-r--r-- | net/disk_cache/simple/simple_backend_impl.cc | 75 | ||||
-rw-r--r-- | net/disk_cache/simple/simple_backend_impl.h | 2 | ||||
-rw-r--r-- | net/disk_cache/simple/simple_index.cc | 2 |
4 files changed, 135 insertions, 7 deletions
diff --git a/net/disk_cache/backend_unittest.cc b/net/disk_cache/backend_unittest.cc index bdfac91..f5b112a 100644 --- a/net/disk_cache/backend_unittest.cc +++ b/net/disk_cache/backend_unittest.cc @@ -21,6 +21,7 @@ #include "net/disk_cache/histogram_macros.h" #include "net/disk_cache/mapped_file.h" #include "net/disk_cache/mem_backend_impl.h" +#include "net/disk_cache/simple/simple_backend_impl.h" #include "net/disk_cache/simple/simple_entry_format.h" #include "net/disk_cache/simple/simple_util.h" #include "net/disk_cache/tracing_cache_backend.h" @@ -2919,4 +2920,66 @@ TEST_F(DiskCacheBackendTest, DISABLED_SimpleCacheSetSize) { BackendSetSize(); } +// Tests that the Simple Cache Backend fails to initialize with non-matching +// file structure on disk. +TEST_F(DiskCacheBackendTest, SimpleCacheOverBlockfileCache) { + // Create a cache structure with the |BackendImpl|. + InitCache(); + disk_cache::Entry* entry; + const int kSize = 50; + scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); + CacheTestFillBuffer(buffer->data(), kSize, false); + ASSERT_EQ(net::OK, CreateEntry("key", &entry)); + ASSERT_EQ(0, WriteData(entry, 0, 0, buffer, 0, false)); + entry->Close(); + delete cache_; + cache_ = NULL; + + // Check that the |SimpleBackendImpl| does not favor this structure. + base::Thread cache_thread("CacheThread"); + ASSERT_TRUE(cache_thread.StartWithOptions( + base::Thread::Options(MessageLoop::TYPE_IO, 0))); + disk_cache::SimpleBackendImpl* simple_cache = + new disk_cache::SimpleBackendImpl(cache_path_, 0, net::DISK_CACHE, + cache_thread.message_loop_proxy(), + NULL); + net::TestCompletionCallback cb; + int rv = simple_cache->Init(cb.callback()); + EXPECT_NE(net::OK, cb.GetResult(rv)); + delete simple_cache; + DisableIntegrityCheck(); +} + +// Tests that the |BackendImpl| refuses to initialize on top of the files +// generated by the Simple Cache Backend. +TEST_F(DiskCacheBackendTest, BlockfileCacheOverSimpleCache) { + // Create a cache structure with the |SimpleBackendImpl|. + SetSimpleCacheMode(); + InitCache(); + disk_cache::Entry* entry; + const int kSize = 50; + scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); + CacheTestFillBuffer(buffer->data(), kSize, false); + ASSERT_EQ(net::OK, CreateEntry("key", &entry)); + ASSERT_EQ(0, WriteData(entry, 0, 0, buffer, 0, false)); + entry->Close(); + delete cache_; + cache_ = NULL; + + // Check that the |BackendImpl| does not favor this structure. + base::Thread cache_thread("CacheThread"); + ASSERT_TRUE(cache_thread.StartWithOptions( + base::Thread::Options(MessageLoop::TYPE_IO, 0))); + disk_cache::BackendImpl* cache = + new disk_cache::BackendImpl(cache_path_, + base::MessageLoopProxy::current(), + NULL); + cache->SetUnitTestMode(); + net::TestCompletionCallback cb; + int rv = cache->Init(cb.callback()); + EXPECT_NE(net::OK, cb.GetResult(rv)); + delete cache; + DisableIntegrityCheck(); +} + #endif // !defined(OS_WIN) diff --git a/net/disk_cache/simple/simple_backend_impl.cc b/net/disk_cache/simple/simple_backend_impl.cc index 1d06109..9d4b43f 100644 --- a/net/disk_cache/simple/simple_backend_impl.cc +++ b/net/disk_cache/simple/simple_backend_impl.cc @@ -11,6 +11,7 @@ #include "base/message_loop_proxy.h" #include "base/threading/worker_pool.h" #include "net/base/net_errors.h" +#include "net/disk_cache/simple/simple_entry_format.h" #include "net/disk_cache/simple/simple_entry_impl.h" #include "net/disk_cache/simple/simple_index.h" #include "net/disk_cache/simple/simple_synchronous_entry.h" @@ -35,6 +36,70 @@ void DeleteBackendImpl(disk_cache::Backend** backend, callback.Run(result); } +// Detects if the files in the cache directory match the current disk cache +// backend type and version. If the directory contains no cache, occupies it +// with the fresh structure. +// +// There is a convention among disk cache backends: looking at the magic in the +// file "index" it should be sufficient to determine if the cache belongs to the +// currently running backend. The Simple Backend stores its index in the file +// "the-real-index" (see simple_index.cc) and the file "index" only signifies +// presence of the implementation's magic and version. There are two reasons for +// that: +// 1. Absence of the index is itself not a fatal error in the Simple Backend +// 2. The Simple Backend has pickled file format for the index making it hacky +// to have the magic in the right place. +bool FileStructureConsistent(const base::FilePath& path) { + if (!file_util::PathExists(path) && !file_util::CreateDirectory(path)) { + LOG(ERROR) << "Failed to create directory: " << path.LossyDisplayName(); + return false; + } + const base::FilePath fake_index = path.AppendASCII("index"); + base::PlatformFileError error; + base::PlatformFile fake_index_file = base::CreatePlatformFile( + fake_index, + base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, + NULL, + &error); + if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) { + base::PlatformFile file = base::CreatePlatformFile( + fake_index, + base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE, + NULL, &error); + disk_cache::SimpleFileHeader file_contents; + file_contents.initial_magic_number = disk_cache::kSimpleInitialMagicNumber; + file_contents.version = disk_cache::kSimpleVersion; + int bytes_written = base::WritePlatformFile( + file, 0, reinterpret_cast<char*>(&file_contents), + sizeof(file_contents)); + if (!base::ClosePlatformFile(file) || + bytes_written != sizeof(file_contents)) { + LOG(ERROR) << "Failed to write cache structure file: " + << path.LossyDisplayName(); + return false; + } + return true; + } else if (error != base::PLATFORM_FILE_OK) { + LOG(ERROR) << "Could not open cache structure file: " + << path.LossyDisplayName(); + return false; + } else { + disk_cache::SimpleFileHeader file_header; + int bytes_read = base::ReadPlatformFile( + fake_index_file, 0, reinterpret_cast<char*>(&file_header), + sizeof(file_header)); + if (!base::ClosePlatformFile(fake_index_file) || + bytes_read != sizeof(file_header) || + file_header.initial_magic_number != + disk_cache::kSimpleInitialMagicNumber || + file_header.version != disk_cache::kSimpleVersion) { + LOG(ERROR) << "File structure does not match the disk cache backend."; + return false; + } + return true; + } +} + } // namespace namespace disk_cache { @@ -62,7 +127,7 @@ int SimpleBackendImpl::Init(const CompletionCallback& completion_callback) { base::Unretained(this), completion_callback); cache_thread_->PostTask(FROM_HERE, - base::Bind(&SimpleBackendImpl::CreateDirectory, + base::Bind(&SimpleBackendImpl::ProvideDirectory, MessageLoopProxy::current(), // io_thread path_, initialize_index_callback)); @@ -166,16 +231,16 @@ void SimpleBackendImpl::InitializeIndex( } // static -void SimpleBackendImpl::CreateDirectory( +void SimpleBackendImpl::ProvideDirectory( SingleThreadTaskRunner* io_thread, const base::FilePath& path, const InitializeIndexCallback& initialize_index_callback) { int rv = net::OK; - if (!file_util::PathExists(path) && !file_util::CreateDirectory(path)) { - LOG(ERROR) << "Simple Cache Backend: failed to create: " << path.value(); + if (!FileStructureConsistent(path)) { + LOG(ERROR) << "Simple Cache Backend: wrong file structure on disk: " + << path.LossyDisplayName(); rv = net::ERR_FAILED; } - io_thread->PostTask(FROM_HERE, base::Bind(initialize_index_callback, rv)); } diff --git a/net/disk_cache/simple/simple_backend_impl.h b/net/disk_cache/simple/simple_backend_impl.h index 9d18c6d..6b7ac17 100644 --- a/net/disk_cache/simple/simple_backend_impl.h +++ b/net/disk_cache/simple/simple_backend_impl.h @@ -86,7 +86,7 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend, // Try to create the directory if it doesn't exist. // Must run on Cache Thread. - static void CreateDirectory( + static void ProvideDirectory( base::SingleThreadTaskRunner* io_thread, const base::FilePath& path, const InitializeIndexCallback& initialize_index_callback); diff --git a/net/disk_cache/simple/simple_index.cc b/net/disk_cache/simple/simple_index.cc index 9f566df..583ee84 100644 --- a/net/disk_cache/simple/simple_index.cc +++ b/net/disk_cache/simple/simple_index.cc @@ -124,7 +124,7 @@ SimpleIndex::SimpleIndex( low_watermark_(0), eviction_in_progress_(false), initialized_(false), - index_filename_(path.AppendASCII("simple-index")), + index_filename_(path.AppendASCII("the-real-index")), cache_thread_(cache_thread), io_thread_(io_thread) { } |