summaryrefslogtreecommitdiffstats
path: root/net/disk_cache
diff options
context:
space:
mode:
authorpasko@google.com <pasko@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-23 17:33:04 +0000
committerpasko@google.com <pasko@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-23 17:33:04 +0000
commit1aae0c60a9f05fe360ff5331f81b422952a6d680 (patch)
tree43f35447492755a599953c14dd8685d6ced34013 /net/disk_cache
parent2e61a4b22558048a6b07a4d18a7c4e9fa8af7792 (diff)
downloadchromium_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.cc63
-rw-r--r--net/disk_cache/simple/simple_backend_impl.cc75
-rw-r--r--net/disk_cache/simple/simple_backend_impl.h2
-rw-r--r--net/disk_cache/simple/simple_index.cc2
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) {
}