// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "posix_translation/pepper_file.h"

#include <string.h>  // memset
#include <sys/ioctl.h>

#include "base/containers/mru_cache.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/safe_strerror_posix.h"
#include "base/strings/stringprintf.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "common/arc_strace.h"
#include "common/danger.h"
#include "common/trace_event.h"
#include "posix_translation/dir.h"
#include "posix_translation/directory_file_stream.h"
#include "posix_translation/directory_manager.h"
#include "posix_translation/path_util.h"
#include "posix_translation/statfs.h"
#include "posix_translation/virtual_file_system.h"
#include "posix_translation/wrap.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_file_io.h"
#include "ppapi/cpp/directory_entry.h"
#include "ppapi/cpp/file_ref.h"
#include "ppapi/cpp/private/file_io_private.h"

namespace posix_translation {

namespace {

const size_t kMaxFSCacheEntries = 1024;
const blksize_t kBlockSize = 4096;

#if !defined(NDEBUG)
// TODO(crbug.com/358440): Fix the issue and remove the very ARC specific
// hack from posix_translation/.
bool IsWhitelistedFile(const std::string& name) {
  // dexZipGetEntryInfo in dalvik/libdex/ZipArchive.cpp reads mmaped
  // (with PROT_WRITE) region so we need to allow all .jar files.
  if (EndsWith(name, ".jar", true))
    return true;

  // This allows the App's APK to be read/mmap'd as well as APKs passed to
  // aapt and during testing.
  if (EndsWith(name, ".apk", true)) {
    return true;
  }

  if (EndsWith(name, ".dex", true)) {
    return StartsWithASCII(name, "/data/dalvik-cache/", true) ||
      StartsWithASCII(name, "/data/data/", true);
  }

  // Secondary dex files are loaded by the same code as .jar from mmaped region.
  if (EndsWith(name, ".zip", true)) {
    return StartsWithASCII(name, "/data/data/", true);
  }

  return false;
}
#endif

// Returns true if it is allowed to read/write |pathname| with |inode|. This
// function may return false if the file associated with the |inode| was/is
// mmapped. Note that "mmap(PROT_READ), munmap, then read/write" is allowed,
// but other ways of mixing mmap and read are not allowed. For production
// (when NDEBUG is defined), this function does nothing and always returns
// true.
bool IsReadWriteAllowed(const std::string& pathname, ino_t inode,
                        const std::string& operation_str) {
#if !defined(NDEBUG)
  VirtualFileSystem* sys = VirtualFileSystem::GetVirtualFileSystem();

  const bool is_write_mapped = sys->IsWriteMapped(inode);
  const bool is_currently_mapped =
    // Do not call IsCurrentlyMapped() when |is_write_mapped| is true
    // for (slightly) better performance.
    is_write_mapped ? false : sys->IsCurrentlyMapped(inode);
  if (!is_write_mapped && !is_currently_mapped)
    return true;

  static const char kWarnWriteMapped[] = "was/is mmapped with PROT_WRITE";
  static const char kWarnMapped[] = "is currently mmapped";
  const std::string log_str = base::StringPrintf(
      "%s(\"%s\") might not be safe on non-Linux environment since the file %s",
      operation_str.c_str(), pathname.c_str(),
      (is_write_mapped ? kWarnWriteMapped : kWarnMapped));
  ALOGI("%s", log_str.c_str());

  // TODO(crbug.com/358440): Stop calling IsWhitelistedFile().
  if (IsWhitelistedFile(pathname))
    return true;

  sys->mutex().AssertAcquired();  // touching |s_show_mmap_warning| is safe.
  static bool s_show_mmap_warning = true;
  if (s_show_mmap_warning) {
    // Show a big warning with ALOGE only once to notify developers that the
    // current APK is not 100% compatible with non-Linux environment.
    s_show_mmap_warning = false;
    ALOGE("********* MMAP COMPATIBILITY ERROR (crbug.com/357780) *********");
    ALOGE("********* %s *********", log_str.c_str());
  }
  return false;
#else
  // For production, do not check anything for performance (crbug.com/373645).
  return true;
#endif
}

}  // namespace

#if defined(DEBUG_POSIX_TRANSLATION)
namespace ipc_stats {

// |VirtualFileSystem::mutex_| must be held before updating these variables.
size_t g_delete;
size_t g_fdatasync;
size_t g_fsync;
size_t g_make_directory;
size_t g_open;
size_t g_query;
size_t g_read_directory_entries;
size_t g_rename;
size_t g_set_length;
size_t g_touch;
uint64_t g_write_bytes;
uint64_t g_read_bytes;

std::string GetIPCStatsAsStringLocked() {
  VirtualFileSystem::GetVirtualFileSystem()->mutex().AssertAcquired();
  const size_t total = g_delete + g_make_directory + g_open + g_query +
      g_read_directory_entries + g_rename + g_set_length + g_touch;
  return base::StringPrintf("PepperFile: Delete:%zu MakeDirectory:%zu Open:%zu "
                            "Query:%zu ReadDirectoryEntries:%zu Rename:%zu "
                            "SetLength:%zu Touch:%zu TOTAL:%zu, "
                            "FSync:%zu FDataSync: %zu, "
                            "BytesWritten: %llu BytesRead: %llu",
                            g_delete, g_make_directory, g_open, g_query,
                            g_read_directory_entries, g_rename, g_set_length,
                            g_touch, total, g_fsync, g_fdatasync,
                            g_write_bytes, g_read_bytes);
}

}  // namespace ipc_stats
#endif

// A MRU cache to avoid doing extra calls to access/stat.
// Access is currently implemented in terms of the same function that stat is
// using. Several applications open files by calling access, followed by stat
// and open. This causes one extra superfluous call to Pepper, that can be
// avoided.
class PepperFileCache {
 public:
  explicit PepperFileCache(size_t size) : size_(size), cache_(size) {}

  bool Get(const std::string& path, PP_FileInfo* file_info, bool* exists) {
    VirtualFileSystem::GetVirtualFileSystem()->mutex().AssertAcquired();
    if (!IsCacheEnabled())
      return false;
    std::string key(path);
    RemoveTrailingSlash(&key);
    const MRUCache::iterator it = cache_.Get(key);
    if (it == cache_.end()) {
      ARC_STRACE_REPORT("PepperFileCache: Cache miss for %s", path.c_str());
      return false;
    }
    ARC_STRACE_REPORT("PepperFileCache: Cache hit for %s", path.c_str());
    if (file_info)
      *file_info = it->second.file_info;
    if (exists)
      *exists = it->second.exists;
    return true;
  }

  // Returns true when the |path| is definitely non-existent. When it exists or
  // when it is unknown, returns false.
  bool IsNonExistent(const std::string& path) {
    VirtualFileSystem::GetVirtualFileSystem()->mutex().AssertAcquired();
    if (!IsCacheEnabled())
      return false;
    bool exists = false;
    if (!Get(path, NULL, &exists))
      return false;  // unknown
    return !exists;
  }

  void Set(const std::string& path, const PP_FileInfo& file_info, bool exists) {
    VirtualFileSystem::GetVirtualFileSystem()->mutex().AssertAcquired();
    if (!IsCacheEnabled())
      return;
    ARC_STRACE_REPORT("PepperFileCache: Adding to cache %s, exists: %s",
                      path.c_str(), exists ? "true" : "false");
    const CacheEntry entry = { exists, file_info };
    std::string key(path);
    RemoveTrailingSlash(&key);
    cache_.Put(key, entry);
  }

  void SetNotExistent(const std::string& path) {
    VirtualFileSystem::GetVirtualFileSystem()->mutex().AssertAcquired();
    if (!IsCacheEnabled())
      return;
    PP_FileInfo dummy = {};
    Set(path, dummy, false);
  }

  void SetNotExistentDirectory(const std::string& path) {
    VirtualFileSystem::GetVirtualFileSystem()->mutex().AssertAcquired();
    if (!IsCacheEnabled())
      return;
    std::string key(path);
    if (!util::EndsWithSlash(key))
      key.append("/");

    PP_FileInfo dummy = {};
    const CacheEntry entry = { false, dummy };
    for (MRUCache::iterator i = cache_.begin(); i != cache_.end(); ++i) {
      if (StartsWithASCII(i->first, key, true))
        i->second = entry;
    }
  }

  void Invalidate(const std::string& path) {
    VirtualFileSystem::GetVirtualFileSystem()->mutex().AssertAcquired();
    if (!IsCacheEnabled())
      return;
    ARC_STRACE_REPORT("PepperFileCache: Cache invalidation for %s",
                      path.c_str());
    std::string key(path);
    RemoveTrailingSlash(&key);
    const MRUCache::iterator it = cache_.Get(key);
    if (it != cache_.end())
      cache_.Erase(it);
  }

  void Clear() {
    VirtualFileSystem::GetVirtualFileSystem()->mutex().AssertAcquired();
    if (!IsCacheEnabled())
      return;
    ARC_STRACE_REPORT("PepperFileCache: Invalidate all cache entries");
    cache_.Clear();
  }

  void DisableForTesting() {
    VirtualFileSystem::GetVirtualFileSystem()->mutex().AssertAcquired();
    Clear();
    size_ = 0;
  }

 private:
  bool IsCacheEnabled() const {
    return size_ > 0;
  }

  static void RemoveTrailingSlash(std::string* in_out_path) {
    ALOG_ASSERT(in_out_path);
    const size_t len = in_out_path->length();
    if (len < 2 || !util::EndsWithSlash(*in_out_path))
      return;
    in_out_path->erase(len - 1);
  }

  struct CacheEntry {
    bool exists;
    PP_FileInfo file_info;
  };
  typedef base::MRUCache<std::string, CacheEntry> MRUCache;

  size_t size_;
  MRUCache cache_;

  DISALLOW_COPY_AND_ASSIGN(PepperFileCache);
};

class FileIOWrapper {
 public:
  FileIOWrapper(pp::FileIO* file_io, PP_FileHandle native_handle,
                const std::string& filename)
      : file_io_(file_io), native_handle_(native_handle) {
    ALOG_ASSERT(native_handle_ >= 0);
  }
  ~FileIOWrapper() {
    if (native_handle_ != PP_kInvalidFileHandle) {
      if (real_close(native_handle_)) {
        ALOGW("libc_close failed: native_handle_=%d: %s",
              native_handle_, safe_strerror(errno).c_str());
      }
    }
  }

  pp::FileIO* file_io() { return file_io_.get(); }
  PP_FileHandle native_handle() { return native_handle_; }

 private:
  scoped_ptr<pp::FileIO> file_io_;
  PP_FileHandle native_handle_;

  DISALLOW_COPY_AND_ASSIGN(FileIOWrapper);
};

PepperFileHandler::PepperFileHandler()
    : FileSystemHandler("PepperFileHandler"),
      factory_(this),
      cache_(new PepperFileCache(kMaxFSCacheEntries)) {
}

PepperFileHandler::PepperFileHandler(const char* name, size_t max_cache_size)
    : FileSystemHandler(name),
      factory_(this),
      cache_(new PepperFileCache(max_cache_size)) {
}

PepperFileHandler::~PepperFileHandler() {
}

void PepperFileHandler::OpenPepperFileSystem(pp::Instance* instance) {
  // Since Chrome ignores |kExpectedUsage|, the actual value is not important.
  static const uint64_t kExpectedUsage = 16ULL * 1024 * 1024 * 1024;
  ALOG_ASSERT(pp::Module::Get()->core()->IsMainThread());
  scoped_ptr<pp::FileSystem> file_system(
      new pp::FileSystem(instance, PP_FILESYSTEMTYPE_LOCALPERSISTENT));
  TRACE_EVENT_ASYNC_BEGIN1(ARC_TRACE_CATEGORY,
                           "PepperFileHandler::OpenPepperFileSystem",
                           this, "type", PP_FILESYSTEMTYPE_LOCALPERSISTENT);
  const int32_t result = file_system->Open(
      kExpectedUsage,
      factory_.NewCallback(&PepperFileHandler::OnFileSystemOpen,
                           file_system.release()));
  ALOG_ASSERT(result == PP_OK_COMPLETIONPENDING,
              "Failed to create pp::FileSystem, error: %d", result);
}

void PepperFileHandler::DisableCacheForTesting() {
  cache_->DisableForTesting();
}

void PepperFileHandler::OnFileSystemOpen(
    int32_t result,
    pp::FileSystem* file_system_ptr) {
  scoped_ptr<pp::FileSystem> file_system(file_system_ptr);
  TRACE_EVENT_ASYNC_END1(ARC_TRACE_CATEGORY,
                         "PepperFileHandler::OpenPepperFileSystem",
                         this, "result", result);
  if (result != PP_OK)
    LOG_FATAL("Failed to open pp::FileSystem, error: %d", result);
  SetPepperFileSystem(file_system.Pass(), "/", "/");
}

bool PepperFileHandler::IsInitialized() const {
  VirtualFileSystem* sys = VirtualFileSystem::GetVirtualFileSystem();
  sys->mutex().AssertAcquired();
  return file_system_.get() && sys->IsBrowserReadyLocked();
}

void PepperFileHandler::Initialize() {
  ALOG_ASSERT(!IsInitialized());
  TRACE_EVENT0(ARC_TRACE_CATEGORY, "PepperFileHandler::Initialize");
  VirtualFileSystem* sys = VirtualFileSystem::GetVirtualFileSystem();
  sys->mutex().AssertAcquired();
  ALOG_ASSERT(!IsInitialized());
  while (!IsInitialized())
    sys->Wait();
}

std::string PepperFileHandler::SetPepperFileSystem(
    scoped_ptr<pp::FileSystem> pepper_file_system,
    const std::string& mount_source_in_pepper_file_system,
    const std::string& mount_dest_in_vfs) {
  VirtualFileSystem* sys = VirtualFileSystem::GetVirtualFileSystem();
  base::AutoLock lock(sys->mutex());
  ALOG_ASSERT(pepper_file_system);
  ALOG_ASSERT(!file_system_);
  file_system_ = pepper_file_system.Pass();
  ARC_STRACE_REPORT("Mounting %s in pp::FileSystem %p to %s in VFS",
                    mount_source_in_pepper_file_system.c_str(),
                    file_system_.get(),
                    mount_dest_in_vfs.c_str());
  sys->Broadcast();
  return mount_dest_in_vfs;
}

bool PepperFileHandler::IsWorldWritable(const std::string& pathname) {
  // Calling this->stat() every time when VFS::GetFileSystemHandlerLocked() is
  // invoked is too expensive for this handler (and this handler's stat() does
  // not fill the permission part of st_mode anyway). Just returning false
  // would be just fine.
  return false;
}

scoped_refptr<FileStream> PepperFileHandler::open(
    int unused_fd, const std::string& pathname, int oflag, mode_t cmode) {
  // TODO(crbug.com/242355): Use |cmode|.
  TRACE_EVENT2(ARC_TRACE_CATEGORY, "PepperFileHandler::open",
               "pathname", pathname, "oflag", oflag);
  // First, check the cache if O_CREAT is not in |oflag|.
  if (pathname.empty() ||
      (!(oflag & O_CREAT) && cache_->IsNonExistent(pathname))) {
    errno = ENOENT;
    return NULL;
  }

  TRACE_EVENT0(ARC_TRACE_CATEGORY, "PepperFileHandler::open - Pepper");
  const int access_mode = (oflag & O_ACCMODE);

  // When needed, invalidate the |cache_| before calling "new PepperFile" which
  // might unlock the |mutex_|. Note that 'O_RDONLY|O_CREAT' is allowed at least
  // on Linux and it may actually create the file. Just in case, do the same for
  // 'O_RDONLY|O_TRUNC' which may also truncate the file at least on Linux (even
  // though pp::FileIO seems to refuse the latter).
  if ((access_mode != O_RDONLY) || (oflag & (O_CREAT | O_TRUNC)))
    cache_->Invalidate(pathname);

  TRACE_EVENT1(ARC_TRACE_CATEGORY, "PepperFile::open",
               "pathname", pathname);

  VirtualFileSystem* sys = VirtualFileSystem::GetVirtualFileSystem();

  const int open_flags = ConvertNativeOpenFlagsToPepper(oflag);
  int32_t result;
  scoped_ptr<pp::FileIO_Private> file_io;
  PP_FileHandle file_handle;
  {
    // TODO(crbug.com/225152): Fix 225152 and remove |unlock|.
    base::AutoUnlock unlock(sys->mutex());
    pp::FileRef file_ref(*file_system_, pathname.c_str());
    file_io.reset(new pp::FileIO_Private(sys->instance()));
    result = file_io->Open(file_ref, open_flags, pp::BlockUntilComplete());
    if (result == PP_OK) {
      pp::CompletionCallbackWithOutput<pp::PassFileHandle> cb(&file_handle);
      result = file_io->RequestOSFileHandle(cb);
      if (result != PP_OK) {
        ALOGE("PPB_FileIO_Private::RequestOSFileHandle failed! This usually "
              "means that your app does not have unlimitedStorage permission.");
      }
    }
  }

  ARC_STRACE_REPORT_PP_ERROR(result);

#if defined(DEBUG_POSIX_TRANSLATION)
  ++ipc_stats::g_open;
#endif
  scoped_refptr<FileStream> stream = NULL;
  if (result == PP_OK) {
    if (oflag & O_DIRECTORY) {
      errno = ENOTDIR;
      return NULL;
    }
    stream = new PepperFile(
        oflag, cache_.get(), pathname,
        new FileIOWrapper(file_io.release(), file_handle, pathname));
  } else if (result == PP_ERROR_NOTAFILE) {
    // A directory is opened.
    if (access_mode != O_RDONLY) {
      errno = EISDIR;
      return NULL;
    }
    stream = new DirectoryFileStream("pepper", pathname, this);
  } else {
    errno = ConvertPepperErrorToErrno(result);
  }

  return stream;
}

Dir* PepperFileHandler::OnDirectoryContentsNeeded(const std::string& name) {
  TRACE_EVENT1(ARC_TRACE_CATEGORY,
               "PepperFileHandler::OnDirectoryContentsNeeded", "name", name);

  // First, check the cache.
  if (name.empty() || cache_->IsNonExistent(name)) {
    errno = ENOENT;
    return NULL;
  }

  TRACE_EVENT0(ARC_TRACE_CATEGORY,
               "PepperFileHandler::OnDirectoryContentsNeeded - Pepper");
  VirtualFileSystem* sys = VirtualFileSystem::GetVirtualFileSystem();
  int32_t result;

  pp::internal::DirectoryEntryArrayOutputAdapterWithStorage adapter;
  pp::CompletionCallbackWithOutput<std::vector<pp::DirectoryEntry> > cb(
      &adapter);

  {
    // TODO(crbug.com/225152): Fix 225152 and remove |unlock|.
    base::AutoUnlock unlock(sys->mutex());
    pp::FileRef file_ref(*file_system_, name.c_str());
    result = file_ref.ReadDirectoryEntries(cb);
  }
#if defined(DEBUG_POSIX_TRANSLATION)
  ++ipc_stats::g_read_directory_entries;
#endif

  ARC_STRACE_REPORT_PP_ERROR(result);
  if (result != PP_OK) {
    errno = ConvertPepperErrorToErrno(result);
    // getdents should not return these values.
    if (errno == EEXIST || errno == EISDIR ||
        errno == ENOSPC || errno == EPERM) {
      ALOG_ASSERT(false, "errno=%d", errno);
      errno = ENOENT;
    }
    return NULL;
  }

  const std::vector<pp::DirectoryEntry>& directories = adapter.output();
  const base::FilePath base_path(name);
  DirectoryManager directory_manager;
  // We have already confirmed the directory exists. Make sure
  // OpenDirectory will succeed for empty directories by adding the
  // directory we are checking.
  directory_manager.MakeDirectories(name);
  for (size_t i = 0; i < directories.size(); ++i) {
    const pp::DirectoryEntry& entry = directories[i];
    const pp::FileRef& ref = entry.file_ref();
    std::string filename = base_path.Append(ref.GetName().AsString()).value();
    if (entry.file_type() == PP_FILETYPE_DIRECTORY) {
      directory_manager.MakeDirectories(filename);
    } else {
      bool result = directory_manager.AddFile(filename);
      ALOG_ASSERT(result);
    }
  }

  return directory_manager.OpenDirectory(name);
}

int PepperFileHandler::stat(const std::string& pathname, struct stat* out) {
  TRACE_EVENT1(ARC_TRACE_CATEGORY, "PepperFileHandler::stat",
               "pathname", pathname);

  PP_FileInfo file_info = {};
  bool exists = false;
  if (!cache_->Get(pathname, &file_info, &exists)) {
    TRACE_EVENT0(ARC_TRACE_CATEGORY, "PepperFileHandler::stat - Pepper");
    int32_t result = QueryRefLocked(pathname, &file_info);
    ARC_STRACE_REPORT_PP_ERROR(result);
    exists = result == PP_OK;
    cache_->Set(pathname, file_info, exists);
  }

  if (!exists) {
    errno = ENOENT;
    return -1;
  }

  if (file_info.type == PP_FILETYPE_DIRECTORY) {
    DirectoryFileStream::FillStatData(pathname, out);
    // Do not fill st_mtime for a directory to be consistent with
    // DirectoryFileStream::fstat.
  } else {
    memset(out, 0, sizeof(struct stat));
    // Always assigning 0 (or another constant) to |st_ino| does not always
    // work. For example, since SQLite3 manages the current file lock status
    // per inode (see unixLock() in sqlite/dist/sqlite3.c), always using
    // 0 for |st_ino| may cause deadlock.
    out->st_ino =
        VirtualFileSystem::GetVirtualFileSystem()->GetInodeLocked(pathname);
    out->st_mode = S_IFREG;
    out->st_nlink = 1;
    out->st_size = file_info.size;
    out->st_blksize = kBlockSize;
    // We do not support atime and ctime. See PepperFile::fstat().
    out->st_mtime = static_cast<time_t>(file_info.last_modified_time);
  }

  return 0;
}

int PepperFileHandler::statfs(const std::string& pathname, struct statfs* out) {
  // TODO(crbug.com/242832): Return real values by apps v2 API.
  // http://developer.chrome.com/extensions/experimental.systemInfo.storage.html
  struct stat st;
  if (this->stat(pathname, &st) == 0)
    return DoStatFsForData(out);
  errno = ENOENT;
  return -1;
}

int PepperFileHandler::mkdir(const std::string& pathname, mode_t mode) {
  TRACE_EVENT2(ARC_TRACE_CATEGORY, "PepperFileHandler::mkdir",
               "pathname", pathname, "mode", mode);

  // First, check the cache.
  PP_FileInfo file_info = {};
  bool exists = false;
  if (cache_->Get(pathname, &file_info, &exists) && exists) {
    // |pathname| already exists (either file or directory).
    errno = EEXIST;
    return -1;
  }

  TRACE_EVENT0(ARC_TRACE_CATEGORY, "PepperFileHandler::mkdir - Pepper");
  cache_->Invalidate(pathname);  // call this before unlocking the |mutex_|.
  VirtualFileSystem* sys = VirtualFileSystem::GetVirtualFileSystem();
  int32_t result;
  {
    // TODO(crbug.com/225152): Fix 225152 and remove |unlock|.
    base::AutoUnlock unlock(sys->mutex());
    pp::FileRef file_ref(*file_system_, pathname.c_str());
    result = file_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_EXCLUSIVE,
                                    pp::BlockUntilComplete());
  }
#if defined(DEBUG_POSIX_TRANSLATION)
  ++ipc_stats::g_make_directory;
#endif
  ARC_STRACE_REPORT_PP_ERROR(result);
  if (result == PP_OK)
    return 0;
  errno = ConvertPepperErrorToErrno(result);
  // mkdir should not return EISDIR.
  if (errno == EISDIR) {
    ALOG_ASSERT(false, "errno=%d", errno);
    errno = ENOENT;
  }
  return -1;
}

int PepperFileHandler::remove(const std::string& pathname) {
  // Remove an empty directory or a file specified by |pathname|.
  TRACE_EVENT1(ARC_TRACE_CATEGORY, "PepperFileHandler::remove",
               "pathname", pathname);

  // First, check the cache.
  if (cache_->IsNonExistent(pathname)) {
    errno = ENOENT;
    return -1;
  }

  TRACE_EVENT0(ARC_TRACE_CATEGORY, "PepperFileHandler::remove - Pepper");
  cache_->Invalidate(pathname);  // call this before unlocking the |mutex_|.
  VirtualFileSystem* sys = VirtualFileSystem::GetVirtualFileSystem();
  int32_t result;
  {
    // TODO(crbug.com/225152): Fix 225152 and remove |unlock|.
    base::AutoUnlock unlock(sys->mutex());
    pp::FileRef file_ref(*file_system_, pathname.c_str());
    result = file_ref.Delete(pp::BlockUntilComplete());
  }
#if defined(DEBUG_POSIX_TRANSLATION)
  ++ipc_stats::g_delete;
#endif
  ARC_STRACE_REPORT_PP_ERROR(result);
  if (result == PP_ERROR_FILENOTFOUND) {
    errno = ENOENT;
    return -1;
  }
  if (result != PP_OK) {
    // TODO(crbug.com/180985): ARC running on Windows might return PP_ERROR
    // to Remove. We might have to add a "delete later" logic here for Windows.
    // Use ConvertPepperErrorToErrno once this issue is resolved.
    errno = EISDIR;
    return -1;
  }
  sys->RemoveInodeLocked(pathname);
  // No need to call SetNotExistentDirectory since remove() can remove only
  // empty directory.
  cache_->SetNotExistent(pathname);
  return 0;
}

int PepperFileHandler::rename(const std::string& oldpath,
                              const std::string& newpath) {
  TRACE_EVENT2(ARC_TRACE_CATEGORY, "PepperFileHandler::rename",
               "oldpath", oldpath, "newpath", newpath);

  // First, check the cache.
  if (cache_->IsNonExistent(oldpath)) {
    errno = ENOENT;
    return -1;
  }

  TRACE_EVENT0(ARC_TRACE_CATEGORY, "PepperFileHandler::rename - Pepper");
  PP_FileInfo old_file_info = {};
  bool old_file_has_metadata = cache_->Get(oldpath, &old_file_info, NULL);
  cache_->Invalidate(oldpath);  // call this before unlocking the |mutex_|.
  cache_->Invalidate(newpath);  // call this before unlocking the |mutex_|.
  VirtualFileSystem* sys = VirtualFileSystem::GetVirtualFileSystem();
  int32_t result;
  {
    // TODO(crbug.com/225152): Fix 225152 and remove |unlock|.
    base::AutoUnlock unlock(sys->mutex());
    pp::FileRef old_file_ref(*file_system_, oldpath.c_str());
    pp::FileRef new_file_ref(*file_system_, newpath.c_str());
    result = old_file_ref.Rename(
        new_file_ref, pp::BlockUntilComplete());
  }
#if defined(DEBUG_POSIX_TRANSLATION)
  ++ipc_stats::g_rename;
#endif
  ARC_STRACE_REPORT_PP_ERROR(result);
  if (result != PP_OK) {
    errno = ConvertPepperErrorToErrno(result);
    return -1;
  }
  if (oldpath != newpath)
    cache_->SetNotExistentDirectory(oldpath);
  if (old_file_has_metadata)
    cache_->Set(newpath, old_file_info, true);  // rename preserves metadata.
  sys->ReassignInodeLocked(oldpath, newpath);
  // rename() should not change inode.
  return 0;
}

int PepperFileHandler::rmdir(const std::string& pathname) {
  // TODO(crbug.com/190550): Implement this properly. Note that we should
  // return ENOTDIR if |pathname| is a file, but right now we do not have a
  // good way to perform the check without unlocking the |mutex|. For now,
  // just call remove() since some apps require this API and a file name is
  // usually not passed to rmdir(). To fix this issue properly, we likely
  // have to add an API to pp::FileRef.
  ALOGW("PepperFileHandler::rmdir is not fully POSIX compatible and may"
        " delete a file: %s", pathname.c_str());
  return this->remove(pathname);
}

int PepperFileHandler::truncate(const std::string& pathname,
                                off64_t length) {
  TRACE_EVENT2(ARC_TRACE_CATEGORY, "PepperFileHandler::truncate",
               "pathname", pathname, "length", length);

  // First, check the cache.
  if (cache_->IsNonExistent(pathname)) {
    errno = ENOENT;
    return -1;
  }

  TRACE_EVENT0(ARC_TRACE_CATEGORY, "PepperFileHandler::truncate - Pepper");
  scoped_refptr<FileStream> stream = this->open(-1, pathname, O_WRONLY, 0);
  if (stream == NULL) {
    // truncate should not return these errno values.
    if (errno == EEXIST || errno == ENOMEM || errno == ENOSPC) {
      ALOG_ASSERT(false, "errno=%d", errno);
      errno = ENOENT;
    }
    return -1;
  }
  return stream->ftruncate(length);
}

int PepperFileHandler::unlink(const std::string& pathname) {
  // TODO(crbug.com/190550): Return EISDIR if |pathname| is a directory. Right
  // now, we do not have a good way to perform the check without unlocking the
  // |mutex|.
  return this->remove(pathname);
}

int PepperFileHandler::utimes(const std::string& pathname,
                              const struct timeval times[2]) {
  TRACE_EVENT1(ARC_TRACE_CATEGORY, "PepperFileHandler::utimes",
               "pathname", pathname);

  // First, check the cache.
  if (cache_->IsNonExistent(pathname)) {
    errno = ENOENT;
    return -1;
  }

  TRACE_EVENT0(ARC_TRACE_CATEGORY, "PepperFileHandler::utimes - Pepper");
  VirtualFileSystem* sys = VirtualFileSystem::GetVirtualFileSystem();
  if (!times) {
    errno = EACCES;
    return -1;
  }
  cache_->Invalidate(pathname);  // call this before unlocking the |mutex_|.
  int32_t result;
  {
    // TODO(crbug.com/225152): Fix 225152 and remove |unlock|.
    base::AutoUnlock unlock(sys->mutex());
    pp::FileRef file_ref(*file_system_, pathname.c_str());
    result = file_ref.Touch(
        times[0].tv_sec, times[1].tv_sec, pp::BlockUntilComplete());
  }
#if defined(DEBUG_POSIX_TRANSLATION)
  ++ipc_stats::g_touch;
#endif
  ARC_STRACE_REPORT_PP_ERROR(result);
  if (result != PP_OK) {
    errno = ConvertPepperErrorToErrno(result);
    // utimes should not return these errno values.
    if (errno == EEXIST || errno == EISDIR ||
        errno == ENOMEM || errno == ENOSPC) {
      ALOG_ASSERT(false, "errno=%d", errno);
      errno = ENOENT;
    }
    return -1;
  }
  return 0;
}

void PepperFileHandler::InvalidateCache() {
  cache_->Clear();
}

void PepperFileHandler::AddToCache(const std::string& path,
                                   const PP_FileInfo& file_info,
                                   bool exists) {
  cache_->Set(path, file_info, exists);
}

void PepperFileHandler::OnMounted(const std::string& path) {
  // Check if |path| being mounted exists. If this function is called on the
  // main thread, do not check the existence. There are two cases when this
  // function is called on the main thread: during handler initialization, the
  // library user mounts a static set of paths that are known to be validn.
  // The other case is that the external file handler mounts an existing
  // external file.
  // Note: It is better to move this check to MountPointManager::Add, but doing
  // so breaks many unit tests outside this library.
  PP_FileInfo info;
  ALOG_ASSERT(pp::Module::Get()->core()->IsMainThread() ||
              (QueryRefLocked(path, &info) == PP_OK),
              "Unknown path '%s' is mounted", path.c_str());

  // Update the cache when possible.
  if (!util::EndsWithSlash(path)) {
    // Ignore OnMounted calls against files since it is difficult to fill the
    // cache for files. Note that chown("/path/to/pepper/file", ..) may end up
    // taking this path.
    return;
  }
  PP_FileInfo file_info = {};
  file_info.size = 4096;
  file_info.type = PP_FILETYPE_DIRECTORY;
  // For directories, we do not have to fill mtime. See DirectoryFileStream.cc.
  cache_->Set(path, file_info, true);
}

void PepperFileHandler::OnUnmounted(const std::string& path) {
  cache_->Invalidate(path);
}

int32_t PepperFileHandler::QueryRefLocked(const std::string& pathname,
                                          PP_FileInfo* out_file_info) {
  VirtualFileSystem* sys = VirtualFileSystem::GetVirtualFileSystem();
  sys->mutex().AssertAcquired();
#if defined(DEBUG_POSIX_TRANSLATION)
  ++ipc_stats::g_query;
#endif
  // TODO(crbug.com/225152): Fix 225152 and remove |unlock|.
  base::AutoUnlock unlock(sys->mutex());
  pp::FileRef file_ref(*file_system_, pathname.c_str());
  pp::CompletionCallbackWithOutput<PP_FileInfo> cb(out_file_info);
  return file_ref.Query(cb);
}

// static
int PepperFileHandler::ConvertPepperErrorToErrno(int pp_error) {
  switch (pp_error) {
    case PP_ERROR_FILENOTFOUND:
      return ENOENT;
    case PP_ERROR_FILEEXISTS:
      return EEXIST;
    case PP_ERROR_NOACCESS:
      // This error code is returned when the system tries to write
      // something to CRX file system. As the CRX file system is
      // read-only, EPERM is more appropriate than EACCES.
      return EPERM;
    case PP_ERROR_NOMEMORY:
      return ENOMEM;
    case PP_ERROR_NOQUOTA:
    case PP_ERROR_NOSPACE:
      return ENOSPC;
    case PP_ERROR_NOTAFILE:
      return EISDIR;
    case PP_ERROR_BADRESOURCE:
      return EBADF;
    default:
      // TODO(crbug.com/293953): Some of PP_ERROR_FAILED should be ENOTDIR.
      DANGERF("Unknown Pepper error code: %d", pp_error);
      return ENOENT;
  }
}

// static
int PepperFileHandler::ConvertNativeOpenFlagsToPepper(int native_flags) {
  int pepper_flags = 0;

  if ((native_flags & O_ACCMODE) == O_WRONLY) {
    pepper_flags = PP_FILEOPENFLAG_WRITE;
  } else if ((native_flags & O_ACCMODE) == O_RDONLY) {
    pepper_flags = PP_FILEOPENFLAG_READ;
  } else if ((native_flags & O_ACCMODE) == O_RDWR) {
    pepper_flags = PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_WRITE;
  } else {
    ALOGW("Unknown open flags %o, falling back to O_RDONLY", native_flags);
    pepper_flags = PP_FILEOPENFLAG_READ;
  }

  if (native_flags & O_CREAT)
    pepper_flags |= PP_FILEOPENFLAG_CREATE;
  if (native_flags & O_EXCL)
    pepper_flags |= PP_FILEOPENFLAG_EXCLUSIVE;
  if (native_flags & O_TRUNC)
    pepper_flags |= PP_FILEOPENFLAG_TRUNCATE;

  if (native_flags & O_NOCTTY)
    ALOGW("O_NOCTTY is not supported");
  if (native_flags & O_NONBLOCK)
    ALOGW("O_NONBLOCK is not supported");
  if (native_flags & O_SYNC)
    ALOGW("O_SYNC is not supported");
  if (native_flags & O_ASYNC)
    ALOGW("O_ASYNC is not supported");
  if (native_flags & O_NOFOLLOW)
    ALOGW("O_NOFOLLOW is not supported");
  if (native_flags & O_CLOEXEC)
    ALOGW("O_CLOEXEC is not supported");
  if (native_flags & O_NOATIME)
    ALOGW("O_NOATIME is not supported");

  if (native_flags & O_APPEND) {
    if (pepper_flags & PP_FILEOPENFLAG_TRUNCATE) {
      // TODO(crbug.com/308809): Support O_APPEND | O_TRUNC file open.
      ALOGW("O_TRUNC with O_APPEND is not supported.");
    }
    if (pepper_flags & PP_FILEOPENFLAG_WRITE) {
      // _WRITE and _APPEND flags are exclusive in Pepper.
      pepper_flags |= PP_FILEOPENFLAG_APPEND;
      pepper_flags &= ~PP_FILEOPENFLAG_WRITE;
    } else {
      ALOGW("O_APPEND is specified with O_RDONLY. Ignored.");
    }
  }

  return pepper_flags;
}

//------------------------------------------------------------------------------

PepperFile::PepperFile(int oflag,
                       PepperFileCache* cache,
                       const std::string& pathname,
                       FileIOWrapper* file_wrapper)
    : FileStream(oflag, pathname),
      factory_(this),
      cache_(cache),
      file_(file_wrapper) {
  ALOG_ASSERT(cache);
  ALOG_ASSERT(file_wrapper);
}

PepperFile::~PepperFile() {}

void* PepperFile::mmap(
    void* addr, size_t length, int prot, int flags, off_t offset) {
  void* result =
      ::mmap(addr, length, prot, flags, file_->native_handle(), offset);
  if (prot & PROT_WRITE)
    cache_->Invalidate(pathname());
  return result;
}

int PepperFile::munmap(void* addr, size_t length) {
  int result = ::munmap(addr, length);
  if ((oflag() & O_ACCMODE) != O_RDONLY)
    cache_->Invalidate(pathname());
  return result;
}

ssize_t PepperFile::read(void* buf, size_t count) {
  // Detect non-portable read attempts like mmap(W)-munmap-read and
  // mmap(W)-read. For more details, see crbug.com/357780.
  if (!IsReadWriteAllowed(pathname(), inode(), "read")) {
    errno = EFAULT;
    return -1;
  }

  const ssize_t result = real_read(file_->native_handle(), buf, count);
#if defined(DEBUG_POSIX_TRANSLATION)
  if (result > 0)
    ipc_stats::g_read_bytes += result;
#endif
  return result;
}

// Note for atomicity of the write/pread/pwrite operations below:
//
// PepperFile::write(), PepperFile::pread(), and PepperFile::pwrite() calls
// lseek() to emulate Linux kernel's behavior. The
// "lseek-lseek-read/write-lseek" (for emulating pread and pwrite) sequence
// is safe for the following reasons.
//
// * Only the PPAPI (or NaCl) process for the app and HTML5 FS code in browser
//   process access files for the app in the FS.
// * For each app, only one PPAPI (or NaCl) process is started.
// * All POSIX compatible functions in this file are synchronized. For example,
//   VirtualFileSystem::write locks the |mutex_| before calling into
//   PepperFile::write.
// * All operations that might change the file offset of a file descriptor,
//   PepperFile::lseek, PepperFile::read, PepperFile::write, PepperFile::pread,
//   and PepperFile::pwrite, are done within this process. They never issues an
//   IPC.
// * Other asynchronous operations, such as PepperFileHandler::unlink,
//   PepperFileHandler::truncate, and PepperFile::ftruncate could be done in the
//   browser process in parallel to the lseek, read, write, pread, and pwrite
//   operations above, but the operations in the browser never change the offset
//   of a descriptor.

ssize_t PepperFile::write(const void* buf, size_t count) {
  // Detect non-portable write attempts like mmap(W)-write and
  // mmap(W)-munmap-write. For more details, see crbug.com/357780.
  if (!IsReadWriteAllowed(pathname(), inode(), "write")) {
    errno = EFAULT;
    return -1;
  }

  cache_->Invalidate(pathname());
  const ssize_t result = real_write(file_->native_handle(), buf, count);
#if defined(DEBUG_POSIX_TRANSLATION)
  if (result > 0)
    ipc_stats::g_write_bytes += result;
#endif
  return result;
}

off64_t PepperFile::lseek(off64_t offset, int whence) {
  return real_lseek64(file_->native_handle(), offset, whence);
}

int PepperFile::fdatasync() {
  TRACE_EVENT0(ARC_TRACE_CATEGORY, "PepperFile::fdatasync");
  // TODO(crbug.com/242349): Call NaCl IRT or pp::FileIO::Flush().
  ARC_STRACE_REPORT("not implemented yet");
#if defined(DEBUG_POSIX_TRANSLATION)
  ++ipc_stats::g_fdatasync;
#endif
  return 0;
}

int PepperFile::fstat(struct stat* out) {
  int result = real_fstat(file_->native_handle(), out);
  if (!result) {
    // If we expose the values got from host filesystem, the result
    // will be inconsistent with stat and lstat. Let VirtualFileSystem set
    // permission bits.
    out->st_mode &= ~0777;
    out->st_ino = inode();
    // Overwrite the real dev/rdev numbers with zero. This is necessary for e.g.
    // dexopt to work. dvmOpenCachedDexFile() in DexPrepare.cpp checks if st_dev
    // numbers returned from ::stat(path) and ::fstat(fd_for_the_path) are the
    // same, and retries until they return the same st_dev numbers.
    out->st_dev = out->st_rdev = 0;
    // We do not support atime and ctime. Note that java.io.File does not
    // provide a way to access them.
    out->st_atime = out->st_ctime = 0;
    // TODO(crbug.com/242337): Fill this value?
    out->st_blocks = 0;
    out->st_blksize = kBlockSize;
  }
  return result;
}

int PepperFile::fsync() {
  TRACE_EVENT0(ARC_TRACE_CATEGORY, "PepperFile::fsync");
  // TODO(crbug.com/242349): Call NaCl IRT or pp::FileIO::Flush().
  ARC_STRACE_REPORT("not implemented yet");
#if defined(DEBUG_POSIX_TRANSLATION)
  ++ipc_stats::g_fsync;
#endif
  return 0;
}

int PepperFile::ftruncate(off64_t length) {
  TRACE_EVENT1(ARC_TRACE_CATEGORY, "PepperFile::ftruncate", "length", length);

  if ((oflag() & O_ACCMODE) == O_RDONLY) {
    errno = EBADF;
    return -1;
  }

  cache_->Invalidate(pathname());
  VirtualFileSystem* sys = VirtualFileSystem::GetVirtualFileSystem();
  int32_t result;
  {
    // TODO(crbug.com/225152): Fix 225152 and remove |unlock|.
    base::AutoUnlock unlock(sys->mutex());
    pp::FileIO* file_io = file_->file_io();
    result = file_io->SetLength(length, pp::BlockUntilComplete());
  }
#if defined(DEBUG_POSIX_TRANSLATION)
  ++ipc_stats::g_set_length;
#endif
  ARC_STRACE_REPORT_PP_ERROR(result);
  if (result != PP_OK) {
    DANGERF("ftruncate failed with Pepper error code: %d", result);
    errno = EACCES;
    return -1;
  }
  return 0;
}

int PepperFile::ioctl(int request, va_list ap) {
  if (request == FIONREAD) {
    // According to "man ioctl_list", FIONREAD stores its value as an int*.
    int* argp = va_arg(ap, int*);
    *argp = 0;
    off64_t pos = this->lseek(0, SEEK_CUR);
    if (pos == -1) {
      ALOGE("lseek(cur) returned error %d", errno);
      errno = EINVAL;
      return -1;
    }
    struct stat st;
    if (this->fstat(&st)) {
      ALOGE("fstat() returned error %d", errno);
      errno = EINVAL;
      return -1;
    }
    if (pos < st.st_size)
      *argp = (st.st_size - pos);
    return 0;
  }
  ALOGE("ioctl command %d not supported\n", request);
  errno = EINVAL;
  return -1;
}

const char* PepperFile::GetStreamType() const {
  return "pepper";
}

size_t PepperFile::GetSize() const {
  struct stat st;
  if (const_cast<PepperFile*>(this)->fstat(&st))
    return 0;  // unknown size
  return st.st_size;
}

}  // namespace posix_translation
