Home | History | Annotate | Download | only in fileapi
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef WEBKIT_BROWSER_FILEAPI_SANDBOX_DIRECTORY_DATABASE_H_
      6 #define WEBKIT_BROWSER_FILEAPI_SANDBOX_DIRECTORY_DATABASE_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/files/file.h"
     12 #include "base/files/file_path.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/time/time.h"
     15 #include "webkit/browser/webkit_storage_browser_export.h"
     16 
     17 namespace content {
     18 class SandboxDirectoryDatabaseTest;
     19 }
     20 
     21 namespace tracked_objects {
     22 class Location;
     23 }
     24 
     25 namespace leveldb {
     26 class DB;
     27 class Env;
     28 class Status;
     29 class WriteBatch;
     30 }
     31 
     32 namespace fileapi {
     33 
     34 // This class WILL NOT protect you against producing directory loops, giving an
     35 // empty directory a backing data file, giving two files the same backing file,
     36 // or pointing to a nonexistent backing file.  It does no file IO other than
     37 // that involved with talking to its underlying database.  It does not create or
     38 // in any way touch real files; it only creates path entries in its database.
     39 
     40 // TODO(ericu): Safe mode, which does more checks such as the above on debug
     41 // builds.
     42 // TODO(ericu): Add a method that will give a unique filename for a data file.
     43 class WEBKIT_STORAGE_BROWSER_EXPORT_PRIVATE SandboxDirectoryDatabase {
     44  public:
     45   typedef int64 FileId;
     46 
     47   struct WEBKIT_STORAGE_BROWSER_EXPORT_PRIVATE FileInfo {
     48     FileInfo();
     49     ~FileInfo();
     50 
     51     bool is_directory() const {
     52       return data_path.empty();
     53     }
     54 
     55     FileId parent_id;
     56     base::FilePath data_path;
     57     base::FilePath::StringType name;
     58     // This modification time is valid only for directories, not files, as
     59     // FileWriter will get the files out of sync.
     60     // For files, look at the modification time of the underlying data_path.
     61     base::Time modification_time;
     62   };
     63 
     64   SandboxDirectoryDatabase(
     65       const base::FilePath& filesystem_data_directory,
     66       leveldb::Env* env_override);
     67   ~SandboxDirectoryDatabase();
     68 
     69   bool GetChildWithName(
     70       FileId parent_id,
     71       const base::FilePath::StringType& name,
     72       FileId* child_id);
     73   bool GetFileWithPath(const base::FilePath& path, FileId* file_id);
     74   // ListChildren will succeed, returning 0 children, if parent_id doesn't
     75   // exist.
     76   bool ListChildren(FileId parent_id, std::vector<FileId>* children);
     77   bool GetFileInfo(FileId file_id, FileInfo* info);
     78   base::File::Error AddFileInfo(const FileInfo& info, FileId* file_id);
     79   bool RemoveFileInfo(FileId file_id);
     80   // This does a full update of the FileInfo, and is what you'd use for moves
     81   // and renames.  If you just want to update the modification_time, use
     82   // UpdateModificationTime.
     83   bool UpdateFileInfo(FileId file_id, const FileInfo& info);
     84   bool UpdateModificationTime(
     85       FileId file_id, const base::Time& modification_time);
     86   // This is used for an overwriting move of a file [not a directory] on top of
     87   // another file [also not a directory]; we need to alter two files' info in a
     88   // single transaction to avoid weird backing file references in the event of a
     89   // partial failure.
     90   bool OverwritingMoveFile(FileId src_file_id, FileId dest_file_id);
     91 
     92   // This produces the series 0, 1, 2..., starting at 0 when the underlying
     93   // filesystem is first created, and maintaining state across
     94   // creation/destruction of SandboxDirectoryDatabase objects.
     95   bool GetNextInteger(int64* next);
     96 
     97   bool IsDirectory(FileId file_id);
     98 
     99   // Returns true if the database looks consistent with local filesystem.
    100   bool IsFileSystemConsistent();
    101 
    102   static bool DestroyDatabase(const base::FilePath& path,
    103                               leveldb::Env* env_override);
    104 
    105  private:
    106   enum RecoveryOption {
    107     DELETE_ON_CORRUPTION,
    108     REPAIR_ON_CORRUPTION,
    109     FAIL_ON_CORRUPTION,
    110   };
    111 
    112   friend class content::SandboxDirectoryDatabaseTest;
    113   friend class ObfuscatedFileUtil;
    114 
    115   bool Init(RecoveryOption recovery_option);
    116   bool RepairDatabase(const std::string& db_path);
    117   void ReportInitStatus(const leveldb::Status& status);
    118   bool StoreDefaultValues();
    119   bool GetLastFileId(FileId* file_id);
    120   bool AddFileInfoHelper(
    121       const FileInfo& info, FileId file_id, leveldb::WriteBatch* batch);
    122   bool RemoveFileInfoHelper(FileId file_id, leveldb::WriteBatch* batch);
    123   void HandleError(const tracked_objects::Location& from_here,
    124                    const leveldb::Status& status);
    125 
    126   const base::FilePath filesystem_data_directory_;
    127   leveldb::Env* env_override_;
    128   scoped_ptr<leveldb::DB> db_;
    129   base::Time last_reported_time_;
    130   DISALLOW_COPY_AND_ASSIGN(SandboxDirectoryDatabase);
    131 };
    132 
    133 }  // namespace fileapi
    134 
    135 #endif  // WEBKIT_BROWSER_FILEAPI_SANDBOX_DIRECTORY_DATABASE_H_
    136