FileSystem API

This directory contains part of the browser side implementation of various filesystem related APIs, as well as interfaces to treat various types of native and non-native filesystems mostly the same without having to worry about the underlying implementation.

Related directories

//content/browser/fileapi/ contains the rest of the browser side implementation, while blink/renderer/modules/filesystem contains the renderer side implementation and blink/public/mojom/filesystem contains the mojom interfaces for these APIs.

File System Types

There are two kinds of file system types supported by the file system implementation: Internal types and public types. //storage/common/fileapi/file_system_types.h has an enum of all the various types that exist. Many of these are Chrome OS specific or only make sense in the context of extensions.

Public Types

The three public file system types are:

  • Sandboxed file systems (with both a temporary and a persistent variant), implemented by storage::SandboxFileSystemBackend;
  • “Isolated” file systems, which wrap one of the internal types, managed by storage::IsolatedContext and implemented by storage::IsolatedFileSystemBackend; and
  • “External” file systems, which also wrap one of the internal types, managed by storage::ExternalMountPoints.

External File Systems

External File Systems are only used by Chrome OS. A lot of the code for this (besides storage::ExternalMountPoints itself) lives in //chrome/browser/chromeos/fileapi/.

TODO(mek): Document this more.

Sandboxed File Systems

The sandbox file system backend provides for per-origin, quota-managed file systems, as specified in the (deprecated) File API: Directories and System specification. There are two flavors of this, “temporary” and “persistent”.

This same file system (or at least the “temporary” version) is also exposed via the new Native File System API.

Isolated File Systems

Isolated file systems generally are used to expose files from other file system types to the web for the Files and Directory Entries API, either via Drag&Drop or <input type=file>. They are also used for the (deprecated) Chrome Apps chrome.fileSystem API, and the new Native File System API.

Interesting Classes

storage::FileSystemContext

This is the main entry point for any interaction with the file system subsystem. It is created (via content::CreateFileSystemContext) and owned by each Storage Partition.

It owns:

  • Via scoped_refptr a optional storage::ExternalMountPoints instance to deal with BrowserContext specific external file systems. Currently always nullptr, except on Chrome OS.

  • A storage::SandboxFileSystemBackendDelegate. This is used by both the backend for the regular sandboxed file system, and for the chrome extensions specific “sync” file system.

  • Via scoped_refptr a bunch of storage::FileSystemBackend instances. These are either created by the FileSystemContext itself (for sandbox, plugin private, and isolated file systems) or passed in to constructor after requesting the additional backends from the content embedder via ContentBrowserClient::GetAdditionalFileSystemBackends.

And further more it references:

  • An ordered set of URL crackers (storage::MountPoints instances). This consists of the optional browser context specific ExternalMountPoints, a global singleton ExternalMountPoints and finally a global singleton IsolatedContext.

storage::SandboxFileSystemBackend

The main entry point of support for sandboxed file systems. This class forwards all operations to the FileSystemContext owned SandboxFileSystemBackendDelegate instance, which does the actual work.

storage::SandboxFileSystemBackendDelegate

The actual main entry point for sandboxed file systems, but as mentioned also used for the Chrome Extensions specific sync file system.

This class delegates operating on files to a storage::ObfuscatedFileUtil instance it owns (wrapped in a AsyncFileUtilAdapter).

It is however responsible for interacting with the quota system. In order to do that it maintains a separate cache of how much disk is being used by various origins/file system types using a FileSystemUsageCache instance. This basically adds a flat file in every directory for a origin/file system type containing the total disk usage of that directory, and some extra meta data.

storage::ObfuscatedFileUtil

This class uses several leveldb databases to translate virtual file paths given by arbitrary untrusted apps to obfuscated file paths that are supported by the underlying file system. First of all it uses SandboxPrioritizedOriginDatabase to map origins to paths, and then owns one SandboxDirectoryDatabase per origin per file system type (each with their own leveldb database) to map files within that origin to obfuscated file names.

See class comments for ObfuscatedFileUtil for more detail on how this works as well.

Important to note that this class doesn't actually deal with any operations on the files themselves. It merely keeps track of metadata. For actual operations on the files this class merely translates the virtual file paths to “real” file paths and then passes those on to a ObfuscatedFileUtilDelegate instance for the actual file operations. There are two possible implementations of this delegate, one that stores all the files in memory (for incognito mode) and one that stores the files on disk inside the profile directory.

storage::IsolatedContext

This class keeps track of all currently registered Isolate File Systems. Isolated file systems are identified by the hex encoding of 16 random bytes of data.

Life time of individual isolated file systems is reference counted, using AddReference and RemoveReference methods. For certain paths it is however also possible to entirely reokve the file system without waiting for its reference count to go to zero.

Today reference counts are increased/decreased implicitly by granting access to certain file systems to certain renderer processes (i.e. content::ChildProcessSecurityPolicyImpl calls AddReference when permission is granted, and call RemoveReference when the process is destroyed on all the file systems that renderer has access to). The Native File System API will introduce its own way of adding and removing references to these file systems.