diff --git a/repos/gems/lib/mk/vfs_cow.mk b/repos/gems/lib/mk/vfs_cow.mk
deleted file mode 100644
index 704d50993d..0000000000
--- a/repos/gems/lib/mk/vfs_cow.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-SRC_CC = vfs_cow.cc
-
-vpath %.cc $(REP_DIR)/src/lib/vfs/cow
-
-SHARED_LIB = yes
diff --git a/repos/gems/recipes/src/vfs_cow/content.mk b/repos/gems/recipes/src/vfs_cow/content.mk
deleted file mode 100644
index 85316766e4..0000000000
--- a/repos/gems/recipes/src/vfs_cow/content.mk
+++ /dev/null
@@ -1,9 +0,0 @@
-MIRROR_FROM_REP_DIR := lib/mk/vfs_cow.mk src/lib/vfs/cow
-
-content: $(MIRROR_FROM_REP_DIR) LICENSE
-
-$(MIRROR_FROM_REP_DIR):
- $(mirror_from_rep_dir)
-
-LICENSE:
- cp $(GENODE_DIR)/LICENSE $@
diff --git a/repos/gems/recipes/src/vfs_cow/hash b/repos/gems/recipes/src/vfs_cow/hash
deleted file mode 100644
index 30665094ed..0000000000
--- a/repos/gems/recipes/src/vfs_cow/hash
+++ /dev/null
@@ -1 +0,0 @@
-2018-07-25 641bf4f2645b2d000ce771aebf85b60eb0d2d3ad
diff --git a/repos/gems/recipes/src/vfs_cow/used_apis b/repos/gems/recipes/src/vfs_cow/used_apis
deleted file mode 100644
index 6069d79557..0000000000
--- a/repos/gems/recipes/src/vfs_cow/used_apis
+++ /dev/null
@@ -1,4 +0,0 @@
-base
-os
-so
-vfs
diff --git a/repos/gems/run/fs_report_cow.run b/repos/gems/run/fs_report_cow.run
deleted file mode 100644
index ba884a1e51..0000000000
--- a/repos/gems/run/fs_report_cow.run
+++ /dev/null
@@ -1,107 +0,0 @@
-#
-# Build
-#
-set build_components {
- core init drivers/timer
- lib/vfs/cow
- server/fs_report
- server/fs_rom
- server/vfs
- test/fs_report
-}
-
-build $build_components
-
-create_boot_directory
-
-#
-# Generate config
-#
-append config {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-}
-
-install_config $config
-
-#
-# Boot modules
-#
-set boot_modules {
- core ld.lib.so init timer
- fs_report
- fs_rom
- test-fs_report
- vfs
- vfs_cow.lib.so
- vfs.lib.so
-}
-
-build_boot_image $boot_modules
-
-append qemu_args " -nographic"
-
-run_genode_until {child "test-fs_report" exited with exit value 0.*\n} 30
diff --git a/repos/gems/src/lib/vfs/cow/target.mk b/repos/gems/src/lib/vfs/cow/target.mk
deleted file mode 100644
index 45b163b26f..0000000000
--- a/repos/gems/src/lib/vfs/cow/target.mk
+++ /dev/null
@@ -1,2 +0,0 @@
-TARGET = dummy-vfs_cow
-LIBS = vfs_cow
diff --git a/repos/gems/src/lib/vfs/cow/vfs_cow.cc b/repos/gems/src/lib/vfs/cow/vfs_cow.cc
deleted file mode 100644
index 2e71dd501f..0000000000
--- a/repos/gems/src/lib/vfs/cow/vfs_cow.cc
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * \brief Copy-on-write file-system
- * \author Emery Hemingway
- * \date 2018-03-22
- */
-
-/*
- * Copyright (C) 2018 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _SRC__VFS__COW_FILE_SYSTEM_H_
-#define _SRC__VFS__COW_FILE_SYSTEM_H_
-
-#include
-#include
-#include
-#include
-
-
-namespace Vfs_cow {
- using namespace Vfs;
- using namespace Genode;
- class File_system;
-}
-
-
-class Vfs_cow::File_system : public Vfs::File_system
-{
- private:
-
- static Absolute_path _config_path(Genode::Xml_node &node, char const *key)
- {
- Genode::String str{};
- node.attribute(key).value(&str);
- return Absolute_path(str.string());
- }
-
- Genode::Allocator &_alloc;
- Vfs::File_system &_root_dir;
- Genode::Entrypoint &_ep;
-
- Absolute_path const _ro_root_path;
- Absolute_path const _rw_root_path;
-
- inline Absolute_path _ro_path(char const *path) const {
- return Absolute_path(path+1, _ro_root_path.string()); }
-
- inline Absolute_path _rw_path(char const *path) const {
- return Absolute_path(path+1, _rw_root_path.string()); }
-
- inline bool _leaf(Absolute_path const &path) {
- return _root_dir.leaf_path(path.string()) != nullptr; }
-
- inline bool _ro_leaf(char const *path) {
- return _leaf(_ro_path(path)); }
-
- inline bool _rw_leaf(char const *path) {
- return _leaf(_ro_path(path)); }
-
- void _mkdirs(Absolute_path const &path)
- {
- Vfs_handle *dir_handle = nullptr;
- Opendir_result res = _root_dir.opendir(
- path.string(), true, &dir_handle, _alloc);
- if (res == OPENDIR_ERR_LOOKUP_FAILED) {
- Absolute_path parent(path);
- parent.strip_last_element();
- _mkdirs(parent);
- _root_dir.opendir(path.string(), true, &dir_handle, _alloc);
- }
- if (dir_handle) dir_handle->ds().close(dir_handle);
- }
-
- bool _copy(Absolute_path const &from, Absolute_path const &to)
- {
- Vfs_handle *roh = nullptr;
- Vfs_handle *rwh = nullptr;
-
- _root_dir.open(
- from.string(), OPEN_MODE_RDONLY, &roh, _alloc);
- if (!roh)
- return false;
-
- _root_dir.open(
- to.string(), OPEN_MODE_WRONLY|OPEN_MODE_CREATE, &rwh, _alloc);
-
- if (!rwh) {
- roh->ds().close(roh);
- return false;
- }
-
- if (!roh || !rwh)
- {
- return false;
- }
-
- char buf[1<<14];
- Stat sb { };
- _root_dir.stat(from.string(), sb);
- file_size remain = sb.size;
-
- while (remain > 0) {
- file_size rn = 0;
- file_size wn = 0;
-
- while (!roh->fs().queue_read(roh, sizeof(buf))) {
- warning("COW: blocking for replication...");
- _ep.wait_and_dispatch_one_io_signal();
- }
-
- Read_result rres = roh->fs().complete_read(
- roh, buf, sizeof(buf), rn);
- switch (rres) {
- case READ_OK: break;
- case READ_QUEUED: continue;
- default: remain = -1; continue;
- }
-
- Write_result wres = rwh->fs().write(rwh, buf, rn, wn);
- switch (wres) {
- case WRITE_OK: break;
- case WRITE_ERR_AGAIN:
- case WRITE_ERR_WOULD_BLOCK:
- continue;
- default:
- _root_dir.unlink(from.string());
- remain = -1; continue;
- }
-
- roh->advance_seek(wn);
- rwh->advance_seek(wn);
- remain -= wn;
- }
-
- roh->ds().close(roh);
- rwh->ds().close(rwh);
- bool res = (remain == 0);
- if (res)
- log("COW: replicated from ", from, " to ", to);
- else
- error("COW: replication from ", from, " to ", to, " failed");
- return res;
- }
-
- struct Cow_dir_handle : Vfs::Vfs_handle
- {
- Vfs_handle &ro;
- Vfs_handle &rw;
-
- Absolute_path const rw_leaf;
-
- Cow_dir_handle(Vfs::File_system &fs,
- Genode::Allocator &alloc,
- Vfs_handle &roh,
- Vfs_handle &rwh,
- char const *rw_leaf)
- : Vfs_handle(fs, fs, alloc, 0), ro(roh), rw(rwh), rw_leaf(rw_leaf) { }
-
- ~Cow_dir_handle()
- {
- ro.ds().close(&ro);
- rw.ds().close(&rw);
- }
-
- /**
- * Apply an operation to the RW or RO handle
- * depending on current seek position.
- */
- template
- void apply_seek(FN const &fn)
- {
- file_size const index = seek() / sizeof(Dirent);
- file_size const rw_dirents = rw.ds().num_dirent(rw_leaf.string());
-
- /* read from RW directory first */
- if (index < rw_dirents) {
- rw.seek(index);
- fn(rw);
- } else {
- ro.seek(index - rw_dirents);
- fn(ro);
- }
- }
- };
-
- public:
-
- File_system(Vfs::Env &vfs_env, Genode::Xml_node config)
- :
- _alloc(vfs_env.alloc()),
- _root_dir(vfs_env.root_dir()),
- _ep(vfs_env.env().ep()),
- _ro_root_path(_config_path(config, "ro")),
- _rw_root_path(_config_path(config, "rw"))
- { }
-
- const char* type() override { return "cow"; }
-
- static const char* name() { return "cow"; }
-
- /***********************
- ** Directory service **
- ***********************/
-
- Genode::Dataspace_capability dataspace(const char *path) override
- {
- auto rw_path = _rw_path(path);
- if (_leaf(rw_path)) {
- return _root_dir.dataspace(rw_path.string());
- } else {
- auto ro_path = _ro_path(path);
- return _root_dir.dataspace(ro_path.string());
- }
- }
-
- void release(char const *path, Dataspace_capability ds) override
- {
- _root_dir.release(_ro_path(path).string(), ds);
- _root_dir.release(_rw_path(path).string(), ds);
- }
-
- Open_result open(const char *path,
- unsigned int mode,
- Vfs::Vfs_handle **out,
- Genode::Allocator &alloc) override
- {
- auto ro_path = _ro_path(path);
- auto rw_path = _rw_path(path);
-
- if (mode & OPEN_MODE_CREATE) {
- if (_leaf(ro_path)) {
- return OPEN_ERR_EXISTS;
- } else {
- return _root_dir.open(
- rw_path.string(), mode, out, alloc);
- }
- }
-
- Open_result rw_res = _root_dir.open(
- rw_path.string(), mode, out, alloc);
-
- if (rw_res == OPEN_ERR_UNACCESSIBLE) {
- _copy(ro_path, rw_path);
- rw_res = _root_dir.open(
- rw_path.string(), mode, out, alloc);
- }
-
- return rw_res;
- }
-
- Opendir_result opendir(char const *path, bool create,
- Vfs_handle **out, Allocator &alloc) override
- {
- auto ro_path = _ro_path(path);
- auto rw_path = _rw_path(path);
- Opendir_result res = OPENDIR_ERR_PERMISSION_DENIED;
-
- if (!_leaf(ro_path)) {
- return _root_dir.opendir(
- rw_path.string(), create, out, alloc);
- }
-
- if (create)
- return OPENDIR_ERR_NODE_ALREADY_EXISTS;
-
- {
- Vfs_handle *roh = nullptr;
- Vfs_handle *rwh = nullptr;
-
- res = _root_dir.opendir(
- ro_path.string(), false, &roh, alloc);
-
- if (res != OPENDIR_OK)
- return res;
-
- char const *rw_leaf = _root_dir.leaf_path(rw_path.string());
- if (!rw_leaf) {
- _mkdirs(rw_path);
- rw_leaf = _root_dir.leaf_path(rw_path.string());
- }
-
- res = _root_dir.opendir(
- rw_path.string(), false, &rwh, alloc);
-
- if (res != OPENDIR_OK) {
- roh->ds().close(roh);
- return res;
- }
-
- *out = new (alloc)
- Cow_dir_handle(*this, alloc, *roh, *rwh, rw_leaf);
- return OPENDIR_OK;
- }
- }
-
- void close(Vfs::Vfs_handle *vfs_handle) override
- {
- if (&vfs_handle->ds() == this) {
- Cow_dir_handle *h = static_cast(vfs_handle);
- destroy(h->alloc(), h);
- } else {
- Genode::error("unknown handle");
- }
- }
-
- Watch_result watch(char const *path,
- Vfs_watch_handle **out,
- Allocator &alloc) override
- {
- auto const rw_path = _rw_path(path);
- if (!_leaf(rw_path)) {
- if (_root_dir.directory(_ro_path(path).string())) {
- _mkdirs(rw_path);
- } else {
- return WATCH_ERR_UNACCESSIBLE;
- }
- }
- return _root_dir.watch(rw_path.string(), out, alloc);
- }
-
- Stat_result stat(const char *path, Vfs::Directory_service::Stat &buf) override
- {
- Stat_result res = _root_dir.stat(_rw_path(path).string(), buf);
- if (res != STAT_OK)
- res = _root_dir.stat(_ro_path(path).string(), buf);
- return res;
- }
-
- Unlink_result unlink(const char *path) override
- {
- if (_ro_leaf(path))
- return UNLINK_ERR_NO_PERM;
- return _root_dir.unlink(_rw_path(path).string());
- }
-
- Rename_result rename(const char *from , const char *to) override
- {
- return _root_dir.rename(
- _rw_path(from).string(), _rw_path(to).string());
- }
-
- file_size num_dirent(const char *path) override
- {
- /* return a simple sum */
- return
- _root_dir.num_dirent(_rw_path(path).string())+
- _root_dir.num_dirent(_ro_path(path).string());
- }
-
- bool directory(char const *path) override
- {
- return _root_dir.directory(_ro_path(path).string()) ?
- true : _root_dir.directory(_rw_path(path).string());
- }
-
- const char* leaf_path(const char *path) override
- {
- char const *res = _root_dir.leaf_path(_ro_path(path).string());
- if (res == nullptr)
- res = _root_dir.leaf_path(_rw_path(path).string());
- return res;
- }
-
- /**********************
- ** File I/O service **
- **********************/
-
- Write_result write(Vfs_handle*,
- const char*, file_size,
- file_size&) override
- {
- return WRITE_ERR_INVALID;
- }
-
- bool queue_read(Vfs_handle *vfs_handle, file_size len) override
- {
- bool res = true;
- Cow_dir_handle *handle =
- dynamic_cast(vfs_handle);
- if (handle)
- handle->apply_seek([&] (Vfs_handle &dir) {
- res = dir.fs().queue_read(&dir, len);
- });
- return res;
- }
-
- Read_result complete_read(Vfs_handle *vfs_handle,
- char *buf, file_size len,
- file_size &out) override
- {
- Read_result res = READ_ERR_INVALID;
- Cow_dir_handle *handle =
- dynamic_cast(vfs_handle);
- if (handle)
- handle->apply_seek([&] (Vfs_handle &dir) {
- res = dir.fs().complete_read(&dir, buf, len, out);
- });
- return res;
- }
-
- bool read_ready(Vfs_handle *vfs_handle) override
- {
- bool res = true;
- Cow_dir_handle *handle =
- dynamic_cast(vfs_handle);
- if (handle)
- handle->apply_seek([&] (Vfs_handle &dir) {
- res = dir.fs().read_ready(&dir);
- });
- return res;
- }
-
- bool notify_read_ready(Vfs_handle *vfs_handle) override
- {
- bool res = true;
- Cow_dir_handle *handle =
- dynamic_cast(vfs_handle);
- if (handle)
- handle->apply_seek([&] (Vfs_handle &dir) {
- res = dir.fs().notify_read_ready(&dir);
- });
- return res;
- }
-
- Ftruncate_result ftruncate(Vfs_handle*, file_size) override {
- return FTRUNCATE_ERR_NO_PERM; }
-
- bool check_unblock(Vfs_handle *vfs_handle, bool rd, bool wr, bool ex) override
- {
- bool res = true;
- Cow_dir_handle *handle =
- dynamic_cast(vfs_handle);
- if (handle)
- handle->apply_seek([&] (Vfs_handle &dir) {
- res = dir.fs().check_unblock(&dir, rd, wr, ex);
- });
- return res;
- }
-
- void register_read_ready_sigh(Vfs_handle *vfs_handle, Signal_context_capability sigh) override
- {
- Cow_dir_handle *handle =
- dynamic_cast(vfs_handle);
- if (handle) {
- handle->rw.fs().register_read_ready_sigh(&handle->rw, sigh);
- handle->ro.fs().register_read_ready_sigh(&handle->ro, sigh);
- }
- }
-
- bool queue_sync(Vfs_handle *vfs_handle) override
- {
- bool res = true;
- Cow_dir_handle *handle =
- dynamic_cast(vfs_handle);
- if (handle)
- handle->apply_seek([&] (Vfs_handle &dir) {
- res = dir.fs().queue_sync(&dir);
- });
- return res;
- }
-
- Sync_result complete_sync(Vfs_handle *vfs_handle) override
- {
- Sync_result res = SYNC_OK;
- Cow_dir_handle *handle =
- dynamic_cast(vfs_handle);
- if (handle)
- handle->apply_seek([&] (Vfs_handle &dir) {
- res = dir.fs().complete_sync(&dir);
- });
- return res;
- }
-};
-
-
-/**************************
- ** VFS plugin interface **
- **************************/
-
-extern "C" Vfs::File_system_factory *vfs_file_system_factory(void)
-{
- struct Factory : Vfs::File_system_factory
- {
- Vfs::File_system *create(Vfs::Env &vfs_env,
- Genode::Xml_node node) override
- {
- return new (vfs_env.alloc())
- Vfs_cow::File_system(vfs_env, node);
- }
- };
-
- static Factory factory;
- return &factory;
-}
-
-
-#endif /* _SRC__VFS__COW_FILE_SYSTEM_H_ */