Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Import VFS FUSE plugin from ticket193_patch-1.zip
- Loading branch information
Showing
7 changed files
with
1,385 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
The fuse vfs plug-in provides access to a FUSE based file system. Like other | ||
vfs plug-ins, it may be either located directly in the client application, or | ||
within a file-system server. | ||
|
||
The plug-in implementation is independent from each | ||
FUSE based file system. fuse vfs only calls the FUSE operation in question | ||
directly. These operations are provided by the FUSE file system and Genode's | ||
libfuse library makes sure, that each operation is executable, e.g. by using | ||
a dummy function in case it is not provided by the FUSE file system. | ||
Therefore, to utilize a FUSE file system, the FUSE file system is linked | ||
against libfuse as well as vfs_fuse. For each fuse vfs plug-in there is | ||
a binary (.e.g. 'world/src/lib/vfs/fuse/ext2'). | ||
|
||
Note: write-support is supported but considered to be experimantal at this | ||
point and for now using it is NOT recommended. | ||
|
||
To use the ext2_fuse plug-in the following config snippet may be used: | ||
|
||
! <start name="fs"> | ||
! <resource name="RAM" quantum="8M"/> XXX | ||
! <config> | ||
! <policy label_prefix="noux -> fuse" root="/" writeable="no" /> XXXX | ||
! <vfs> | ||
! <dir name="dev"> | ||
! <block name="sda1"/> <!-- handles block session to real block device --> | ||
! </dir> | ||
! <dir name="fs"> | ||
! <fuse-ext2fs block_path="/dev/sda1"/> | ||
! </dir> | ||
! </vfs> | ||
! </config> | ||
! </start> | ||
|
||
|
||
xxx///FIXME: we don't provide a setting to toggle r/o or r/w policy, unlike the previous implementation.. Should we? | ||
|
||
This is a work-in-progress; among the tech debt that is still to be repaid to | ||
bring it up to Genode standards, one should mention: | ||
|
||
TODO: | ||
- rename plug-in from "fuse" to "fuse-ntfs-3g" etc | ||
- add support for ext2fs and exfat (in theory this should be straightfoward, | ||
using as guidelines the diffs that enabled ntfs-3g support) | ||
- stub out the remainder of LibC (the one that can be left out when running in | ||
a libc-using host, but will be required when running in an fs server) | ||
|
||
|
||
Additionally, during the course of migrating FUSE from a server to a vfs plug-in, | ||
some ideas came up to make the test-suite even more robust: | ||
|
||
TODO: test suite: | ||
- add opendir tests | ||
- add stat() tests after each mkdir()/rmdir() tests, to check for functions that return OK even though they didn't perform their task. | ||
- repeatedly open()/close(), for ca. 256+10 time, to check for fd leaks (i.e. if the plug-in fails to release() file descriptors) | ||
|
||
|
||
|
||
How to build: | ||
(/// Remove this, build instructions are not generally provided in READMEs): | ||
- make -C build/x86_64 KERNEL=nova BOARD=pc LIB=vfs_fuse | ||
- make -C build/x86_64 KERNEL=nova BOARD=pc run/libc_vfs_ntfs-3g_fuse_fs | ||
|
165 changes: 165 additions & 0 deletions
165
src/lib/vfs/fuse/_d_ block_dev.h _delete, let's use VfsBlockFs instead_
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
/* | ||
* Copyright (C) 2021 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. | ||
*/ | ||
|
||
|
||
|
||
#pragma once | ||
|
||
|
||
#error give up on this -- it works well for reads, but wont handle non-aligned-writes... Use "VfsBlock.." system instead, which handles that for us | ||
|
||
|
||
/* Genode includes */ | ||
#include <base/allocator.h> | ||
#include <base/allocator_avl.h> | ||
#include <base/log.h> | ||
#include <block_session/connection.h> | ||
|
||
/* libc includes */ | ||
#include <errno.h> // EACCESS etc | ||
|
||
|
||
|
||
|
||
static void dump( const char * buf, int size ) | ||
{ | ||
for( int i = 0; i < size; i++ ) | ||
{ | ||
// Genode::log( buf[i] ); | ||
} | ||
} | ||
|
||
|
||
///ToDo: the Block::Connection API is deprecated (see ticket #193) | ||
// use eg API used in this instead: os/src/server/part_block/partition_table.h | ||
|
||
struct WholeBlock_Read | ||
{ | ||
// Fuse-NTFS might request "partial" blocks in pread(), but a Block session | ||
// is "all or nothing", it can only read whole blocks (i.e. multiples of | ||
// 512 bytes), so delegate block access to this subclass, and the caller | ||
// will call memcpy() on a subset of the whole block bytes if needed. | ||
WholeBlock_Read(Block::Connection<> & block, int64_t bytecount, int64_t offset) | ||
: _block( block ), | ||
_packet(), | ||
buffer( nullptr ) | ||
{ | ||
Genode::size_t const sector_size = _block.info().block_size; | ||
|
||
// Calculate the "rounded" bytesize (might differ from bytecount) | ||
// | ||
Genode::size_t const sector_count = (bytecount + sector_size-1)/sector_size;// * _block.info().block_size; | ||
Genode::size_t const bytesize = sector_count * sector_size; | ||
|
||
// Genode::log( " reading ", sector_count, " blocks starting from block #", offset/sector_size ); | ||
|
||
//assert(offset); | ||
if (offset % sector_size != 0) | ||
Genode::error ("offset is not a multiple of sector size ! not implemented !"); | ||
|
||
_packet.construct( | ||
_block.tx()->alloc_packet(bytesize), | ||
Block::Packet_descriptor::READ, | ||
offset/sector_size, // asserted above | ||
sector_count); | ||
_block.tx()->submit_packet(*_packet); | ||
*_packet = _block.tx()->get_acked_packet(); | ||
|
||
if (_packet->succeeded() && _packet->size() == bytesize) { | ||
buffer = _block.tx()->packet_content(*_packet); | ||
} else { | ||
Genode::error(__func__, " failed at sector ", offset/sector_size, " -- p.size: ", _packet->size());//sector, ", bytecount ", bytecount); | ||
} | ||
} | ||
|
||
~WholeBlock_Read() | ||
{ | ||
_block.tx()->release_packet(*_packet); | ||
} | ||
|
||
// in | ||
Block::Connection<> & _block; | ||
|
||
// out | ||
Genode::Constructible<Block::Packet_descriptor> _packet; | ||
const char * buffer; | ||
}; | ||
|
||
struct Blockdev | ||
{ | ||
Genode::Env &_env; | ||
Genode::Allocator &_alloc; | ||
Genode::Allocator_avl _tx_alloc { &_alloc }; | ||
|
||
Block::Connection<> _block { _env, &_tx_alloc, 512*1024 }; | ||
Block::Session::Info const _info { _block.info() }; | ||
|
||
Blockdev(Genode::Env &env, Genode::Allocator &alloc) | ||
: _env(env), _alloc(alloc) { } | ||
|
||
int pwrite(const void * buf, uint64_t bytesize, int64_t byteoffset) | ||
{ | ||
if (!_block.info().writeable) { return 0; } | ||
|
||
Genode::size_t const sector_size = _block.info().block_size; | ||
|
||
//assert(writing exactly whole blocks); | ||
//otherwise let's leave it to the CALLER to de-derp... | ||
if (byteoffset % sector_size != 0) | ||
Genode::error ("pwrite: offset is not a multiple of sector size ! not implemented !"); | ||
if (bytesize % sector_size != 0) | ||
Genode::error ("pwrite: count is not a multiple of sector size ! not implemented !"); | ||
|
||
Block::Packet_descriptor p(_block.tx()->alloc_packet(bytesize), | ||
Block::Packet_descriptor::WRITE, | ||
byteoffset/sector_size, // asserted above | ||
bytesize/sector_size); | ||
_block.tx()->submit_packet(p); | ||
p = _block.tx()->get_acked_packet(); | ||
|
||
if (p.succeeded() && p.size() == bytesize) { | ||
//result = EOK; | ||
} else { | ||
Genode::error(__func__, " failed at sector ", byteoffset/sector_size, " -- p.size: ", p.size()); | ||
} | ||
|
||
_block.tx()->release_packet(p); | ||
|
||
return bytesize; | ||
} | ||
|
||
int pread(void * buf, int64_t count, int64_t offset) | ||
{ | ||
//Genode::log( " reading ", count, " bytes at byte-offset: ", offset ); | ||
|
||
int result = 0; // default to failure (zero bytes read) | ||
#if 0 | ||
if (p.succeeded() && p.size() == bytesize) { | ||
char const * const content = _block.tx()->packet_content(p); | ||
dump(content, bytesize); | ||
Genode::memcpy(buf, content, bytesize); | ||
result = bytesize;//0;//EOK; | ||
} else { | ||
Genode::error(__func__, " failed at sector ", offset/sector_size, " -- p.size: ", p.size());//sector, ", count ", count); | ||
//Genode::error("could not read lba: ", lba, " count: ", count); | ||
} | ||
#else | ||
WholeBlock_Read whole( _block, count, offset ); | ||
if (whole.buffer) { | ||
dump(whole.buffer, count); | ||
Genode::memcpy(buf, whole.buffer, count); // count is inferior or equal to packet.size() | ||
return count; | ||
} else { | ||
//return 0; | ||
} | ||
#endif | ||
|
||
return result; | ||
} | ||
}; | ||
|
||
|
16 changes: 16 additions & 0 deletions
16
src/lib/vfs/fuse/_d_(done?)libc_vfs_fs_fuse-ntfs-3g.run (Move To Run Dir!)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
if {[get_cmd_switch --autopilot] && [have_board riscv_qemu]} { | ||
puts "Autopilot mode is not supported on this platform." | ||
exit 0 | ||
} | ||
|
||
set mkfs_cmd [error use mkfs.ntfs or such] | ||
#set mkfs_cmd [installed_command mkfs.vfat] | ||
#set mkfs_opts "-F32 -nlibc_vfs" | ||
|
||
set test_build_components lib/vfs/fusefs-ntfs-3g | ||
set test_vfs_config "<fusefs-ntfs-3g/>" | ||
set test_boot_modules fusefs-ntfs-3g.lib.so | ||
|
||
set use_vfs_server 1 | ||
|
||
source ${genode_dir}/repos/libports/run/libc_vfs_filesystem_test.inc |
Oops, something went wrong.