Exemple #1
0
CryDevice::BlobWithParent CryDevice::LoadBlobWithParent(const bf::path &path) {
  optional<unique_ref<DirBlobRef>> parentBlob = none;
  optional<unique_ref<FsBlobRef>> currentBlobOpt = _fsBlobStore->load(_rootKey);
  if (currentBlobOpt == none) {
    LOG(ERROR) << "Could not load root blob. Is the base directory accessible?";
    throw FuseErrnoException(EIO);
  }
  unique_ref<FsBlobRef> currentBlob = std::move(*currentBlobOpt);

  for (const bf::path &component : path.relative_path()) {
    auto currentDir = dynamic_pointer_move<DirBlobRef>(currentBlob);
    if (currentDir == none) {
      throw FuseErrnoException(ENOTDIR); // Path component is not a dir
    }

    auto childOpt = (*currentDir)->GetChild(component.c_str());
    if (childOpt == boost::none) {
      throw FuseErrnoException(ENOENT); // Child entry in directory not found
    }
    Key childKey = childOpt->key();
    auto nextBlob = _fsBlobStore->load(childKey);
    if (nextBlob == none) {
      throw FuseErrnoException(ENOENT); // Blob for directory entry not found
    }
    parentBlob = std::move(*currentDir);
    currentBlob = std::move(*nextBlob);
  }

  return BlobWithParent{std::move(currentBlob), std::move(parentBlob)};

  //TODO (I think this is resolved, but I should test it)
  //     Running the python script, waiting for "Create files in sequential order...", then going into dir ~/tmp/cryfs-mount-.../Bonnie.../ and calling "ls"
  //     crashes cryfs with a sigsegv.
  //     Possible reason: Many parallel changes to a directory blob are a race condition. Need something like ParallelAccessStore!
}
Exemple #2
0
void CryNode::rename(const bf::path &to) {
  device()->callFsActionCallbacks();
  if (_parent == none) {
    //We are the root direcory.
    throw FuseErrnoException(EBUSY);
  }
  auto targetDirWithParent = _device->LoadDirBlobWithParent(to.parent_path());
  auto targetDir = std::move(targetDirWithParent.blob);
  auto targetDirParent = std::move(targetDirWithParent.parent);

  auto old = (*_parent)->GetChild(_key);
  if (old == boost::none) {
    throw FuseErrnoException(EIO);
  }
  fsblobstore::DirEntry oldEntry = *old; // Copying this (instead of only keeping the reference) is necessary, because the operations below (i.e. RenameChild()) might make a reference invalid.
  auto onOverwritten = [this] (const blockstore::Key &key) {
      device()->RemoveBlob(key);
  };
  _updateParentModificationTimestamp();
  if (targetDir->key() == (*_parent)->key()) {
    targetDir->RenameChild(oldEntry.key(), to.filename().native(), onOverwritten);
  } else {
    _updateTargetDirModificationTimestamp(*targetDir, std::move(targetDirParent));
    targetDir->AddOrOverwriteChild(to.filename().native(), oldEntry.key(), oldEntry.type(), oldEntry.mode(), oldEntry.uid(), oldEntry.gid(),
                                   oldEntry.lastAccessTime(), oldEntry.lastModificationTime(), onOverwritten);
    (*_parent)->RemoveChild(oldEntry.name());
    // targetDir is now the new parent for this node. Adapt to it, so we can call further operations on this node object.
    _parent = cpputils::to_unique_ptr(std::move(targetDir));
  }
}
Exemple #3
0
void CryDevice::RemoveBlob(const blockstore::Key &key) {
  auto blob = _fsBlobStore->load(key);
  if (blob == none) {
    LOG(ERROR) << "Could not load blob " << key.ToString() << ". Is the base directory accessible?";
    throw FuseErrnoException(EIO);
  }
  _fsBlobStore->remove(std::move(*blob));
}
Exemple #4
0
unique_ref<FsBlobRef> CryDevice::LoadBlob(const blockstore::Key &key) {
  auto blob = _fsBlobStore->load(key);
  if (blob == none) {
    LOG(ERROR) << "Could not load blob " << key.ToString() << ". Is the base directory accessible?";
    throw FuseErrnoException(EIO);
  }
  return std::move(*blob);
}
Exemple #5
0
CryDevice::DirBlobWithParent CryDevice::LoadDirBlobWithParent(const bf::path &path) {
  auto blob = LoadBlobWithParent(path);
  auto dir = dynamic_pointer_move<DirBlobRef>(blob.blob);
  if (dir == none) {
    throw FuseErrnoException(ENOTDIR); // Loaded blob is not a directory
  }
  return DirBlobWithParent{std::move(*dir), std::move(blob.parent)};
}
Exemple #6
0
void CryNode::chown(uid_t uid, gid_t gid) {
  device()->callFsActionCallbacks();
  if (_parent == none) {
	//We are the root direcory.
	//TODO What should we do?
	throw FuseErrnoException(EIO);
  }
  (*_parent)->chownChild(_key, uid, gid);
}
Exemple #7
0
void CryNode::chmod(mode_t mode) {
  device()->callFsActionCallbacks();
  if (_parent == none) {
    //We are the root direcory.
	//TODO What should we do?
	throw FuseErrnoException(EIO);
  }
  (*_parent)->chmodChild(_key, mode);
}
Exemple #8
0
void CryNode::utimens(timespec lastAccessTime, timespec lastModificationTime) {
  device()->callFsActionCallbacks();
  if (_parent == none) {
    //We are the root direcory.
    //TODO What should we do?
    throw FuseErrnoException(EIO);
  }
  (*_parent)->utimensChild(_key, lastAccessTime, lastModificationTime);
}
Exemple #9
0
void CryNode::removeNode() {
  //TODO Instead of all these if-else and having _parent being an optional, we could also introduce a CryRootDir which inherits from fspp::Dir.
  if (_parent == none) {
    //We are the root direcory.
    //TODO What should we do?
    throw FuseErrnoException(EIO);
  }
  (*_parent)->RemoveChild(_key);
  _device->RemoveBlob(_key);
}
Exemple #10
0
void CryNode::rename(const bf::path &to) {
  device()->callFsActionCallbacks();
  if (_parent == none) {
    //We are the root direcory.
    //TODO What should we do?
    throw FuseErrnoException(EIO);
  }
  //TODO More efficient implementation possible: directly rename when it's actually not moved to a different directory
  //     It's also quite ugly code because in the parent==targetDir case, it depends on _parent not overriding the changes made by targetDir.
  auto old = (*_parent)->GetChild(_key);
  auto mode = old.mode;
  auto uid = old.uid;
  auto gid = old.gid;
  (*_parent)->RemoveChild(_key);
  (*_parent)->flush();
  auto targetDir = _device->LoadDirBlob(to.parent_path());
  targetDir->AddChild(to.filename().native(), _key, getType(), mode, uid, gid);
}
Exemple #11
0
void CryNode::utimens(const timespec times[2]) {
  device()->callFsActionCallbacks();
  //TODO
  throw FuseErrnoException(ENOTSUP);
}
Exemple #12
0
void CryNode::access(int mask) const {
  device()->callFsActionCallbacks();
  //TODO
  return;
  throw FuseErrnoException(ENOTSUP);
}