15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifndef CHROME_BROWSER_CHROMEOS_DRIVE_FILE_CACHE_H_ 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define CHROME_BROWSER_CHROMEOS_DRIVE_FILE_CACHE_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <set> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_errors.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/drive/resource_metadata_storage.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ScopedClosureRunner; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SequencedTaskRunner; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace drive { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)namespace internal { 25b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Interface class used for getting the free disk space. Tests can inject an 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// implementation that reports fake free disk space. 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FreeDiskSpaceGetterInterface { 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~FreeDiskSpaceGetterInterface() {} 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual int64 AmountOfFreeDiskSpace() = 0; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// FileCache is used to maintain cache states of FileSystem. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All non-static public member functions, unless mentioned otherwise (see 37b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// GetCacheFilePath() for example), should be run with |blocking_task_runner|. 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class FileCache { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enum defining type of file operation e.g. copy or move, etc. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum FileOperationType { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE_OPERATION_MOVE = 0, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE_OPERATION_COPY, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // |cache_file_directory| stores cached files. 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // |blocking_task_runner| indicates the blocking worker pool for cache 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // operations. All operations on this FileCache must be run on this runner. 50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Must not be null. 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |free_disk_space_getter| is used to inject a custom free disk space 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // getter for testing. NULL must be passed for production code. 54b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // 55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Must be called on the UI thread. 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FileCache(ResourceMetadataStorage* storage, 577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const base::FilePath& cache_file_directory, 58b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::SequencedTaskRunner* blocking_task_runner, 59b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) FreeDiskSpaceGetterInterface* free_disk_space_getter); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the given path is under drive cache directory, i.e. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // <user_profile_dir>/GCache/v1 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Can be called on any thread. 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool IsUnderFileCacheDirectory(const base::FilePath& path) const; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Frees up disk space to store a file with |num_bytes| size content, while 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // keeping cryptohome::kMinFreeSpaceInBytes bytes on the disk, if needed. 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Returns true if we successfully manage to have enough space, otherwise 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // false. 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool FreeDiskSpaceIfNeededFor(int64 num_bytes); 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 73424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Checks if file corresponding to |id| exists in cache, and returns 7458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch // FILE_ERROR_OK with |cache_file_path| storing the path to the file. 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // |cache_file_path| must not be null. 76424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FileError GetFile(const std::string& id, base::FilePath* cache_file_path); 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Stores |source_path| as a cache of the remote content of the file 79424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // with |id| and |md5|. 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Pass an empty string as MD5 to mark the entry as dirty. 81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FileError Store(const std::string& id, 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& md5, 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::FilePath& source_path, 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FileOperationType file_operation_type); 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Pins the specified entry. 87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FileError Pin(const std::string& id); 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Unpins the specified entry. 90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FileError Unpin(const std::string& id); 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 92424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Sets the state of the cache entry corresponding to |id| as mounted. 93424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FileError MarkAsMounted(const std::string& id, 94424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::FilePath* cache_file_path); 95424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Sets the state of the cache entry corresponding to file_path as unmounted. 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FileError MarkAsUnmounted(const base::FilePath& file_path); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Opens the cache file corresponding to |id| for write. |file_closer| should 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // be kept alive until writing finishes. 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This method must be called before writing to cache files. 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FileError OpenForWrite(const std::string& id, 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ScopedClosureRunner>* file_closer); 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Returns true if the cache file corresponding to |id| is write-opened. 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool IsOpenedForWrite(const std::string& id); 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Calculates MD5 of the cache file and updates the stored value. 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FileError UpdateMd5(const std::string& id); 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Clears dirty state of the specified entry. 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FileError ClearDirty(const std::string& id); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Removes the specified cache entry and delete cache files if available. 115424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FileError Remove(const std::string& id); 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Removes all the files in the cache directory. 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool ClearAll(); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Initializes the cache. Returns true on success. 1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool Initialize(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Destroys this cache. This function posts a task to the blocking task 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // runner to safely delete the object. 125b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Must be called on the UI thread. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Destroy(); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Moves files in the cache directory which are not managed by FileCache to 1290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // |dest_directory|. 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |recovered_cache_info| should contain cache info recovered from the trashed 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // metadata DB. It is used to ignore non-dirty files. 1320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) bool RecoverFilesFromCacheDirectory( 1330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const base::FilePath& dest_directory, 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const ResourceMetadataStorage::RecoveredCacheInfoMap& 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) recovered_cache_info); 1360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) friend class FileCacheTest; 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 140b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ~FileCache(); 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Returns absolute path of the file if it were cached or to be cached. 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Can be called on any thread. 145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::FilePath GetCacheFilePath(const std::string& id) const; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checks whether the current thread is on the right sequenced worker pool 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with the right sequence ID. If not, DCHECK will fail. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AssertOnSequencedWorkerPool(); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Destroys the cache on the blocking pool. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DestroyOnBlockingPool(); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns true if we have sufficient space to store the given number of 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // bytes, while keeping cryptohome::kMinFreeSpaceInBytes bytes on the disk. 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool HasEnoughSpaceFor(int64 num_bytes, const base::FilePath& path); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Renames cache files from old "prefix:id.md5" format to the new format. 1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // TODO(hashimoto): Remove this method at some point. 1608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool RenameCacheFilesToNewFormat(); 1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This method must be called after writing to a cache file. 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Used to implement OpenForWrite(). 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void CloseForWrite(const std::string& id); 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const base::FilePath cache_file_directory_; 1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ResourceMetadataStorage* storage_; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FreeDiskSpaceGetterInterface* free_disk_space_getter_; // Not owned. 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // IDs of files being write-opened. 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::map<std::string, int> write_opened_files_; 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // IDs of files marked mounted. 1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::set<std::string> mounted_files_; 1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: This should remain the last member so it'll be destroyed and 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // invalidate its weak pointers before any other members are destroyed. 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This object should be accessed only on |blocking_task_runner_|. 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WeakPtrFactory<FileCache> weak_ptr_factory_; 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FileCache); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 187b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} // namespace internal 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace drive 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif // CHROME_BROWSER_CHROMEOS_DRIVE_FILE_CACHE_H_ 191