libports: extend FUSE implementation

* add sync method:
  Since file systems tend to have a inbuild caching mechansim we need to
  sync these caches at the end of session when using the fuse_fs server.
  Therefore each FUSE file system port has to implement a Fuse::sync_fs()
  function that executes the necessary actions if requested.

* add symlink check

* allow to check FUSE fs initialization
  This changes the private API of the FUSE implementation. The init_fs
  method now has to return true if the initialization was successful and
  otherwise false. All current users of the API are also changed
  accordingly.

Fixes #1058.
This commit is contained in:
Josef Söntgen 2013-12-05 11:24:16 +01:00 committed by Christian Helmuth
parent 3b69dc2a58
commit 9f5c13564c
4 changed files with 72 additions and 11 deletions

View File

@ -77,10 +77,37 @@ namespace Fuse {
bool initialized();
/* Genode fuse filesystem init functions */
void init_fs();
/**
* Initialize the file system
*
* Mount the medium containg the file system, e.g. by
* using a Block_session connection, and call the file system
* init function as well as initialize needed fuse structures.
*/
bool init_fs();
/**
* Deinitialize the file system
*
* Unmount the medium, call the file system cleanup function
* and free all fuse structures.
*/
void deinit_fs();
/**
* Synchronize the file system
*
* Request the file system to flush all internal caches
* to disk.
*/
void sync_fs();
/**
* FUSE File system implementation supports symlinks
*/
bool support_symlinks();
/* list of FUSE operations as of version 2.6 */
enum Fuse_operations {
FUSE_OP_GETATTR = 0,
FUSE_OP_READLINK = 1,

View File

@ -29,25 +29,38 @@ struct exfat ef;
}
void Fuse::init_fs(void)
bool Fuse::init_fs(void)
{
PLOG("libc_fuse_exfat: try to mount /dev/blkdev...");
int err = exfat_mount(&ef, "/dev/blkdev", "");
if (err) {
PERR("libc_fuse_exfat: could not mount /dev/blkdev");
return;
return false;
}
fh = fuse_new(fc, NULL, &fuse_exfat_ops, sizeof (struct fuse_operations), NULL);
if (fh == 0) {
PERR("libc_fuse_exfat: fuse_new() failed");
return;
return false;
}
return true;
}
void Fuse::deinit_fs(void)
{
PLOG("libc_fuse_exfat: umount /dev/blkdev...");
exfat_unmount(&ef);
}
void Fuse::sync_fs(void) { }
bool Fuse::support_symlinks(void)
{
return false;
}

View File

@ -36,21 +36,22 @@ static struct extfs_data extfs_data;
}
void Fuse::init_fs(void)
bool Fuse::init_fs(void)
{
PLOG("libc_fuse_ext2: try to mount /dev/blkdev...");
int err = ext2fs_open("/dev/blkdev", EXT2_FLAG_RW, 0, 0, unix_io_manager, &e2fs);
if (err) {
PERR("libc_fuse_ext2: could not mount /dev/blkdev, error: %d", err);
return;
return false;
}
errcode_t rc = ext2fs_read_bitmaps(e2fs);
if (rc) {
PERR("libc_fuse_ext2: error while reading bitmaps");
ext2fs_close(e2fs);
return;
return false;
}
extfs_data.debug = 0;
@ -67,12 +68,28 @@ void Fuse::init_fs(void)
fh = fuse_new(fc, NULL, &ext2fs_ops, sizeof (ext2fs_ops), &extfs_data);
if (fh == 0) {
PERR("libc_fuse_ext2: fuse_new() failed");
return;
return false;
}
return true;
}
void Fuse::deinit_fs(void)
{
PLOG("libc_fuse_ext2: unmount /dev/blkdev...");
ext2fs_close(e2fs);
}
void Fuse::sync_fs(void)
{
PLOG("libc_fuse_ext2: sync file system...");
ext2fs_flush(e2fs);
}
bool Fuse::support_symlinks(void)
{
return true;
}

View File

@ -129,12 +129,16 @@ namespace {
*/
Plugin()
{
Fuse::init_fs();
if (!Fuse::init_fs()) {
PERR("FUSE fs initialization failed");
return;
}
}
~Plugin()
{
Fuse::deinit_fs();
if (Fuse::initialized())
Fuse::deinit_fs();
}
bool supports_mkdir(const char *path, mode_t mode)