1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/resource_metadata.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/guid.h" 85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/rand_util.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 105e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/sys_info.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/drive.pb.h" 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/drive/file_cache.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system_util.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/resource_metadata_storage.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using content::BrowserThread; 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace drive { 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace internal { 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Returns true if enough disk space is available for DB operation. 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TODO(hashimoto): Merge this with FileCache's FreeDiskSpaceGetterInterface. 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool EnoughDiskSpaceIsAvailableForDBOperation(const base::FilePath& path) { 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int64 kRequiredDiskSpaceInMB = 128; // 128 MB seems to be large enough. 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return base::SysInfo::AmountOfFreeDiskSpace(path) >= 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kRequiredDiskSpaceInMB * (1 << 20); 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Returns a file name with a uniquifier appended. (e.g. "File (1).txt") 335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustd::string GetUniquifiedName(const std::string& name, int uniquifier) { 345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::FilePath name_path = base::FilePath::FromUTF8Unsafe(name); 355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu name_path = name_path.InsertBeforeExtension( 365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::StringPrintf(" (%d)", uniquifier)); 375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return name_path.AsUTF8Unsafe(); 385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Returns true when there is no entry with the specified name under the parent 415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// other than the specified entry. 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError EntryCanUseName(ResourceMetadataStorage* storage, 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& parent_local_id, 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& local_id, 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& base_name, 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool* result) { 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string existing_entry_id; 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FileError error = storage->GetChild(parent_local_id, base_name, 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &existing_entry_id); 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error == FILE_ERROR_OK) 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *result = existing_entry_id == local_id; 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) else if (error == FILE_ERROR_NOT_FOUND) 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *result = true; 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) else 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return FILE_ERROR_OK; 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Returns true when the ID is used by an immutable entry. 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool IsImmutableEntry(const std::string& id) { 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return id == util::kDriveGrandRootLocalId || 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) id == util::kDriveOtherDirLocalId || 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) id == util::kDriveTrashDirLocalId; 645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} // namespace 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ResourceMetadata::ResourceMetadata( 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ResourceMetadataStorage* storage, 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FileCache* cache, 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : blocking_task_runner_(blocking_task_runner), 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) storage_(storage), 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cache_(cache) { 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)FileError ResourceMetadata::Initialize() { 797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return SetUpDefaultEntries(); 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ResourceMetadata::Destroy() { 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocking_task_runner_->PostTask( 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&ResourceMetadata::DestroyOnBlockingPool, 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 92b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)FileError ResourceMetadata::Reset() { 93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path())) 96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return FILE_ERROR_NO_LOCAL_SPACE; 97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FileError error = storage_->SetLargestChangestamp(0); 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Remove all root entries. 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<Iterator> it = GetIterator(); 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (; !it->IsAtEnd(); it->Advance()) { 105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (it->GetValue().parent_local_id().empty()) { 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = RemoveEntryRecursively(it->GetID()); 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (it->HasError()) 112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return FILE_ERROR_FAILED; 113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return SetUpDefaultEntries(); 115b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 116b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ResourceMetadata::~ResourceMetadata() { 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError ResourceMetadata::SetUpDefaultEntries() { 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Initialize "/drive". 1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ResourceEntry entry; 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FileError error = storage_->GetEntry(util::kDriveGrandRootLocalId, &entry); 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error == FILE_ERROR_NOT_FOUND) { 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry root; 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root.mutable_file_info()->set_is_directory(true); 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) root.set_local_id(util::kDriveGrandRootLocalId); 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root.set_title(util::kDriveGrandRootDirName); 1325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu root.set_base_name(util::kDriveGrandRootDirName); 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = storage_->PutEntry(root); 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (error == FILE_ERROR_OK) { 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!entry.resource_id().empty()) { 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Old implementations used kDriveGrandRootLocalId as a resource ID. 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) entry.clear_resource_id(); 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = storage_->PutEntry(entry); 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Initialize "/drive/other". 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = storage_->GetEntry(util::kDriveOtherDirLocalId, &entry); 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error == FILE_ERROR_NOT_FOUND) { 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ResourceEntry other_dir; 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) other_dir.mutable_file_info()->set_is_directory(true); 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) other_dir.set_local_id(util::kDriveOtherDirLocalId); 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) other_dir.set_parent_local_id(util::kDriveGrandRootLocalId); 1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) other_dir.set_title(util::kDriveOtherDirName); 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = PutEntryUnderDirectory(other_dir); 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (error == FILE_ERROR_OK) { 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!entry.resource_id().empty()) { 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Old implementations used kDriveOtherDirLocalId as a resource ID. 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) entry.clear_resource_id(); 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = storage_->PutEntry(entry); 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Initialize "drive/trash". 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = storage_->GetEntry(util::kDriveTrashDirLocalId, &entry); 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error == FILE_ERROR_NOT_FOUND) { 174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ResourceEntry trash_dir; 175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) trash_dir.mutable_file_info()->set_is_directory(true); 176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) trash_dir.set_local_id(util::kDriveTrashDirLocalId); 177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) trash_dir.set_parent_local_id(util::kDriveGrandRootLocalId); 178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) trash_dir.set_title(util::kDriveTrashDirName); 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = PutEntryUnderDirectory(trash_dir); 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (error != FILE_ERROR_OK) { 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Initialize "drive/root". 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string child_id; 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = storage_->GetChild( 189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) util::kDriveGrandRootLocalId, util::kDriveMyDriveRootDirName, &child_id); 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error == FILE_ERROR_NOT_FOUND) { 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ResourceEntry mydrive; 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mydrive.mutable_file_info()->set_is_directory(true); 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mydrive.set_parent_local_id(util::kDriveGrandRootLocalId); 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mydrive.set_title(util::kDriveMyDriveRootDirName); 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string local_id; 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = AddEntry(mydrive, &local_id); 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (error != FILE_ERROR_OK) { 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return FILE_ERROR_OK; 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ResourceMetadata::DestroyOnBlockingPool() { 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delete this; 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError ResourceMetadata::GetLargestChangestamp(int64* out_value) { 212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return storage_->GetLargestChangestamp(out_value); 214b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 215b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)FileError ResourceMetadata::SetLargestChangestamp(int64 value) { 217b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 218b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path())) 220a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return FILE_ERROR_NO_LOCAL_SPACE; 221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return storage_->SetLargestChangestamp(value); 223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 224b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)FileError ResourceMetadata::AddEntry(const ResourceEntry& entry, 226424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::string* out_id) { 227b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 2288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(entry.local_id().empty()); 229b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path())) 231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return FILE_ERROR_NO_LOCAL_SPACE; 232b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ResourceEntry parent; 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FileError error = storage_->GetEntry(entry.parent_local_id(), &parent); 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!parent.file_info().is_directory()) 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return FILE_ERROR_NOT_A_DIRECTORY; 239b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Multiple entries with the same resource ID should not be present. 2418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::string local_id; 2428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ResourceEntry existing_entry; 243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!entry.resource_id().empty()) { 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = storage_->GetIdByResourceId(entry.resource_id(), &local_id); 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error == FILE_ERROR_OK) 246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = storage_->GetEntry(local_id, &existing_entry); 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error == FILE_ERROR_OK) 249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return FILE_ERROR_EXISTS; 250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) else if (error != FILE_ERROR_NOT_FOUND) 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Generate unique local ID when needed. 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // We don't check for ID collisions as its probability is extremely low. 256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (local_id.empty()) 2578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) local_id = base::GenerateGUID(); 2588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 25968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ResourceEntry new_entry(entry); 26068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) new_entry.set_local_id(local_id); 2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = PutEntryUnderDirectory(new_entry); 263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 265b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) *out_id = local_id; 267b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_OK; 268b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 269b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FileError ResourceMetadata::RemoveEntry(const std::string& id) { 271b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 272b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path())) 274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return FILE_ERROR_NO_LOCAL_SPACE; 275b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Disallow deletion of default entries. 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (IsImmutableEntry(id)) 278b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_ACCESS_DENIED; 279b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ResourceEntry entry; 281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FileError error = storage_->GetEntry(id, &entry); 282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 284b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return RemoveEntryRecursively(id); 286b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 287b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FileError ResourceMetadata::GetResourceEntryById(const std::string& id, 2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ResourceEntry* out_entry) { 290b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!id.empty()); 292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(out_entry); 293b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return storage_->GetEntry(id, out_entry); 295b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 297a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)FileError ResourceMetadata::GetResourceEntryByPath(const base::FilePath& path, 298a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) ResourceEntry* out_entry) { 299b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 300b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(out_entry); 301b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 3023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string id; 3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FileError error = GetIdByPath(path, &id); 3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (error != FILE_ERROR_OK) 3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return error; 3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return GetResourceEntryById(id, out_entry); 308b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)FileError ResourceMetadata::ReadDirectoryByPath( 311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::FilePath& path, 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ResourceEntryVector* out_entries) { 313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(out_entries); 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string id; 3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FileError error = GetIdByPath(path, &id); 3183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (error != FILE_ERROR_OK) 3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return error; 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ReadDirectoryById(id, out_entries); 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FileError ResourceMetadata::ReadDirectoryById( 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& id, 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ResourceEntryVector* out_entries) { 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(out_entries); 3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ResourceEntry entry; 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FileError error = GetResourceEntryById(id, &entry); 3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (error != FILE_ERROR_OK) 3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return error; 333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!entry.file_info().is_directory()) 335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return FILE_ERROR_NOT_A_DIRECTORY; 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<std::string> children; 338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = storage_->GetChildren(id, &children); 339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ResourceEntryVector entries(children.size()); 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < children.size(); ++i) { 344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = storage_->GetEntry(children[i], &entries[i]); 345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) out_entries->swap(entries); 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return FILE_ERROR_OK; 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 35268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)FileError ResourceMetadata::RefreshEntry(const ResourceEntry& entry) { 353b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 354b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path())) 356a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return FILE_ERROR_NO_LOCAL_SPACE; 357b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ResourceEntry old_entry; 359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FileError error = storage_->GetEntry(entry.local_id(), &old_entry); 360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 362b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (IsImmutableEntry(entry.local_id()) || 3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) old_entry.file_info().is_directory() != // Reject incompatible input. 365b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) entry.file_info().is_directory()) 366b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return FILE_ERROR_INVALID_OPERATION; 367b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!entry.resource_id().empty()) { 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Multiple entries cannot share the same resource ID. 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string local_id; 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FileError error = GetIdByResourceId(entry.resource_id(), &local_id); 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (error) { 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case FILE_ERROR_OK: 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (local_id != entry.local_id()) 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return FILE_ERROR_INVALID_OPERATION; 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case FILE_ERROR_NOT_FOUND: 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) default: 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return error; 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Make sure that the new parent exists and it is a directory. 3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ResourceEntry new_parent; 388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = storage_->GetEntry(entry.parent_local_id(), &new_parent); 389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 391b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 3923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!new_parent.file_info().is_directory()) 3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return FILE_ERROR_NOT_A_DIRECTORY; 3943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Do not overwrite cache states. 396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Cache state should be changed via FileCache. 397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ResourceEntry updated_entry(entry); 398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (old_entry.file_specific_info().has_cache_state()) { 399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *updated_entry.mutable_file_specific_info()->mutable_cache_state() = 400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) old_entry.file_specific_info().cache_state(); 401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (updated_entry.file_specific_info().has_cache_state()) { 402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) updated_entry.mutable_file_specific_info()->clear_cache_state(); 403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 404b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Remove from the old parent and add it to the new parent with the new data. 405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return PutEntryUnderDirectory(updated_entry); 406b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 407b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError ResourceMetadata::GetSubDirectoriesRecursively( 4093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& id, 4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::set<base::FilePath>* sub_directories) { 411b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<std::string> children; 414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FileError error = storage_->GetChildren(id, &children); 415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < children.size(); ++i) { 4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ResourceEntry entry; 419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = storage_->GetEntry(children[i], &entry); 420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (entry.file_info().is_directory()) { 423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::FilePath path; 424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = GetFilePath(children[i], &path); 425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 426cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sub_directories->insert(path); 4283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GetSubDirectoriesRecursively(children[i], sub_directories); 429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return FILE_ERROR_OK; 432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError ResourceMetadata::GetChildId(const std::string& parent_local_id, 435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& base_name, 436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string* out_child_id) { 43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return storage_->GetChild(parent_local_id, base_name, out_child_id); 43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 44090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 441a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)scoped_ptr<ResourceMetadata::Iterator> ResourceMetadata::GetIterator() { 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 443b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 444a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return storage_->GetIterator(); 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError ResourceMetadata::GetFilePath(const std::string& id, 448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::FilePath* out_file_path) { 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ResourceEntry entry; 452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FileError error = storage_->GetEntry(id, &entry); 453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::FilePath path; 457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!entry.parent_local_id().empty()) { 458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = GetFilePath(entry.parent_local_id(), &path); 459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (entry.local_id() != util::kDriveGrandRootLocalId) { 462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DVLOG(1) << "Entries not under the grand root don't have paths."; 463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return FILE_ERROR_NOT_FOUND; 464b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) path = path.Append(base::FilePath::FromUTF8Unsafe(entry.base_name())); 466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *out_file_path = path; 467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return FILE_ERROR_OK; 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FileError ResourceMetadata::GetIdByPath(const base::FilePath& file_path, 4713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string* out_id) { 472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Start from the root. 475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<base::FilePath::StringType> components; 476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_path.GetComponents(&components); 4773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (components.empty() || components[0] != util::kDriveGrandRootDirName) 4783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return FILE_ERROR_NOT_FOUND; 479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Iterate over the remaining components. 481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string id = util::kDriveGrandRootLocalId; 482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 1; i < components.size(); ++i) { 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string component = base::FilePath(components[i]).AsUTF8Unsafe(); 484cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string child_id; 485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FileError error = storage_->GetChild(id, component, &child_id); 486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) id = child_id; 489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 4903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *out_id = id; 4913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return FILE_ERROR_OK; 492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 494424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)FileError ResourceMetadata::GetIdByResourceId(const std::string& resource_id, 495424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::string* out_local_id) { 496424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 497cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return storage_->GetIdByResourceId(resource_id, out_local_id); 498424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 499424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError ResourceMetadata::PutEntryUnderDirectory(const ResourceEntry& entry) { 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 50268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(!entry.local_id().empty()); 50368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(!entry.parent_local_id().empty()); 504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string base_name; 506cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FileError error = GetDeduplicatedBaseName(entry, &base_name); 507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResourceEntry updated_entry(entry); 510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) updated_entry.set_base_name(base_name); 5115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return storage_->PutEntry(updated_entry); 5125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 5135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError ResourceMetadata::GetDeduplicatedBaseName( 515cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ResourceEntry& entry, 516cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string* base_name) { 5175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 5185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(!entry.parent_local_id().empty()); 5195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(!entry.title().empty()); 520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The entry name may have been changed due to prior name de-duplication. 522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We need to first restore the file name based on the title before going 523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // through name de-duplication again when it is added to another directory. 524cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *base_name = entry.title(); 5255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (entry.has_file_specific_info() && 5265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu entry.file_specific_info().is_hosted_document()) { 527cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *base_name += entry.file_specific_info().document_extension(); 5285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 529cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *base_name = util::NormalizeFileName(*base_name); 5305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // If |base_name| is not used, just return it. 532cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool can_use_name = false; 533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FileError error = EntryCanUseName(storage_, entry.parent_local_id(), 534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) entry.local_id(), *base_name, 535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &can_use_name); 536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK || can_use_name) 537cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Find an unused number with binary search. 5405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu int smallest_known_unused_modifier = 1; 541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (true) { 542cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = EntryCanUseName(storage_, entry.parent_local_id(), entry.local_id(), 543cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetUniquifiedName(*base_name, 544cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) smallest_known_unused_modifier), 545cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &can_use_name); 546cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 547cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 548cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (can_use_name) 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const int delta = base::RandInt(1, smallest_known_unused_modifier); 5525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (smallest_known_unused_modifier <= INT_MAX - delta) { 5535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu smallest_known_unused_modifier += delta; 5545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } else { // No luck finding an unused number. Try again. 5555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu smallest_known_unused_modifier = 1; 5565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu int largest_known_used_modifier = 1; 5605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu while (smallest_known_unused_modifier - largest_known_used_modifier > 1) { 5615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const int modifier = largest_known_used_modifier + 5625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu (smallest_known_unused_modifier - largest_known_used_modifier) / 2; 5635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = EntryCanUseName(storage_, entry.parent_local_id(), entry.local_id(), 565cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetUniquifiedName(*base_name, modifier), 566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &can_use_name); 567cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 568cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 569cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (can_use_name) { 5705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu smallest_known_unused_modifier = modifier; 5715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } else { 5725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu largest_known_used_modifier = modifier; 5735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 5745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 575cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *base_name = GetUniquifiedName(*base_name, smallest_known_unused_modifier); 576cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return FILE_ERROR_OK; 577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 579cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError ResourceMetadata::RemoveEntryRecursively(const std::string& id) { 580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ResourceEntry entry; 583cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FileError error = storage_->GetEntry(id, &entry); 584cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 585cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (entry.file_info().is_directory()) { 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<std::string> children; 589cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = storage_->GetChildren(id, &children); 590cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 591cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < children.size(); ++i) { 593cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = RemoveEntryRecursively(children[i]); 594cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 595cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 598cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 599cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = cache_->Remove(id); 600cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 601cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 602cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 6033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return storage_->RemoveEntry(id); 604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace internal 607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace drive 608