mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-20 19:49:28 +00:00
parent
39085f08fc
commit
f113460348
@ -1,161 +0,0 @@
|
||||
/*
|
||||
* \brief libfuse re-implementation public API
|
||||
* \author Josef Soentgen
|
||||
* \date 2013-11-07
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 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 _INCLUDE__FUSE_H_
|
||||
#define _INCLUDE__FUSE_H_
|
||||
|
||||
/* libc includes */
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <utime.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef FUSE_USE_VERSION
|
||||
#define FUSE_USE_VERSION 26
|
||||
#endif
|
||||
|
||||
#if FUSE_USE_VERSION >= 26
|
||||
#define FUSE_VERSION 26
|
||||
#else
|
||||
#error "No support for FUSE_VERSION < 26"
|
||||
#endif
|
||||
|
||||
void fuse_genode(const char*);
|
||||
|
||||
#include "fuse_opt.h"
|
||||
|
||||
struct fuse_chan;
|
||||
struct fuse_args;
|
||||
struct fuse_session;
|
||||
|
||||
struct fuse_file_info {
|
||||
int32_t flags; /* open(2) flags */
|
||||
uint32_t fh_old; /* old file handle */
|
||||
int32_t writepage;
|
||||
uint32_t direct_io:1;
|
||||
uint32_t keep_cache:1;
|
||||
uint32_t flush:1;
|
||||
uint32_t nonseekable:1;
|
||||
uint32_t __padd:27;
|
||||
uint32_t flock_release : 1;
|
||||
uint64_t fh; /* file handle */
|
||||
uint64_t lock_owner;
|
||||
};
|
||||
|
||||
struct fuse_conn_info {
|
||||
uint32_t proto_major;
|
||||
uint32_t proto_minor;
|
||||
uint32_t async_read;
|
||||
uint32_t max_write;
|
||||
uint32_t max_readahead;
|
||||
uint32_t capable;
|
||||
uint32_t want;
|
||||
uint32_t max_background;
|
||||
uint32_t congestion_threshold;
|
||||
uint32_t reserved[23];
|
||||
};
|
||||
|
||||
struct fuse_context {
|
||||
struct fuse *fuse;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
pid_t pid;
|
||||
void *private_data;
|
||||
mode_t umask;
|
||||
};
|
||||
|
||||
typedef ino_t fuse_ino_t;
|
||||
typedef int (*fuse_fill_dir_t)(void *, const char *, const struct stat *, off_t);
|
||||
|
||||
|
||||
|
||||
typedef int (*fuse_dirfil_t)(void *, const char *, int, ino_t);
|
||||
|
||||
/* only operations available in 2.6 */
|
||||
struct fuse_operations {
|
||||
int (*getattr)(const char *, struct stat *);
|
||||
int (*readlink)(const char *, char *, size_t);
|
||||
int (*getdir)(const char *, void *, fuse_dirfil_t);
|
||||
int (*mknod)(const char *, mode_t, dev_t);
|
||||
int (*mkdir)(const char *, mode_t);
|
||||
int (*unlink)(const char *);
|
||||
int (*rmdir)(const char *);
|
||||
int (*symlink)(const char *, const char *);
|
||||
int (*rename)(const char *, const char *);
|
||||
int (*link)(const char *, const char *);
|
||||
int (*chmod)(const char *, mode_t);
|
||||
int (*chown)(const char *, uid_t, gid_t);
|
||||
int (*truncate)(const char *, off_t);
|
||||
int (*utime)(const char *, struct utimbuf *);
|
||||
int (*open)(const char *, struct fuse_file_info *);
|
||||
int (*read)(const char *, char *, size_t, off_t,
|
||||
struct fuse_file_info *);
|
||||
int (*write)(const char *, const char *, size_t, off_t,
|
||||
struct fuse_file_info *);
|
||||
int (*statfs)(const char *, struct statvfs *);
|
||||
int (*flush)(const char *, struct fuse_file_info *);
|
||||
int (*release)(const char *, struct fuse_file_info *);
|
||||
int (*fsync)(const char *, int, struct fuse_file_info *);
|
||||
int (*setxattr)(const char *, const char *, const char *, size_t,
|
||||
int);
|
||||
int (*getxattr)(const char *, const char *, char *, size_t);
|
||||
int (*listxattr)(const char *, char *, size_t);
|
||||
int (*removexattr)(const char *, const char *);
|
||||
int (*opendir)(const char *, struct fuse_file_info *);
|
||||
int (*readdir)(const char *, void *, fuse_fill_dir_t, off_t,
|
||||
struct fuse_file_info *);
|
||||
int (*releasedir)(const char *, struct fuse_file_info *);
|
||||
int (*fsyncdir)(const char *, int, struct fuse_file_info *);
|
||||
void *(*init)(struct fuse_conn_info *);
|
||||
void (*destroy)(void *);
|
||||
int (*access)(const char *, int);
|
||||
int (*create)(const char *, mode_t, struct fuse_file_info *);
|
||||
int (*ftruncate)(const char *, off_t, struct fuse_file_info *);
|
||||
int (*fgetattr)(const char *, struct stat *, struct fuse_file_info *);
|
||||
int (*lock)(const char *, struct fuse_file_info *, int, struct flock *);
|
||||
int (*utimens)(const char *, const struct timespec *);
|
||||
int (*bmap)(const char *, size_t , uint64_t *);
|
||||
};
|
||||
|
||||
/* API */
|
||||
int fuse_version(void);
|
||||
struct fuse *fuse_new(struct fuse_chan *, struct fuse_args *,
|
||||
const struct fuse_operations *, size_t, void *);
|
||||
void fuse_destroy(struct fuse *);
|
||||
void fuse_exit(struct fuse *f);
|
||||
struct fuse_session *fuse_get_session(struct fuse *);
|
||||
struct fuse_context *fuse_get_context(void);
|
||||
int fuse_loop(struct fuse *);
|
||||
int fuse_loop_mt(struct fuse *);
|
||||
int fuse_main(int, char **, const struct fuse_operations *, void *);
|
||||
struct fuse_chan *fuse_mount(const char *, struct fuse_args *);
|
||||
int fuse_parse_cmdline(struct fuse_args *, char **, int *, int *);
|
||||
void fuse_remove_signal_handlers(struct fuse_session *);
|
||||
int fuse_set_signal_handlers(struct fuse_session *);
|
||||
int fuse_chan_fd(struct fuse_chan *);
|
||||
int fuse_daemonize(int);
|
||||
int fuse_is_lib_option(const char *);
|
||||
void fuse_teardown(struct fuse *, char *);
|
||||
void fuse_unmount(const char *, struct fuse_chan *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _INCLUDE__FUSE_H_ */
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* \brief libfuse public API
|
||||
* \author Josef Soentgen
|
||||
* \date 2013-11-07
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 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 _FUSE_OPT_H_
|
||||
#define _FUSE_OPT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct fuse_opt {
|
||||
const char *templ;
|
||||
unsigned long off;
|
||||
int val;
|
||||
};
|
||||
|
||||
struct fuse_args {
|
||||
int argc;
|
||||
char **argv;
|
||||
int allocated;
|
||||
};
|
||||
|
||||
typedef int (*fuse_opt_proc_t)(void *, const char *, int, struct fuse_args *);
|
||||
int fuse_opt_add_arg(struct fuse_args *, const char *);
|
||||
int fuse_opt_insert_arg(struct fuse_args *, int, const char *);
|
||||
void fuse_opt_free_args(struct fuse_args *);
|
||||
int fuse_opt_add_opt(char **, const char *);
|
||||
int fuse_opt_add_opt_escaped(char **, const char *);
|
||||
int fuse_opt_match(const struct fuse_opt *, const char *);
|
||||
int fuse_opt_parse(struct fuse_args *, void *, struct fuse_opt *,
|
||||
fuse_opt_proc_t);
|
||||
|
||||
#define FUSE_ARGS_INIT(ac, av) { ac, av, 0 }
|
||||
|
||||
#define FUSE_OPT_KEY(t, k) { t, -1, k }
|
||||
#define FUSE_OPT_END { NULL, 0, 0 }
|
||||
#define FUSE_OPT_KEY_OPT -1
|
||||
#define FUSE_OPT_KEY_NONOPT -2
|
||||
#define FUSE_OPT_KEY_KEEP -3
|
||||
#define FUSE_OPT_KEY_DISCARD -4
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FUSE_OPT_H_ */
|
@ -1,154 +0,0 @@
|
||||
/*
|
||||
* \brief libfuse private API
|
||||
* \author Josef Soentgen
|
||||
* \date 2013-11-07
|
||||
* */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 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 _INCLUDE__FUSE_PRIVATE_H_
|
||||
#define _INCLUDE__FUSE_PRIVATE_H_
|
||||
|
||||
#include "fuse.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct fuse_dirhandle;
|
||||
struct fuse_args;
|
||||
|
||||
struct fuse_session {
|
||||
void *args;
|
||||
};
|
||||
|
||||
struct fuse_chan {
|
||||
char *dir;
|
||||
struct fuse_args *args;
|
||||
};
|
||||
|
||||
struct fuse_config {
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
pid_t pid;
|
||||
mode_t umask;
|
||||
int set_mode;
|
||||
int set_uid;
|
||||
int set_gid;
|
||||
};
|
||||
|
||||
typedef struct fuse_dirhandle {
|
||||
fuse_fill_dir_t filler;
|
||||
void *buf;
|
||||
size_t size;
|
||||
off_t offset;
|
||||
} *fuse_dirh_t;
|
||||
|
||||
|
||||
struct fuse {
|
||||
struct fuse_chan *fc;
|
||||
struct fuse_operations op;
|
||||
struct fuse_args *args;
|
||||
|
||||
struct fuse_config conf;
|
||||
struct fuse_session se;
|
||||
|
||||
fuse_fill_dir_t filler;
|
||||
|
||||
void *userdata;
|
||||
|
||||
/* Block_session info */
|
||||
uint32_t block_size;
|
||||
uint64_t block_count;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace Fuse {
|
||||
|
||||
struct fuse* fuse();
|
||||
|
||||
bool initialized();
|
||||
|
||||
/**
|
||||
* 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,
|
||||
FUSE_OP_GETDIR = 2,
|
||||
FUSE_OP_MKNOD = 3,
|
||||
FUSE_OP_MKDIR = 4,
|
||||
FUSE_OP_UNLINK = 5,
|
||||
FUSE_OP_RMDIR = 6,
|
||||
FUSE_OP_SYMLINK = 7,
|
||||
FUSE_OP_RENAME = 8,
|
||||
FUSE_OP_LINK = 9,
|
||||
FUSE_OP_CHMOD = 10,
|
||||
FUSE_OP_CHOWN = 11,
|
||||
FUSE_OP_TRUNCATE = 12,
|
||||
FUSE_OP_UTIME = 13,
|
||||
FUSE_OP_OPEN = 14,
|
||||
FUSE_OP_READ = 15,
|
||||
FUSE_OP_WRITE = 16,
|
||||
FUSE_OP_STATFS = 17,
|
||||
FUSE_OP_FLUSH = 18,
|
||||
FUSE_OP_RELEASE = 19,
|
||||
FUSE_OP_FSYNC = 20,
|
||||
FUSE_OP_SETXATTR = 21,
|
||||
FUSE_OP_GETXATTR = 22,
|
||||
FUSE_OP_LISTXATTR = 23,
|
||||
FUSE_OP_REMOVEXATTR = 24,
|
||||
FUSE_OP_OPENDIR = 25,
|
||||
FUSE_OP_READDIR = 26,
|
||||
FUSE_OP_RELEASEDIR = 27,
|
||||
FUSE_OP_FSYNCDIR = 28,
|
||||
FUSE_OP_INIT = 29,
|
||||
FUSE_OP_DESTROY = 30,
|
||||
FUSE_OP_ACCESS = 31,
|
||||
FUSE_OP_CREATE = 32,
|
||||
FUSE_OP_FTRUNCATE = 33,
|
||||
FUSE_OP_FGETATTR = 34,
|
||||
FUSE_OP_LOCK = 35,
|
||||
FUSE_OP_UTIMENS = 36,
|
||||
FUSE_OP_BMAP = 37,
|
||||
FUSE_OP_MAX = 38,
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__FUSE_PRIVATE_ */
|
@ -1 +0,0 @@
|
||||
INC_DIR += $(call select_from_ports,exfat)/include
|
@ -1 +0,0 @@
|
||||
INC_DIR += $(call select_from_ports,fuse-ext2)/include/fuse-ext2
|
@ -1 +0,0 @@
|
||||
REP_INC_DIR += include/fuse
|
@ -1 +0,0 @@
|
||||
INC_DIR += $(call select_from_ports,ntfs-3g)/include/ntfs-3g
|
@ -1,7 +0,0 @@
|
||||
LIBS = libc libfuse
|
||||
|
||||
SRC_CC = plugin.cc
|
||||
|
||||
vpath %.cc $(REP_DIR)/src/lib/libc_fuse
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -1,15 +0,0 @@
|
||||
REQUIRES = conversion_to_vfs_plugin
|
||||
|
||||
EXFAT_DIR := $(call select_from_ports,exfat)/src/lib/exfat
|
||||
|
||||
SRC_C = $(notdir $(EXFAT_DIR)/fuse/main.c)
|
||||
SRC_CC = init.cc
|
||||
|
||||
LIBS = libc libc_fuse libfuse libexfat
|
||||
|
||||
vpath %.c $(EXFAT_DIR)/fuse
|
||||
vpath %.cc $(REP_DIR)/src/lib/exfat
|
||||
|
||||
SHARED_LIB = yes
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -1,25 +0,0 @@
|
||||
REQUIRES = conversion_to_vfs_plugin
|
||||
|
||||
FUSE_EXT2_PORT_DIR := $(call select_from_ports,fuse-ext2)
|
||||
FUSE_EXT2_DIR := $(FUSE_EXT2_PORT_DIR)/src/lib/fuse-ext2/fuse-ext2
|
||||
|
||||
FILTER_OUT = fuse-ext2.probe.c fuse-ext2.wait.c
|
||||
SRC_C = $(filter-out $(FILTER_OUT), $(notdir $(wildcard $(FUSE_EXT2_DIR)/*.c)))
|
||||
SRC_CC = init.cc
|
||||
|
||||
LIBS = libc libc_fuse libfuse libext2fs
|
||||
|
||||
CC_OPT = -DHAVE_CONFIG_H -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64
|
||||
|
||||
CC_CXX_OPT +=-fpermissive
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/lib/fuse-ext2 \
|
||||
$(FUSE_EXT2_DIR) \
|
||||
$(FUSE_EXT2_PORT_DIR)/include/fuse-ext2
|
||||
|
||||
vpath %.c $(FUSE_EXT2_DIR)
|
||||
vpath %.cc $(REP_DIR)/src/lib/fuse-ext2
|
||||
|
||||
SHARED_LIB = yes
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -1,20 +0,0 @@
|
||||
REQUIRES = conversion_to_vfs_plugin
|
||||
|
||||
NTFS_3G_DIR := $(call select_from_ports,ntfs-3g)/src/lib/ntfs-3g
|
||||
|
||||
SRC_C = ntfs-3g.c ntfs-3g_common.c
|
||||
SRC_CC = init.cc
|
||||
|
||||
LIBS = libc libc_fuse libfuse libntfs-3g
|
||||
|
||||
CC_OPT = -DHAVE_TIMESPEC -DHAVE_CONFIG_H -DRECORD_LOCKING_NOT_IMPLEMENTED
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/lib/ntfs-3g \
|
||||
$(NTFS_3G_DIR)/src
|
||||
|
||||
vpath %.c $(NTFS_3G_DIR)/src
|
||||
vpath %.cc $(REP_DIR)/src/lib/ntfs-3g
|
||||
|
||||
SHARED_LIB = yes
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -1,17 +0,0 @@
|
||||
EXFAT_DIR = $(call select_from_ports,exfat)/src/lib/exfat
|
||||
|
||||
#FILTER_OUT = win32_io.c
|
||||
#SRC_C = $(filter-out $(FILTER_OUT),$(notdir $(wildcard $(EXFAT_DIR)/libexfat/*.c)))
|
||||
|
||||
SRC_C = $(notdir $(wildcard $(EXFAT_DIR)/libexfat/*.c))
|
||||
|
||||
INC_DIR += $(REP_DIR)/include/exfat \
|
||||
$(EXFAT_DIR)/libexfat
|
||||
|
||||
#CC_OPT += -DHAVE_CONFIG_H -DRECORD_LOCKING_NOT_IMPLEMENTED
|
||||
|
||||
LIBS += libc
|
||||
|
||||
vpath %.c $(EXFAT_DIR)/libexfat
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -1,29 +0,0 @@
|
||||
FUSE_EXT2_PORT_DIR := $(call select_from_ports,fuse-ext2)
|
||||
FUSE_EXT2_DIR = $(FUSE_EXT2_PORT_DIR)/src/lib/fuse-ext2
|
||||
E2FSPROGS_DIR = $(FUSE_EXT2_DIR)/e2fsprogs-1.41.12.newgit
|
||||
EXT2FS_DIR = $(E2FSPROGS_DIR)/ext2fs
|
||||
ET_DIR = $(E2FSPROGS_DIR)/et
|
||||
|
||||
FILTER_OUT = bmove.c dosio.c irel_ma.c nt_io.c tdbtool.c
|
||||
SRC_C = $(filter-out $(FILTER_OUT), $(notdir $(wildcard $(EXT2FS_DIR)/*.c)))
|
||||
SRC_C += $(notdir $(wildcard $(ET_DIR)/*.c))
|
||||
|
||||
INC_DIR += $(REP_DIR)/include/fuse-ext2 \
|
||||
$(REP_DIR)/src/lib/fuse-ext2 \
|
||||
$(FUSE_EXT2_PORT_DIR)/include/fuse-ext2 \
|
||||
$(ET_DIR)
|
||||
|
||||
CC_OPT += -DHAVE_CONFIG_H -D__BSD_VISIBLE -DENABLE_DEBUG
|
||||
|
||||
CC_OPT += -Wno-unused-function -Wno-unused-variable \
|
||||
-Wno-unused-but-set-variable -Wno-cpp \
|
||||
-Wno-maybe-uninitialized -Wno-uninitialized
|
||||
|
||||
CC_C_OPT += -std=gnu89
|
||||
|
||||
LIBS += libc
|
||||
|
||||
vpath %.c $(EXT2FS_DIR)
|
||||
vpath %.c $(ET_DIR)
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -1,11 +0,0 @@
|
||||
SRC_CC = fuse.cc
|
||||
|
||||
INC_DIR += $(REP_DIR)/include/fuse
|
||||
|
||||
LIBS = libc
|
||||
|
||||
CC_OPT += -fpermissive
|
||||
|
||||
vpath %.cc $(REP_DIR)/src/lib/fuse
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -1,17 +0,0 @@
|
||||
NTFS_3G_PORT_DIR := $(call select_from_ports,ntfs-3g)
|
||||
NTFS_3G_DIR := $(NTFS_3G_PORT_DIR)/src/lib/ntfs-3g
|
||||
|
||||
FILTER_OUT = win32_io.c
|
||||
SRC_C = $(filter-out $(FILTER_OUT),$(notdir $(wildcard $(NTFS_3G_DIR)/libntfs-3g/*.c)))
|
||||
|
||||
INC_DIR += $(REP_DIR)/include/ntfs-3g \
|
||||
$(REP_DIR)/src/lib/ntfs-3g \
|
||||
$(NTFS_3G_PORT_DIR)/include/ntfs-3g
|
||||
|
||||
CC_OPT += -DHAVE_CONFIG_H -DRECORD_LOCKING_NOT_IMPLEMENTED -DDEBUG
|
||||
|
||||
LIBS += libc
|
||||
|
||||
vpath %.c $(NTFS_3G_DIR)/libntfs-3g
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -1 +0,0 @@
|
||||
97a451ebdb6d3071b753d6fcd9e5aa6a0eda665f
|
@ -1,12 +0,0 @@
|
||||
LICENSE := GPLv3
|
||||
VERSION := 1.0.1
|
||||
DOWNLOADS := exfat.archive
|
||||
|
||||
URL(exfat) := https://genode.org/files/fuse-exfat-$(VERSION).tar.gz
|
||||
SHA(exfat) := 12ac1ba1b7d4343bef64e7898176705a41cfe3b5a7a179e28549d242e2854758
|
||||
DIR(exfat) := src/lib/exfat
|
||||
|
||||
PATCHES := src/lib/exfat/main.c.patch
|
||||
|
||||
DIRS := include
|
||||
DIR_CONTENT(include) := src/lib/exfat/libexfat/*.h
|
@ -1 +0,0 @@
|
||||
867fc9cb8f828f6463871d5db396b8cda9d7b5b5
|
@ -1,16 +0,0 @@
|
||||
LICENSE := GPLv2
|
||||
VERSION := svn-220
|
||||
DOWNLOADS := fuse-ext2.svn
|
||||
|
||||
URL(fuse-ext2) := http://svn.code.sf.net/p/fuse-ext2/code/branch/renzo
|
||||
REV(fuse-ext2) := 220
|
||||
DIR(fuse-ext2) := src/lib/fuse-ext2
|
||||
|
||||
PATCHES := src/lib/fuse-ext2/patches/*.patch
|
||||
|
||||
DIRS := $(addprefix include/fuse-ext2/,e2p et ext2fs)
|
||||
e2fs_dir := src/lib/fuse-ext2/e2fsprogs-1.41.12.newgit
|
||||
|
||||
DIR_CONTENT(include/fuse-ext2/e2p) := $(e2fs_dir)/e2p/*.h
|
||||
DIR_CONTENT(include/fuse-ext2/et) := $(e2fs_dir)/et/*.h
|
||||
DIR_CONTENT(include/fuse-ext2/ext2fs) := $(e2fs_dir)/ext2fs/*.h
|
@ -1 +0,0 @@
|
||||
436966b79dec7c24b28b6bbfa5c356b4f5e3846e
|
@ -1,13 +0,0 @@
|
||||
LICENSE := GPLv2
|
||||
VERSION := 2013.1.13
|
||||
DOWNLOADS := ntfs-3g.archive
|
||||
|
||||
URL(ntfs-3g) := http://tuxera.com/opensource/ntfs-3g_ntfsprogs-$(VERSION).tgz
|
||||
SHA(ntfs-3g) := 4b383f0074a3ab7683339d1f18222b107aaeb4983db119292c43c2b275cefb27
|
||||
DIR(ntfs-3g) := src/lib/ntfs-3g
|
||||
|
||||
PATCHES := src/lib/ntfs-3g/*.patch
|
||||
|
||||
DIRS := include/ntfs-3g
|
||||
DIR_CONTENT(include/ntfs-3g) := src/lib/ntfs-3g/include/ntfs-3g/*.h
|
||||
|
@ -1,6 +0,0 @@
|
||||
set mkfs_cmd mkfs.exfat
|
||||
set mkfs_opts ""
|
||||
set filesystem fuse_exfat
|
||||
set libc_dev_blkdev {<block name="blkdev"/>}
|
||||
|
||||
source ${genode_dir}/repos/libports/run/libc_filesystem_test.inc
|
@ -1,6 +0,0 @@
|
||||
set mkfs_cmd mkfs.ext2
|
||||
set mkfs_opts "-F"
|
||||
set filesystem fuse_ext2
|
||||
set libc_dev_blkdev {<block name="blkdev"/>}
|
||||
|
||||
source ${genode_dir}/repos/libports/run/libc_filesystem_test.inc
|
@ -1,7 +0,0 @@
|
||||
set build_component server/fuse_fs/exfat
|
||||
set binary exfat_fuse_fs
|
||||
set mkfs_cmd mkfs.exfat
|
||||
set mkfs_opts ""
|
||||
set vfs_dev_blkdev {<block name="blkdev"/>}
|
||||
|
||||
source ${genode_dir}/repos/libports/run/libc_vfs_fs_test.inc
|
@ -1,7 +0,0 @@
|
||||
set build_component server/fuse_fs/ext2
|
||||
set binary ext2_fuse_fs
|
||||
set mkfs_cmd mkfs.ext2
|
||||
set mkfs_opts "-F"
|
||||
set vfs_dev_blkdev {<block name="blkdev"/>}
|
||||
|
||||
source ${genode_dir}/repos/libports/run/libc_vfs_fs_test.inc
|
@ -1,7 +0,0 @@
|
||||
set build_component server/fuse_fs/ntfs-3g
|
||||
set binary ntfs-3g_fuse_fs
|
||||
set mkfs_cmd mkfs.ntfs
|
||||
set mkfs_opts ""
|
||||
set vfs_dev_blkdev {<block name="blkdev"/>}
|
||||
|
||||
source ${genode_dir}/repos/libports/run/libc_vfs_fs_test.inc
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* \brief libc_fuse_exfat
|
||||
* \author Josef Soentgen
|
||||
* \date 2013-11-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
|
||||
#include <fuse_private.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include <exfat.h>
|
||||
|
||||
extern struct fuse_operations fuse_exfat_ops;
|
||||
|
||||
struct fuse_chan *fc;
|
||||
struct fuse *fh;
|
||||
|
||||
struct exfat ef;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Fuse::init_fs(void)
|
||||
{
|
||||
Genode::log("libc_fuse_exfat: try to mount /dev/blkdev...");
|
||||
|
||||
int err = exfat_mount(&ef, "/dev/blkdev", "");
|
||||
if (err) {
|
||||
Genode::error("libc_fuse_exfat: could not mount /dev/blkdev");
|
||||
return false;
|
||||
}
|
||||
|
||||
fh = fuse_new(fc, NULL, &fuse_exfat_ops, sizeof (struct fuse_operations), NULL);
|
||||
if (fh == 0) {
|
||||
Genode::error("libc_fuse_exfat: fuse_new() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Fuse::deinit_fs(void)
|
||||
{
|
||||
Genode::log("libc_fuse_exfat: umount /dev/blkdev...");
|
||||
exfat_unmount(&ef);
|
||||
}
|
||||
|
||||
|
||||
void Fuse::sync_fs(void) { }
|
||||
|
||||
|
||||
bool Fuse::support_symlinks(void)
|
||||
{
|
||||
return false;
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
Make fuse_operation struct globally accessible and comment-out
|
||||
main() function.
|
||||
|
||||
+++ src/lib/exfat/fuse/main.c
|
||||
@@ -296,7 +296,7 @@
|
||||
exit(1);
|
||||
}
|
||||
|
||||
-static struct fuse_operations fuse_exfat_ops =
|
||||
+struct fuse_operations fuse_exfat_ops =
|
||||
{
|
||||
.getattr = fuse_exfat_getattr,
|
||||
.truncate = fuse_exfat_truncate,
|
||||
@@ -403,6 +403,7 @@
|
||||
return options;
|
||||
}
|
||||
|
||||
+#if 0
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
struct fuse_args mount_args = FUSE_ARGS_INIT(0, NULL);
|
||||
@@ -550,3 +551,4 @@
|
||||
fuse_destroy(fh);
|
||||
return 0;
|
||||
}
|
||||
+#endif
|
@ -1,373 +0,0 @@
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if the `closedir' function returns void instead of `int'. */
|
||||
/* #undef CLOSEDIR_VOID */
|
||||
|
||||
/* Define to 1 if you want 'debug' support. */
|
||||
#define ENABLE_DEBUG 1
|
||||
|
||||
/* Define to 1 if you want 'swapfs' support. */
|
||||
#define ENABLE_SWAPFS 1
|
||||
|
||||
/* Version of FUSE interface */
|
||||
#define FUSE_USE_VERSION 26
|
||||
|
||||
/* Define to 1 if your system has a working `chown' function. */
|
||||
/* #undef HAVE_CHOWN */
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#define HAVE_DIRENT_H 1
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
|
||||
/* #undef HAVE_DOPRNT */
|
||||
|
||||
/* Define to 1 if you have the <errno.h> header file. */
|
||||
#define HAVE_ERRNO_H 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the `ftruncate' function. */
|
||||
#define HAVE_FTRUNCATE 1
|
||||
|
||||
/* Define to 1 if you have the `getdtablesize' function. */
|
||||
/* #undef HAVE_GETDTABLESIZE */
|
||||
|
||||
/* Define to 1 if you have the `getmntent' function. */
|
||||
#define HAVE_GETMNTENT 1
|
||||
|
||||
/* Define to 1 if you have the `getmntinfo' function. */
|
||||
/* #undef HAVE_GETMNTINFO */
|
||||
|
||||
/* Define to 1 if you have the <getopt.h> header file. */
|
||||
#define HAVE_GETOPT_H 1
|
||||
|
||||
/* Define to 1 if you have the `getpagesize' function. */
|
||||
#define HAVE_GETPAGESIZE 1
|
||||
|
||||
/* Define to 1 if you have the `hasmntopt' function. */
|
||||
/* #undef HAVE_HASMNTOPT */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `ext2fs' library (-lext2fs). */
|
||||
#define HAVE_LIBEXT2FS 1
|
||||
|
||||
/* Define to 1 if you have the <linux/fd.h> header file. */
|
||||
/* #undef HAVE_LINUX_FD_H */
|
||||
|
||||
/* Define to 1 if you have the `llseek' function. */
|
||||
/* #undef HAVE_LLSEEK */
|
||||
|
||||
/* Define to 1 if you have the `llseek' prototype. */
|
||||
/* #undef HAVE_LLSEEK_PROTOTYPE */
|
||||
|
||||
/* Define to 1 if you have the `lseek64' function. */
|
||||
/* #undef HAVE_LSEEK64 */
|
||||
|
||||
/* Define to 1 if you have the `lseek64' prototype. */
|
||||
#define HAVE_LSEEK64_PROTOTYPE 1
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||
to 0 otherwise. */
|
||||
#define HAVE_MALLOC 1
|
||||
|
||||
/* Define to 1 if you have the <malloc.h> header file. */
|
||||
#define HAVE_MALLOC_H 1
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
#define HAVE_MEMMOVE 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* Define to 1 if you have a working `mmap' system call. */
|
||||
/* #undef HAVE_MMAP */
|
||||
|
||||
/* Define to 1 if you have the <mntent.h> header file. */
|
||||
/* #undef HAVE_MNTENT_H */
|
||||
|
||||
/* Define to 1 if you have the `munmap' function. */
|
||||
/* #undef HAVE_MUNMAP */
|
||||
|
||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||
/* #undef HAVE_NDIR_H */
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
|
||||
/* Define to 1 if you have the <net/if_dl.h> header file. */
|
||||
/* #undef HAVE_NET_IF_DL_H */
|
||||
|
||||
/* Define to 1 if you have the <net/if.h> header file. */
|
||||
#define HAVE_NET_IF_H 1
|
||||
|
||||
/* Define to 1 if you have the <paths.h> header file. */
|
||||
#define HAVE_PATHS_H 1
|
||||
|
||||
/* Define to 1 if you have the `random' function. */
|
||||
#define HAVE_RANDOM 1
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
|
||||
and to 0 otherwise. */
|
||||
#define HAVE_REALLOC 1
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#define HAVE_SELECT 1
|
||||
|
||||
/* Define to 1 if you have the `srand' function. */
|
||||
#define HAVE_SRAND 1
|
||||
|
||||
/* Define to 1 if you have the `srandom' function. */
|
||||
#define HAVE_SRANDOM 1
|
||||
|
||||
/* Define to 1 if `stat' has the bug that it succeeds when given the
|
||||
zero-length file name argument. */
|
||||
/* #undef HAVE_STAT_EMPTY_STRING_BUG */
|
||||
|
||||
/* Define to 1 if you have the <stddef.h> header file. */
|
||||
#define HAVE_STDDEF_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#define HAVE_STRERROR 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strrchr' function. */
|
||||
#define HAVE_STRRCHR 1
|
||||
|
||||
/* Define to 1 if you have the `strtol' function. */
|
||||
#define HAVE_STRTOL 1
|
||||
|
||||
/* Define to 1 if you have the `strtoul' function. */
|
||||
#define HAVE_STRTOUL 1
|
||||
|
||||
/* Define to 1 if you have the `strtoull' function. */
|
||||
#define HAVE_STRTOULL 1
|
||||
|
||||
/* Define to 1 if `st_blksize' is a member of `struct stat'. */
|
||||
#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
|
||||
|
||||
/* Define to 1 if `st_blocks' is a member of `struct stat'. */
|
||||
#define HAVE_STRUCT_STAT_ST_BLOCKS 1
|
||||
|
||||
/* Define to 1 if `st_rdev' is a member of `struct stat'. */
|
||||
#define HAVE_STRUCT_STAT_ST_RDEV 1
|
||||
|
||||
/* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use
|
||||
`HAVE_STRUCT_STAT_ST_BLOCKS' instead. */
|
||||
#define HAVE_ST_BLOCKS 1
|
||||
|
||||
/* Define to 1 if you have the `sysconf' function. */
|
||||
#define HAVE_SYSCONF 1
|
||||
|
||||
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
/* #undef HAVE_SYS_DIR_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/disklabel.h> header file. */
|
||||
/* #undef HAVE_SYS_DISKLABEL_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/disk.h> header file. */
|
||||
/* #undef HAVE_SYS_DISK_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/file.h> header file. */
|
||||
#define HAVE_SYS_FILE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/mkdev.h> header file. */
|
||||
/* #undef HAVE_SYS_MKDEV_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#define HAVE_SYS_MMAN_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/mount.h> header file. */
|
||||
#define HAVE_SYS_MOUNT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
/* #undef HAVE_SYS_NDIR_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/prctl.h> header file. */
|
||||
/* #undef HAVE_SYS_PRCTL_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/queue.h> header file. */
|
||||
#define HAVE_SYS_QUEUE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
||||
#define HAVE_SYS_RESOURCE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#define HAVE_SYS_SELECT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/sockio.h> header file. */
|
||||
/* #undef HAVE_SYS_SOCKIO_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/statvfs.h> header file. */
|
||||
#define HAVE_SYS_STATVFS_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/syscall.h> header file. */
|
||||
#define HAVE_SYS_SYSCALL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/un.h> header file. */
|
||||
#define HAVE_SYS_UN_H 1
|
||||
|
||||
/* Define to 1 if you have the `ssize_t' prototype. */
|
||||
#define HAVE_TYPE_SSIZE_T 1
|
||||
|
||||
/* Define to 1 if you have the `uname' function. */
|
||||
#define HAVE_UNAME 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `utime' function. */
|
||||
#define HAVE_UTIME 1
|
||||
|
||||
/* Define to 1 if you have the <utime.h> header file. */
|
||||
#define HAVE_UTIME_H 1
|
||||
|
||||
/* Define to 1 if `utime(file, NULL)' sets file's timestamp to the present. */
|
||||
#define HAVE_UTIME_NULL 1
|
||||
|
||||
/* Define to 1 if you have the `vprintf' function. */
|
||||
#define HAVE_VPRINTF 1
|
||||
|
||||
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
|
||||
slash. */
|
||||
#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
/* #undef LT_OBJDIR */
|
||||
|
||||
/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
|
||||
*/
|
||||
/* #undef MAJOR_IN_MKDEV */
|
||||
|
||||
/* Define to 1 if `major', `minor', and `makedev' are declared in
|
||||
<sysmacros.h>. */
|
||||
/* #undef MAJOR_IN_SYSMACROS */
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "fuse-ext2"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "fuse-ext2"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "fuse-ext2 0.0.7.1"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "fuse-ext2"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "0.0.7.1"
|
||||
|
||||
/* Define to the type of arg 1 for `select'. */
|
||||
#define SELECT_TYPE_ARG1 int
|
||||
|
||||
/* Define to the type of args 2, 3 and 4 for `select'. */
|
||||
#define SELECT_TYPE_ARG234 (fd_set *)
|
||||
|
||||
/* Define to the type of arg 5 for `select'. */
|
||||
#define SELECT_TYPE_ARG5 (struct timeval *)
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "0.0.7.1"
|
||||
|
||||
/* File Offset size */
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
/* Large files support */
|
||||
#define _LARGE_FILE_SOURCE /**/
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
/* #undef gid_t */
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
/* #undef inline */
|
||||
#endif
|
||||
|
||||
/* Define to rpl_malloc if the replacement function should be used. */
|
||||
/* #undef malloc */
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef mode_t */
|
||||
|
||||
/* Define to `long int' if <sys/types.h> does not define. */
|
||||
/* #undef off_t */
|
||||
|
||||
/* Define to rpl_realloc if the replacement function should be used. */
|
||||
/* #undef realloc */
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* #undef size_t */
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef ssize_t */
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
/* #undef uid_t */
|
@ -1,104 +0,0 @@
|
||||
/*
|
||||
* \brief libc_fuse_ext2
|
||||
* \author Josef Soentgen
|
||||
* \date 2013-11-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <util/string.h>
|
||||
|
||||
#include <fuse.h>
|
||||
#include <fuse_private.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <stdlib.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include <fuse-ext2.h>
|
||||
#include <ext2fs/ext2fs.h>
|
||||
|
||||
extern struct fuse_operations ext2fs_ops;
|
||||
|
||||
struct fuse_chan *fc;
|
||||
struct fuse *fh;
|
||||
|
||||
static ext2_filsys e2fs;
|
||||
static struct extfs_data extfs_data;
|
||||
|
||||
char mnt_point[] = "/";
|
||||
char options[] = "";
|
||||
char device[] = "/dev/blkdev";
|
||||
char volname[] = "ext2_volume";
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Fuse::init_fs(void)
|
||||
{
|
||||
Genode::log("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) {
|
||||
Genode::error("libc_fuse_ext2: could not mount /dev/blkdev, error: ", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
errcode_t rc = ext2fs_read_bitmaps(e2fs);
|
||||
if (rc) {
|
||||
Genode::error("libc_fuse_ext2: error while reading bitmaps");
|
||||
ext2fs_close(e2fs);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* set 1 to enable debug messages */
|
||||
extfs_data.debug = 0;
|
||||
|
||||
extfs_data.silent = 0;
|
||||
extfs_data.force = 0;
|
||||
extfs_data.readonly = 0;
|
||||
extfs_data.last_flush = 0;
|
||||
extfs_data.mnt_point = mnt_point;
|
||||
extfs_data.options = options;
|
||||
extfs_data.device = device;
|
||||
extfs_data.volname = volname;
|
||||
extfs_data.e2fs = e2fs;
|
||||
|
||||
fh = fuse_new(fc, NULL, &ext2fs_ops, sizeof (ext2fs_ops), &extfs_data);
|
||||
if (fh == 0) {
|
||||
Genode::error("libc_fuse_ext2: fuse_new() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Fuse::deinit_fs(void)
|
||||
{
|
||||
Genode::log("libc_fuse_ext2: unmount /dev/blkdev...");
|
||||
ext2fs_close(e2fs);
|
||||
|
||||
free(fh);
|
||||
}
|
||||
|
||||
|
||||
void Fuse::sync_fs(void)
|
||||
{
|
||||
Genode::log("libc_fuse_ext2: sync file system...");
|
||||
ext2fs_flush(e2fs);
|
||||
}
|
||||
|
||||
|
||||
bool Fuse::support_symlinks(void)
|
||||
{
|
||||
return true;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/e2fsprogs-1.41.12.newgit/ext2fs/bitops.h
|
||||
@@ -98,7 +98,7 @@
|
||||
extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
|
||||
blk_t block, int num);
|
||||
extern int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,
|
||||
- ino_t inode, int num);
|
||||
+ ext2_ino_t inode, int num);
|
||||
extern void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
|
||||
blk_t block, int num);
|
||||
extern void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
|
@ -1,21 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/e2fsprogs-1.41.12.newgit/ext2fs/closefs.c
|
||||
@@ -32,19 +32,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
-int ext2fs_bg_has_super(ext2_filsys fs, int group_block)
|
||||
-{
|
||||
- if (!(fs->super->s_feature_ro_compat &
|
||||
- EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
|
||||
- return 1;
|
||||
-
|
||||
- if (test_root(group_block, 3) || (test_root(group_block, 5)) ||
|
||||
- test_root(group_block, 7))
|
||||
- return 1;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* ext2fs_super_and_bgd_loc2()
|
||||
* @fs: ext2 fs pointer
|
@ -1,10 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/e2fsprogs-1.41.12.newgit/et/com_err.c
|
||||
@@ -11,6 +11,8 @@
|
||||
* express or implied warranty.
|
||||
*/
|
||||
|
||||
+#include "config.h"
|
||||
+
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
#include <termios.h>
|
@ -1,10 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/e2fsprogs-1.41.12.newgit/et/error_message.c
|
||||
@@ -16,6 +16,8 @@
|
||||
* express or implied warranty.
|
||||
*/
|
||||
|
||||
+#include "config.h"
|
||||
+
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
@ -1,14 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/e2fsprogs-1.41.12.newgit/ext2fs/ext2fs.h
|
||||
@@ -49,9 +49,12 @@
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
+typedef unsigned int dev_t;
|
||||
+
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
+#include <time.h>
|
||||
|
||||
#if EXT2_FLAT_INCLUDES
|
||||
#include "e2_types.h"
|
@ -1,23 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/fuse-ext2/fuse-ext2.c
|
||||
@@ -278,7 +278,7 @@
|
||||
goto exit;
|
||||
}
|
||||
|
||||
-static const struct fuse_operations ext2fs_ops = {
|
||||
+const struct fuse_operations ext2fs_ops = {
|
||||
.getattr = op_getattr,
|
||||
.readlink = op_readlink,
|
||||
.mknod = op_mknod,
|
||||
@@ -317,6 +317,7 @@
|
||||
.bmap = NULL,
|
||||
};
|
||||
|
||||
+#if 0
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
int err = 0;
|
||||
@@ -385,3 +386,4 @@
|
||||
free(opts.volname);
|
||||
return err;
|
||||
}
|
||||
+#endif
|
@ -1,19 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/fuse-ext2/fuse-ext2.h
|
||||
@@ -88,7 +88,7 @@
|
||||
static inline ext2_filsys current_ext2fs(void)
|
||||
{
|
||||
struct fuse_context *mycontext=fuse_get_context();
|
||||
- struct extfs_data *e2data=mycontext->private_data;
|
||||
+ struct extfs_data *e2data= (struct extfs_data*)mycontext->private_data;
|
||||
time_t now=time(NULL);
|
||||
if ((now - e2data->last_flush) > FLUSH_BITMAPS_TIMEOUT) {
|
||||
ext2fs_write_bitmaps(e2data->e2fs);
|
||||
@@ -103,7 +103,7 @@
|
||||
{
|
||||
va_list args;
|
||||
struct fuse_context *mycontext=fuse_get_context();
|
||||
- struct extfs_data *e2data=mycontext->private_data;
|
||||
+ struct extfs_data *e2data=(struct extfs_data*) mycontext->private_data;
|
||||
if (e2data && (e2data->debug == 0 || e2data->silent == 1)) {
|
||||
return;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/e2fsprogs-1.41.12.newgit/ext2fs/gen_bitmap64.c
|
||||
@@ -577,4 +577,5 @@
|
||||
com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
|
||||
"called %s with 64-bit bitmap", func);
|
||||
#endif
|
||||
+ return 0;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/e2fsprogs-1.41.12.newgit/ext2fs/icount.c
|
||||
@@ -9,6 +9,8 @@
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
+#include "config.h"
|
||||
+
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
@ -1,10 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/e2fsprogs-1.41.12.newgit/et/init_et.c
|
||||
@@ -16,6 +16,8 @@
|
||||
* express or implied warranty.
|
||||
*/
|
||||
|
||||
+#include "config.h"
|
||||
+
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_STDLIB_H
|
@ -1,10 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/fuse-ext2/op_access.c
|
||||
@@ -18,6 +18,8 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
+#include <unistd.h>
|
||||
+
|
||||
#include "fuse-ext2.h"
|
||||
|
||||
int op_access (const char *path, int mask)
|
@ -1,14 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/fuse-ext2/op_statfs.c
|
||||
@@ -41,10 +41,12 @@
|
||||
|
||||
static int ext2_bg_has_super (ext2_filsys e2fs, int group)
|
||||
{
|
||||
+ /*
|
||||
if (EXT2_HAS_RO_COMPAT_FEATURE(e2fs->super, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) &&
|
||||
!ext2_group_spare(group)) {
|
||||
return 0;
|
||||
}
|
||||
+ */
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/e2fsprogs-1.41.12.newgit/ext2fs/res_gdt.c
|
||||
@@ -63,7 +63,7 @@
|
||||
errcode_t retval, retval2;
|
||||
struct ext2_super_block *sb;
|
||||
struct ext2_inode inode;
|
||||
- __u32 *dindir_buf, *gdt_buf;
|
||||
+ __u32 *dindir_buf = 0, *gdt_buf;
|
||||
unsigned long long apb, inode_size;
|
||||
/* FIXME-64 - can't deal with extents */
|
||||
blk_t dindir_blk, rsv_off, gdt_off, gdt_blk;
|
@ -1,10 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/e2fsprogs-1.41.12.newgit/ext2fs/rw_bitmaps.c
|
||||
@@ -34,7 +34,7 @@
|
||||
int block_nbytes, inode_nbytes;
|
||||
unsigned int nbits;
|
||||
errcode_t retval;
|
||||
- char *block_buf, *inode_buf;
|
||||
+ char *block_buf = 0, *inode_buf = 0;
|
||||
int csum_flag = 0;
|
||||
blk64_t blk;
|
||||
blk64_t blk_itr = fs->super->s_first_data_block;
|
@ -1,16 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/e2fsprogs-1.41.12.newgit/ext2fs/tdb.c
|
||||
@@ -75,12 +75,11 @@
|
||||
static char *rep_strdup(const char *s)
|
||||
{
|
||||
char *ret;
|
||||
- int length;
|
||||
+ size_t length;
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
- if (!length)
|
||||
- length = strlen(s);
|
||||
+ length = strlen(s);
|
||||
|
||||
ret = malloc(length + 1);
|
||||
if (ret) {
|
@ -1,10 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/e2fsprogs-1.41.12.newgit/ext2fs/test_io.c
|
||||
@@ -9,6 +9,8 @@
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
+#include "config.h"
|
||||
+
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#if HAVE_UNISTD_H
|
@ -1,10 +0,0 @@
|
||||
+++ src/lib/fuse-ext2/e2fsprogs-1.41.12.newgit/ext2fs/unix_io.c
|
||||
@@ -200,7 +200,7 @@
|
||||
errcode_t retval;
|
||||
size_t size, alignsize, fragment;
|
||||
ext2_loff_t location;
|
||||
- int total = 0, actual;
|
||||
+ int total = 0, actual = 0;
|
||||
#define BLOCKALIGN 512
|
||||
char sector[BLOCKALIGN];
|
||||
|
@ -1,299 +0,0 @@
|
||||
/*
|
||||
* \brief libfuse re-implementation
|
||||
* \author Josef Soentgen
|
||||
* \date 2013-11-07
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 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.
|
||||
*/
|
||||
|
||||
/* Genodes includes */
|
||||
#include <base/log.h>
|
||||
#include <util/string.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <fuse.h>
|
||||
#include <fuse_private.h>
|
||||
|
||||
static bool _initialized;
|
||||
static struct fuse *_fuse;
|
||||
static struct fuse_context _ctx;
|
||||
|
||||
#if 1
|
||||
#define TRACE Genode::log("")
|
||||
#else
|
||||
#define TRACE
|
||||
#endif
|
||||
|
||||
struct fuse* Fuse::fuse()
|
||||
{
|
||||
if (_fuse == 0) {
|
||||
Genode::error("libfuse: struct fuse is zero");
|
||||
abort();
|
||||
}
|
||||
|
||||
return _fuse;
|
||||
}
|
||||
|
||||
bool Fuse::initialized()
|
||||
{
|
||||
return _initialized;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
void fuse_genode(const char *s)
|
||||
{
|
||||
Genode::log(__func__, ": ", s);
|
||||
}
|
||||
|
||||
#define FIX_UP_OPERATION1(f, name) \
|
||||
if(f->op.name == 0) \
|
||||
f->op.name = dummy_op1;
|
||||
|
||||
#define FIX_UP_OPERATION2(f, name) \
|
||||
if(f->op.name == 0) \
|
||||
f->op.name = dummy_op2;
|
||||
|
||||
static int dummy_op1(void)
|
||||
{
|
||||
TRACE;
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static int dummy_op2(void)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fill_dir(void *dh, const char *name, const struct stat *sbuf, off_t offset)
|
||||
{
|
||||
static uint32_t fileno = 1;
|
||||
|
||||
struct fuse_dirhandle *dir = (struct fuse_dirhandle*)dh;
|
||||
|
||||
if ((dir->offset + sizeof (struct dirent)) > dir->size) {
|
||||
Genode::warning("fill_dir buffer full");
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct dirent *entry = (struct dirent *)(((char*)dir->buf) + dir->offset);
|
||||
Genode::memset(entry, 0, sizeof (struct dirent));
|
||||
|
||||
if (sbuf) {
|
||||
entry->d_fileno = sbuf->st_ino;
|
||||
entry->d_type = IFTODT(sbuf->st_mode);
|
||||
}
|
||||
else {
|
||||
entry->d_fileno = fileno++;
|
||||
entry->d_type = DT_UNKNOWN;
|
||||
}
|
||||
|
||||
/* even in a valid sbuf the inode might by 0 */
|
||||
if (entry->d_fileno == 0)
|
||||
entry->d_fileno = fileno++;
|
||||
|
||||
size_t namelen = Genode::strlen(name);
|
||||
if (namelen > 255)
|
||||
namelen = 255;
|
||||
|
||||
Genode::strncpy(entry->d_name, name, namelen + 1);
|
||||
|
||||
entry->d_reclen = sizeof (struct dirent);
|
||||
|
||||
dir->offset += sizeof (struct dirent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* FUSE API
|
||||
*/
|
||||
|
||||
int fuse_version(void)
|
||||
{
|
||||
return (FUSE_VERSION);
|
||||
}
|
||||
|
||||
int fuse_main(int argc, char *argv[],
|
||||
const struct fuse_operations *fsop, void *data)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct fuse* fuse_new(struct fuse_chan *chan, struct fuse_args *args,
|
||||
const struct fuse_operations *fsop, size_t size,
|
||||
void *userdata)
|
||||
{
|
||||
TRACE;
|
||||
|
||||
_fuse = reinterpret_cast<struct fuse*>(malloc(sizeof (struct fuse)));
|
||||
if (_fuse == 0) {
|
||||
Genode::error("could not create struct fuse");
|
||||
return 0;
|
||||
}
|
||||
|
||||
_fuse->fc = chan;
|
||||
_fuse->args = args;
|
||||
|
||||
Genode::memcpy(&_fuse->op, fsop, Genode::min(size, sizeof (_fuse->op)));
|
||||
|
||||
/**
|
||||
* Defining a dummy function for each fuse operation is cumbersome.
|
||||
* So let us faithfully ignore the compiler.
|
||||
*/
|
||||
#pragma GCC diagnostic ignored "-fpermissive"
|
||||
|
||||
FIX_UP_OPERATION1(_fuse, readlink);
|
||||
FIX_UP_OPERATION1(_fuse, mknod);
|
||||
FIX_UP_OPERATION1(_fuse, unlink);
|
||||
FIX_UP_OPERATION1(_fuse, rmdir);
|
||||
FIX_UP_OPERATION1(_fuse, symlink);
|
||||
FIX_UP_OPERATION1(_fuse, rename);
|
||||
FIX_UP_OPERATION1(_fuse, link);
|
||||
FIX_UP_OPERATION1(_fuse, chmod);
|
||||
FIX_UP_OPERATION1(_fuse, chown);
|
||||
FIX_UP_OPERATION1(_fuse, truncate);
|
||||
FIX_UP_OPERATION1(_fuse, utime);
|
||||
FIX_UP_OPERATION2(_fuse, open);
|
||||
FIX_UP_OPERATION1(_fuse, read);
|
||||
FIX_UP_OPERATION1(_fuse, write);
|
||||
FIX_UP_OPERATION1(_fuse, statfs);
|
||||
FIX_UP_OPERATION1(_fuse, flush);
|
||||
FIX_UP_OPERATION1(_fuse, release);
|
||||
FIX_UP_OPERATION1(_fuse, fsync);
|
||||
FIX_UP_OPERATION1(_fuse, fsyncdir);
|
||||
FIX_UP_OPERATION1(_fuse, access);
|
||||
FIX_UP_OPERATION1(_fuse, create);
|
||||
FIX_UP_OPERATION1(_fuse, utimens);
|
||||
FIX_UP_OPERATION1(_fuse, read);
|
||||
FIX_UP_OPERATION1(_fuse, read);
|
||||
|
||||
if (_fuse->op.opendir == 0)
|
||||
_fuse->op.opendir = _fuse->op.open;
|
||||
if (_fuse->op.releasedir == 0)
|
||||
_fuse->op.releasedir = _fuse->op.release;
|
||||
if (_fuse->op.fgetattr == 0)
|
||||
_fuse->op.fgetattr = _fuse->op.getattr;
|
||||
if (_fuse->op.ftruncate == 0)
|
||||
_fuse->op.ftruncate = _fuse->op.truncate;
|
||||
|
||||
_fuse->filler = fill_dir;
|
||||
|
||||
_fuse->userdata = userdata;
|
||||
|
||||
_ctx.fuse = _fuse;
|
||||
_ctx.uid = 0;
|
||||
_ctx.gid = 0;
|
||||
_ctx.pid = 0;
|
||||
_ctx.private_data = userdata;
|
||||
_ctx.umask = 022;
|
||||
|
||||
_initialized = true;
|
||||
|
||||
return _fuse;
|
||||
}
|
||||
|
||||
int fuse_parse_cmdline(struct fuse_args *args, char **mp, int *mt, int *fg)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct fuse_chan* fuse_mount(const char *dir, struct fuse_args *args)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fuse_remove_signal_handlers(struct fuse_session *se)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
int fuse_set_signal_handlers(struct fuse_session *se)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct fuse_session* fuse_get_session(struct fuse *f)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct fuse_context* fuse_get_context(void)
|
||||
{
|
||||
return &_ctx;
|
||||
}
|
||||
|
||||
int fuse_is_lib_option(const char *opt)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fuse_loop(struct fuse *fuse)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fuse_loop_mt(struct fuse *fuse)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fuse_chan_fd(struct fuse_chan *ch)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void fuse_unmount(const char *dir, struct fuse_chan *ch)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
int fuse_daemonize(int foreground)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void fuse_destroy(struct fuse *f)
|
||||
{
|
||||
TRACE;
|
||||
|
||||
free(f);
|
||||
}
|
||||
|
||||
void fuse_teardown(struct fuse *f, char *mp)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
int fuse_opt_add_arg(struct fuse_args *, const char *)
|
||||
{
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void fuse_opt_free_args(struct fuse_args *)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
} /* extern "C" */
|
@ -1,534 +0,0 @@
|
||||
/*
|
||||
* \brief Libc libfuse plugin
|
||||
* \author Josef Soentgen
|
||||
* \date 2013-11-07
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/allocator_avl.h>
|
||||
#include <base/env.h>
|
||||
#include <base/log.h>
|
||||
#include <util/string.h>
|
||||
#include <os/path.h>
|
||||
|
||||
/* libc plugin includes */
|
||||
#include <libc-plugin/plugin.h>
|
||||
#include <libc-plugin/fd_alloc.h>
|
||||
|
||||
/* fuse */
|
||||
#include <fuse_private.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/* a little helper to prevent code duplication */
|
||||
static inline int check_result(int res)
|
||||
{
|
||||
if (res < 0) {
|
||||
/**
|
||||
* FUSE file systems always return -errno as result
|
||||
* if something went wrong.
|
||||
*/
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************
|
||||
** override libc defaults **
|
||||
****************************/
|
||||
|
||||
extern "C" int chmod(const char *path, mode_t mode)
|
||||
{
|
||||
return check_result(Fuse::fuse()->op.chmod(path, mode));
|
||||
}
|
||||
|
||||
|
||||
extern "C" int chown(const char *path, uid_t uid, gid_t gid)
|
||||
{
|
||||
return check_result(Fuse::fuse()->op.chown(path, uid, gid));
|
||||
}
|
||||
|
||||
|
||||
extern "C" int link(const char *oldpath, const char *newpath)
|
||||
{
|
||||
return check_result(Fuse::fuse()->op.link(oldpath, newpath));
|
||||
}
|
||||
|
||||
|
||||
/************
|
||||
** Plugin **
|
||||
************/
|
||||
|
||||
namespace {
|
||||
|
||||
struct Plugin_context : Libc::Plugin_context
|
||||
{
|
||||
String<4096> path;
|
||||
int flags;
|
||||
int fd_flags;
|
||||
struct fuse_file_info file_info;
|
||||
|
||||
::off_t offset;
|
||||
|
||||
Plugin_context(const char *p, int f)
|
||||
:
|
||||
path(p), flags(f), offset(0)
|
||||
{
|
||||
Genode::memset(&file_info, 0, sizeof (struct fuse_file_info));
|
||||
}
|
||||
|
||||
~Plugin_context() { }
|
||||
};
|
||||
|
||||
static inline Plugin_context *context(Libc::File_descriptor *fd)
|
||||
{
|
||||
return static_cast<Plugin_context *>(fd->context);
|
||||
}
|
||||
|
||||
class Plugin : public Libc::Plugin
|
||||
{
|
||||
private:
|
||||
|
||||
enum { PLUGIN_PRIORITY = 1 };
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Plugin() : Libc::Plugin(PLUGIN_PRIORITY)
|
||||
{
|
||||
if (!Fuse::init_fs()) {
|
||||
error("FUSE fs initialization failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
~Plugin()
|
||||
{
|
||||
if (Fuse::initialized())
|
||||
Fuse::deinit_fs();
|
||||
}
|
||||
|
||||
bool supports_mkdir(const char *path, mode_t mode)
|
||||
{
|
||||
if (Fuse::initialized() == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool supports_open(const char *pathname, int flags)
|
||||
{
|
||||
if (Genode::strcmp(pathname, "/dev/blkdev") == 0)
|
||||
return false;
|
||||
|
||||
if (Fuse::initialized() == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool supports_readlink(const char *path, char *buf, ::size_t bufsiz)
|
||||
{
|
||||
if (Fuse::initialized() == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool supports_rmdir(const char *path)
|
||||
{
|
||||
if (Fuse::fuse() == 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool supports_stat(const char *path)
|
||||
{
|
||||
if (Fuse::initialized() == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool supports_symlink(const char *oldpath, const char *newpath)
|
||||
{
|
||||
if (Fuse::fuse() == 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool supports_unlink(const char *path)
|
||||
{
|
||||
if (Fuse::fuse() == 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int close(Libc::File_descriptor *fd)
|
||||
{
|
||||
Plugin_context *ctx = context(fd);
|
||||
|
||||
Fuse::fuse()->op.release(ctx->path.string(), &ctx->file_info);
|
||||
|
||||
destroy(env()->heap(), ctx);
|
||||
Libc::file_descriptor_allocator()->free(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fcntl(Libc::File_descriptor *fd, int cmd, long arg)
|
||||
{
|
||||
Plugin_context *ctx = context(fd);
|
||||
|
||||
switch (cmd) {
|
||||
case F_GETFD:
|
||||
return ctx->fd_flags;
|
||||
case F_GETFL:
|
||||
return ctx->flags;
|
||||
case F_SETFD:
|
||||
ctx->fd_flags = arg;
|
||||
return 0;
|
||||
default:
|
||||
warning(__func__, ": cmd ", cmd, " not supported");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1; /* never reached */
|
||||
}
|
||||
|
||||
int fstat(Libc::File_descriptor *fd, struct stat *buf)
|
||||
{
|
||||
Plugin_context *ctx = context(fd);
|
||||
|
||||
Genode::memset(buf, 0, sizeof (struct stat));
|
||||
|
||||
int res = Fuse::fuse()->op.getattr(ctx->path.string(), buf);
|
||||
if (res != 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fstatfs(Libc::File_descriptor *fd, struct statfs *buf)
|
||||
{
|
||||
Plugin_context *ctx = context(fd);
|
||||
|
||||
struct statvfs vfs;
|
||||
|
||||
int res = Fuse::fuse()->op.statfs(ctx->path.string(), &vfs);
|
||||
if (res != 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Genode::memset(buf, 0, sizeof (struct statfs));
|
||||
|
||||
buf->f_bsize = vfs.f_bsize;
|
||||
//buf->f_frsize = vfs.f_frsize;
|
||||
buf->f_blocks = vfs.f_blocks;
|
||||
buf->f_bavail = vfs.f_bavail;
|
||||
buf->f_bfree = vfs.f_bfree;
|
||||
buf->f_namemax = vfs.f_namemax;
|
||||
buf->f_files = vfs.f_files;
|
||||
//buf->f_favail = vfs.f_favail;
|
||||
buf->f_ffree = vfs.f_ffree;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ftruncate(Libc::File_descriptor *fd, ::off_t length)
|
||||
{
|
||||
Plugin_context *ctx = context(fd);
|
||||
|
||||
int res = Fuse::fuse()->op.ftruncate(ctx->path.string(), length,
|
||||
&ctx->file_info);
|
||||
if (res != 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
::ssize_t getdirentries(Libc::File_descriptor *fd, char *buf, ::size_t nbytes,
|
||||
::off_t *basep)
|
||||
{
|
||||
Plugin_context *ctx = context(fd);
|
||||
|
||||
if (nbytes < sizeof (struct dirent)) {
|
||||
error(__func__, ": buf too small");
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct dirent *de = (struct dirent *)buf;
|
||||
::memset(de, 0, sizeof (struct dirent));
|
||||
|
||||
struct fuse_dirhandle dh = {
|
||||
.filler = Fuse::fuse()->filler,
|
||||
.buf = buf,
|
||||
.size = nbytes,
|
||||
.offset = 0,
|
||||
};
|
||||
|
||||
int res = Fuse::fuse()->op.readdir(ctx->path.string(), &dh,
|
||||
Fuse::fuse()->filler, 0,
|
||||
&ctx->file_info);
|
||||
if (res != 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* We have to stat(2) each entry because there are FUSE file
|
||||
* systems which do not provide a valid struct stat entry in
|
||||
* its readdir() implementation because only d_ino and d_name
|
||||
* are specified by POSIX.
|
||||
*/
|
||||
::off_t offset = 0;
|
||||
while (offset < dh.offset) {
|
||||
struct dirent *entry = (struct dirent*)(buf + offset);
|
||||
|
||||
/* try to query the type of the file if the type is unknown */
|
||||
if (entry->d_type == DT_UNKNOWN) {
|
||||
Genode::Path<4096> path(entry->d_name, ctx->path.string());
|
||||
struct stat sbuf;
|
||||
res = Fuse::fuse()->op.getattr(path.base(), &sbuf);
|
||||
if (res == 0) {
|
||||
entry->d_type = IFTODT(sbuf.st_mode);
|
||||
entry->d_fileno = sbuf.st_ino ? sbuf.st_ino : 1;
|
||||
}
|
||||
}
|
||||
|
||||
offset += sizeof (struct dirent);
|
||||
}
|
||||
|
||||
/**
|
||||
* To prevent the libc from being stuck in an endless loop we
|
||||
* append an empty entry. This is a rather hacky solution but
|
||||
* for now it suffice.
|
||||
*/
|
||||
dh.offset += sizeof (struct dirent);
|
||||
((struct dirent*)(buf + dh.offset))->d_reclen = 0;
|
||||
|
||||
return dh.offset;
|
||||
}
|
||||
|
||||
::off_t lseek(Libc::File_descriptor *fd, ::off_t offset, int whence)
|
||||
{
|
||||
Plugin_context *ctx = context(fd);
|
||||
|
||||
switch (whence) {
|
||||
case SEEK_SET:
|
||||
ctx->offset = offset;
|
||||
return ctx->offset;
|
||||
|
||||
case SEEK_CUR:
|
||||
ctx->offset += offset;
|
||||
return ctx->offset;
|
||||
|
||||
case SEEK_END:
|
||||
if (offset != 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
ctx->offset = ~0L;
|
||||
|
||||
return (Fuse::fuse()->block_size * Fuse::fuse()->block_count);
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int mkdir(const char *pathname, mode_t mode)
|
||||
{
|
||||
int res = Fuse::fuse()->op.mkdir(pathname, mode);
|
||||
|
||||
return check_result(res);
|
||||
}
|
||||
|
||||
Libc::File_descriptor *open(const char *pathname, int flags)
|
||||
{
|
||||
/* XXX evaluate flags */
|
||||
|
||||
Plugin_context *context = new (Genode::env()->heap())
|
||||
Plugin_context(pathname, flags);
|
||||
|
||||
int res;
|
||||
int tries = 0;
|
||||
do {
|
||||
/* first try to open pathname */
|
||||
res = Fuse::fuse()->op.open(pathname, &context->file_info);
|
||||
if (res == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* try to create pathname if open failed and O_CREAT flag was specified */
|
||||
if (flags & O_CREAT && !tries) {
|
||||
mode_t mode = S_IFREG | 0644;
|
||||
int res = Fuse::fuse()->op.mknod(pathname, mode, 0);
|
||||
switch (res) {
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
error(__func__, ": could not create '", pathname, "'");
|
||||
destroy(env()->heap(), context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tries++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (res < 0) {
|
||||
errno = -res;
|
||||
destroy(env()->heap(), context);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
while (true);
|
||||
|
||||
if (flags & O_TRUNC) {
|
||||
res = Fuse::fuse()->op.ftruncate(pathname, 0,
|
||||
&context->file_info);
|
||||
if (res != 0) {
|
||||
errno = -res;
|
||||
Fuse::fuse()->op.release(context->path.string(),
|
||||
&context->file_info);
|
||||
destroy(env()->heap(), context);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
context->file_info.flags = flags;
|
||||
|
||||
return Libc::file_descriptor_allocator()->alloc(this, context);
|
||||
}
|
||||
|
||||
ssize_t read(Libc::File_descriptor *fd, void *buf, ::size_t count)
|
||||
{
|
||||
Plugin_context *ctx = context(fd);
|
||||
|
||||
int res = Fuse::fuse()->op.read(ctx->path.string(),
|
||||
reinterpret_cast<char*>(buf),
|
||||
count, ctx->offset, &ctx->file_info);
|
||||
|
||||
if (check_result(res))
|
||||
return -1;
|
||||
|
||||
ctx->offset += res;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
ssize_t readlink(const char *path, char *buf, ::size_t bufsiz)
|
||||
{
|
||||
int res = Fuse::fuse()->op.readlink(path, buf, bufsiz);
|
||||
if (res < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* We have to trust each FUSE file system to append a
|
||||
* null byte to buf, which is required according to
|
||||
* FUSEs documentation.
|
||||
*/
|
||||
return Genode::strlen(buf);
|
||||
}
|
||||
|
||||
int rename(const char *oldpath, const char *newpath)
|
||||
{
|
||||
int res = Fuse::fuse()->op.rename(oldpath, newpath);
|
||||
|
||||
return check_result(res);
|
||||
}
|
||||
|
||||
int rmdir(const char *path)
|
||||
{
|
||||
int res = Fuse::fuse()->op.rmdir(path);
|
||||
|
||||
return check_result(res);
|
||||
}
|
||||
|
||||
int stat(const char *path, struct stat *buf)
|
||||
{
|
||||
Genode::memset(buf, 0, sizeof (buf));
|
||||
|
||||
int res = Fuse::fuse()->op.getattr(path, buf);
|
||||
|
||||
return check_result(res);
|
||||
}
|
||||
|
||||
int symlink(const char *oldpath, const char *newpath)
|
||||
{
|
||||
int res = Fuse::fuse()->op.symlink(oldpath, newpath);
|
||||
|
||||
return check_result(res);
|
||||
}
|
||||
|
||||
int unlink(const char *path)
|
||||
{
|
||||
int res = Fuse::fuse()->op.unlink(path);
|
||||
|
||||
return check_result(res);
|
||||
}
|
||||
|
||||
ssize_t write(Libc::File_descriptor *fd, const void *buf, ::size_t count)
|
||||
{
|
||||
Plugin_context *ctx = context(fd);
|
||||
|
||||
int res = Fuse::fuse()->op.write(ctx->path.string(),
|
||||
reinterpret_cast<const char*>(buf),
|
||||
count, ctx->offset, &ctx->file_info);
|
||||
|
||||
if (check_result(res))
|
||||
return -1;
|
||||
|
||||
ctx->offset += res;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} /* unnamed namespace */
|
||||
|
||||
|
||||
void __attribute__((constructor)) init_libc_fuse(void)
|
||||
{
|
||||
/*
|
||||
* During the initialization of the plugin, we already require the VFS.
|
||||
* Hence, we need to make sure to initialize the VFS before doing our
|
||||
* own initialization.
|
||||
*/
|
||||
extern void init_libc_vfs(void);
|
||||
init_libc_vfs();
|
||||
|
||||
static Plugin plugin;
|
||||
}
|
@ -1,372 +0,0 @@
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define this to 1 if you want to enable support of encrypted files in
|
||||
libntfs and utilities. */
|
||||
/* #undef ENABLE_CRYPTO */
|
||||
|
||||
/* Define to 1 if debug should be enabled */
|
||||
/* #undef ENABLE_DEBUG */
|
||||
|
||||
/* Define to 1 if the nfconv patch should be enabled */
|
||||
/* #undef ENABLE_NFCONV */
|
||||
|
||||
/* Define this to 1 if you want to enable generation of DCE compliant UUIDs.
|
||||
*/
|
||||
/* #undef ENABLE_UUID */
|
||||
|
||||
/* Define to 1 if using internal fuse */
|
||||
/* #undef FUSE_INTERNAL */
|
||||
|
||||
/* Define to 1 if you have the `atexit' function. */
|
||||
#define HAVE_ATEXIT 1
|
||||
|
||||
/* Define to 1 if you have the `basename' function. */
|
||||
#define HAVE_BASENAME 1
|
||||
|
||||
/* Define to 1 if you have the <byteswap.h> header file. */
|
||||
/* #undef HAVE_BYTESWAP_H */
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
/* #undef HAVE_CLOCK_GETTIME */
|
||||
|
||||
/* Define to 1 if you have the <ctype.h> header file. */
|
||||
#define HAVE_CTYPE_H 1
|
||||
|
||||
/* Define to 1 if you have the `daemon' function. */
|
||||
/* #undef HAVE_DAEMON */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
|
||||
/* #undef HAVE_DOPRNT */
|
||||
|
||||
/* Define to 1 if you have the `dup2' function. */
|
||||
#define HAVE_DUP2 1
|
||||
|
||||
/* Define to 1 if you have the <endian.h> header file. */
|
||||
/* #undef HAVE_ENDIAN_H */
|
||||
|
||||
/* Define to 1 if you have the <errno.h> header file. */
|
||||
#define HAVE_ERRNO_H 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the `fdatasync' function. */
|
||||
/* #undef HAVE_FDATASYNC */
|
||||
|
||||
/* Define to 1 if you have the <features.h> header file. */
|
||||
/* #undef HAVE_FEATURES_H */
|
||||
|
||||
/* Define to 1 if you have the `ffs' function. */
|
||||
#define HAVE_FFS 1
|
||||
|
||||
/* Define to 1 if you have the `fork' function. */
|
||||
#define HAVE_FORK 1
|
||||
|
||||
/* Define to 1 if you have the `getmntent' function. */
|
||||
/* #undef HAVE_GETMNTENT */
|
||||
|
||||
/* Define to 1 if you have the <getopt.h> header file. */
|
||||
#define HAVE_GETOPT_H 1
|
||||
|
||||
/* Define to 1 if you have the `getopt_long' function. */
|
||||
#define HAVE_GETOPT_LONG 1
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
|
||||
/* Define to 1 if you have the `hasmntopt' function. */
|
||||
/* #undef HAVE_HASMNTOPT */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <libgen.h> header file. */
|
||||
#define HAVE_LIBGEN_H 1
|
||||
|
||||
/* Define to 1 if you have the <libintl.h> header file. */
|
||||
/* #undef HAVE_LIBINTL_H */
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define to 1 if you have the <linux/fd.h> header file. */
|
||||
/* #undef HAVE_LINUX_FD_H */
|
||||
|
||||
/* Define to 1 if you have the <linux/hdreg.h> header file. */
|
||||
/* #undef HAVE_LINUX_HDREG_H */
|
||||
|
||||
/* Define to 1 if you have the <linux/major.h> header file. */
|
||||
/* #undef HAVE_LINUX_MAJOR_H */
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#define HAVE_LOCALE_H 1
|
||||
|
||||
/* Define to 1 if you have the <machine/endian.h> header file. */
|
||||
#define HAVE_MACHINE_ENDIAN_H 1
|
||||
|
||||
/* Define to 1 if mbrtowc and mbstate_t are properly declared. */
|
||||
#define HAVE_MBRTOWC 1
|
||||
|
||||
/* Define to 1 if you have the `mbsinit' function. */
|
||||
#define HAVE_MBSINIT 1
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
#define HAVE_MEMMOVE 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* Define to 1 if you have the <mntent.h> header file. */
|
||||
/* #undef HAVE_MNTENT_H */
|
||||
|
||||
/* Define to 1 if you have the <pwd.h> header file. */
|
||||
#define HAVE_PWD_H 1
|
||||
|
||||
/* Define to 1 if you have the `realpath' function. */
|
||||
#define HAVE_REALPATH 1
|
||||
|
||||
|
||||
/* Define to 1 if you have the `regcomp' function. */
|
||||
#define HAVE_REGCOMP 1
|
||||
|
||||
/* Define to 1 if you have the `setlocale' function. */
|
||||
#define HAVE_SETLOCALE 1
|
||||
|
||||
/* Define to 1 if you have the `setxattr' function. */
|
||||
/* #undef HAVE_SETXATTR */
|
||||
|
||||
/* Define to 1 if `stat' has the bug that it succeeds when given the
|
||||
zero-length file name argument. */
|
||||
#define HAVE_STAT_EMPTY_STRING_BUG 1
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#define HAVE_STDARG_H 1
|
||||
|
||||
/* Define to 1 if stdbool.h conforms to C99. */
|
||||
#define HAVE_STDBOOL_H 1
|
||||
|
||||
/* Define to 1 if you have the <stddef.h> header file. */
|
||||
#define HAVE_STDDEF_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdio.h> header file. */
|
||||
#define HAVE_STDIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#define HAVE_STRERROR 1
|
||||
|
||||
/* Define to 1 if you have the `strftime' function. */
|
||||
#define HAVE_STRFTIME 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strnlen' function. */
|
||||
/* #undef HAVE_STRNLEN */
|
||||
|
||||
/* Define to 1 if you have the `strsep' function. */
|
||||
#define HAVE_STRSEP 1
|
||||
|
||||
/* Define to 1 if you have the `strtol' function. */
|
||||
#define HAVE_STRTOL 1
|
||||
|
||||
/* Define to 1 if you have the `strtoul' function. */
|
||||
#define HAVE_STRTOUL 1
|
||||
|
||||
/* Define to 1 if `st_atim' is member of `struct stat'. */
|
||||
/* #undef HAVE_STRUCT_STAT_ST_ATIM */
|
||||
|
||||
/* Define to 1 if `st_atimensec' is member of `struct stat'. */
|
||||
/* #undef HAVE_STRUCT_STAT_ST_ATIMENSEC */
|
||||
|
||||
/* Define to 1 if `st_atimespec' is member of `struct stat'. */
|
||||
#define HAVE_STRUCT_STAT_ST_ATIMESPEC 1
|
||||
|
||||
/* Define to 1 if `st_blocks' is member of `struct stat'. */
|
||||
#define HAVE_STRUCT_STAT_ST_BLOCKS 1
|
||||
|
||||
/* Define to 1 if `st_rdev' is member of `struct stat'. */
|
||||
#define HAVE_STRUCT_STAT_ST_RDEV 1
|
||||
|
||||
/* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use
|
||||
`HAVE_STRUCT_STAT_ST_BLOCKS' instead. */
|
||||
#define HAVE_ST_BLOCKS 1
|
||||
|
||||
/* Define to 1 if you have the `sysconf' function. */
|
||||
#define HAVE_SYSCONF 1
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#define HAVE_SYSLOG_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/byteorder.h> header file. */
|
||||
/* #undef HAVE_SYS_BYTEORDER_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/disk.h> header file. */
|
||||
#define HAVE_SYS_DISK_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/endian.h> header file. */
|
||||
#define HAVE_SYS_ENDIAN_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/mkdev.h> header file. */
|
||||
/* #undef HAVE_SYS_MKDEV_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/mount.h> header file. */
|
||||
#define HAVE_SYS_MOUNT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/statvfs.h> header file. */
|
||||
#define HAVE_SYS_STATVFS_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/sysmacros.h> header file. */
|
||||
/* #undef HAVE_SYS_SYSMACROS_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/vfs.h> header file. */
|
||||
/* #undef HAVE_SYS_VFS_H */
|
||||
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#define HAVE_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `utime' function. */
|
||||
#define HAVE_UTIME 1
|
||||
|
||||
/* Define to 1 if you have the `utimensat' function. */
|
||||
/* #undef HAVE_UTIMENSAT */
|
||||
|
||||
/* Define to 1 if you have the <utime.h> header file. */
|
||||
#define HAVE_UTIME_H 1
|
||||
|
||||
/* Define to 1 if `utime(file, NULL)' sets file's timestamp to the present. */
|
||||
#define HAVE_UTIME_NULL 1
|
||||
|
||||
/* Define to 1 if you have the `vprintf' function. */
|
||||
#define HAVE_VPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the <wchar.h> header file. */
|
||||
#define HAVE_WCHAR_H 1
|
||||
|
||||
/* Define to 1 if you have the <windows.h> header file. */
|
||||
/* #undef HAVE_WINDOWS_H */
|
||||
|
||||
/* Define to 1 if the system has the type `_Bool'. */
|
||||
#define HAVE__BOOL 1
|
||||
|
||||
/* Don't update /etc/mtab */
|
||||
/* #undef IGNORE_MTAB */
|
||||
|
||||
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
|
||||
slash. */
|
||||
/* #undef LSTAT_FOLLOWS_SLASHED_SYMLINK */
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
/* #undef NO_MINUS_C_MINUS_O */
|
||||
|
||||
/* Don't use default IO ops */
|
||||
/* #undef NO_NTFS_DEVICE_DEFAULT_IO_OPS */
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "ntfs3g-genode"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "ntfs-3g"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "ntfs3g-genode 2013.1.3"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "ntfs-3g"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "2013.1.13"
|
||||
|
||||
/* POSIX ACL support */
|
||||
/* #undef POSIXACLS */
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "2013.1.13"
|
||||
|
||||
/* Define to 1 if this is a Windows OS */
|
||||
/* #undef WINDOWS */
|
||||
|
||||
/* Define to 1 if your processor stores words with the most significant byte
|
||||
first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
/* #undef WORDS_BIGENDIAN */
|
||||
|
||||
/* Define to 1 if your processor stores words with the least significant byte
|
||||
first (like Intel and VAX, unlike Motorola and SPARC). */
|
||||
#define WORDS_LITTLEENDIAN 1
|
||||
|
||||
/* system extended attributes mappings */
|
||||
/* #undef XATTR_MAPPINGS */
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
/* #undef _FILE_OFFSET_BITS */
|
||||
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef _LARGE_FILES */
|
||||
|
||||
/* Required define if using POSIX threads */
|
||||
/* #undef _REENTRANT */
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
/* #undef inline */
|
||||
#endif
|
||||
|
||||
/* Define to `long int' if <sys/types.h> does not define. */
|
||||
/* #undef off_t */
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* #undef size_t */
|
@ -1,112 +0,0 @@
|
||||
/*
|
||||
* \brief libc_fuse_ntfs-3g
|
||||
* \author Josef Soentgen
|
||||
* \date 2013-11-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <util/string.h>
|
||||
|
||||
#include <fuse.h>
|
||||
#include <fuse_private.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <stdlib.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include <device.h>
|
||||
#include <security.h>
|
||||
#include <ntfs-3g_common.h>
|
||||
|
||||
extern struct fuse_operations ntfs_3g_ops;
|
||||
|
||||
struct fuse_chan *fc;
|
||||
struct fuse *fh;
|
||||
|
||||
extern ntfs_fuse_context_t **ntfs_fuse_ctx();
|
||||
extern int ntfs_open(const char*);
|
||||
extern void ntfs_close(void);
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Fuse::init_fs(void)
|
||||
{
|
||||
ntfs_set_locale();
|
||||
ntfs_log_set_handler(ntfs_log_handler_stderr);
|
||||
|
||||
ntfs_fuse_context_t **ctx = ntfs_fuse_ctx();
|
||||
|
||||
*ctx = reinterpret_cast<ntfs_fuse_context_t *>(malloc(sizeof (ntfs_fuse_context_t)));
|
||||
if (!*ctx) {
|
||||
Genode::error("out of memory");
|
||||
return false;
|
||||
}
|
||||
|
||||
Genode::memset(*ctx, 0, sizeof (ntfs_fuse_context_t));
|
||||
(*ctx)->streams = NF_STREAMS_INTERFACE_NONE;
|
||||
(*ctx)->atime = ATIME_RELATIVE;
|
||||
(*ctx)->silent = TRUE;
|
||||
(*ctx)->recover = TRUE;
|
||||
|
||||
/*
|
||||
*ctx = (ntfs_fuse_context_t) {
|
||||
.uid = 0,
|
||||
.gid = 0,
|
||||
.streams = NF_STREAMS_INTERFACE_NONE,
|
||||
.atime = ATIME_RELATIVE,
|
||||
.silent = TRUE,
|
||||
.recover = TRUE
|
||||
};
|
||||
*/
|
||||
|
||||
Genode::log("libc_fuse_ntfs-3g: try to mount /dev/blkdev...");
|
||||
|
||||
int err = ntfs_open("/dev/blkdev");
|
||||
if (err) {
|
||||
Genode::error("libc_fuse_ntfs-3g: could not mount /dev/blkdev");
|
||||
return false;
|
||||
}
|
||||
|
||||
fh = fuse_new(fc, NULL, &ntfs_3g_ops, sizeof (ntfs_3g_ops), NULL);
|
||||
if (fh == 0) {
|
||||
Genode::error("libc_fuse_exfat: fuse_new() failed");
|
||||
ntfs_close();
|
||||
return false;
|
||||
}
|
||||
|
||||
(*ctx)->mounted = TRUE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Fuse::deinit_fs(void)
|
||||
{
|
||||
Genode::log("libc_fuse_ntfs-3g: unmount /dev/blkdev...");
|
||||
ntfs_close();
|
||||
|
||||
free(*ntfs_fuse_ctx());
|
||||
}
|
||||
|
||||
|
||||
void Fuse::sync_fs(void)
|
||||
{
|
||||
Genode::log("libc_fuse_ntfs-3g: sync file system...");
|
||||
ntfs_device_sync((*ntfs_fuse_ctx())->vol->dev);
|
||||
}
|
||||
|
||||
|
||||
bool Fuse::support_symlinks(void)
|
||||
{
|
||||
return true;
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
+++ src/lib/ntfs-3g/src/ntfs-3g.c
|
||||
@@ -151,6 +151,11 @@
|
||||
static ntfs_fuse_context_t *ctx;
|
||||
static u32 ntfs_sequence;
|
||||
|
||||
+ntfs_fuse_context_t **ntfs_fuse_ctx()
|
||||
+{
|
||||
+ return &ctx;
|
||||
+}
|
||||
+
|
||||
static const char *usage_msg =
|
||||
"\n"
|
||||
"%s %s %s %d - Third Generation NTFS Driver\n"
|
||||
@@ -3266,7 +3271,7 @@
|
||||
#endif
|
||||
#endif /* HAVE_SETXATTR */
|
||||
|
||||
-static void ntfs_close(void)
|
||||
+void ntfs_close(void)
|
||||
{
|
||||
struct SECURITY_CONTEXT security;
|
||||
|
||||
@@ -3305,7 +3310,7 @@
|
||||
ntfs_close();
|
||||
}
|
||||
|
||||
-static struct fuse_operations ntfs_3g_ops = {
|
||||
+struct fuse_operations ntfs_3g_ops = {
|
||||
#if defined(HAVE_UTIMENSAT) && (defined(FUSE_INTERNAL) || (FUSE_VERSION > 28))
|
||||
/*
|
||||
* Accept UTIME_NOW and UTIME_OMIT in utimens, when
|
||||
@@ -3387,7 +3392,7 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int ntfs_open(const char *device)
|
||||
+int ntfs_open(const char *device)
|
||||
{
|
||||
unsigned long flags = 0;
|
||||
|
||||
@@ -3669,6 +3674,7 @@
|
||||
ntfs_log_info("Mount options: %s\n", parsed_options);
|
||||
}
|
||||
|
||||
+#if 0
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *parsed_options = NULL;
|
||||
@@ -3931,3 +3937,4 @@
|
||||
free(opts.device);
|
||||
return err;
|
||||
}
|
||||
+#endif
|
@ -1,26 +0,0 @@
|
||||
The fuse_fs server provides access to a FUSE based file system by using a
|
||||
File_system_session.
|
||||
|
||||
The File_system_session component implementation is independent from each
|
||||
FUSE based file system. fuse_fs 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 executeable, 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 the File_system_session component. For each
|
||||
fuse_fs server there is a binary (.e.g. 'os/src/server/fuse_fs/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_fs server in noux the following config snippet may be
|
||||
used:
|
||||
|
||||
! <start name="ext2_fuse_fs">
|
||||
! <resource name="RAM" quantum="8M"/>
|
||||
! <provides> <service name="File_system"/> </provides>
|
||||
! <config>
|
||||
! <policy label_prefix="noux -> fuse" root="/" writeable="no" />
|
||||
! </config>
|
||||
! </start>
|
@ -1,293 +0,0 @@
|
||||
/*
|
||||
* \brief File-system directory node
|
||||
* \author Norman Feske
|
||||
* \author Christian Helmuth
|
||||
* \author Josef Soentgen
|
||||
* \date 2013-11-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 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 _DIRECTORY_H_
|
||||
#define _DIRECTORY_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <os/path.h>
|
||||
#include <util/string.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* local includes */
|
||||
#include <file.h>
|
||||
#include <mode_util.h>
|
||||
#include <node.h>
|
||||
#include <util.h>
|
||||
#include <symlink.h>
|
||||
|
||||
#include <fuse.h>
|
||||
#include <fuse_private.h>
|
||||
|
||||
|
||||
namespace Fuse_fs {
|
||||
class Directory;
|
||||
}
|
||||
|
||||
|
||||
class Fuse_fs::Directory : public Node
|
||||
{
|
||||
private:
|
||||
|
||||
typedef Genode::Path<MAX_PATH_LEN> Path;
|
||||
|
||||
struct fuse_file_info _file_info;
|
||||
Path _path;
|
||||
Allocator &_alloc;
|
||||
|
||||
/**
|
||||
* Check if the given path points to a directory
|
||||
*/
|
||||
bool _is_dir(char const *path)
|
||||
{
|
||||
struct stat s;
|
||||
if (Fuse::fuse()->op.getattr(path, &s) != 0 || ! S_ISDIR(s.st_mode))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void _open_path(char const *path, bool create)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (create) {
|
||||
|
||||
res = Fuse::fuse()->op.mkdir(path, 0755);
|
||||
|
||||
if (res < 0) {
|
||||
int err = -res;
|
||||
switch (err) {
|
||||
case EACCES:
|
||||
Genode::error("op.mkdir() permission denied");
|
||||
throw Permission_denied();
|
||||
case EEXIST:
|
||||
throw Node_already_exists();
|
||||
case EIO:
|
||||
Genode::error("op.mkdir() I/O error occurred");
|
||||
throw Lookup_failed();
|
||||
case ENOENT:
|
||||
throw Lookup_failed();
|
||||
case ENOTDIR:
|
||||
throw Lookup_failed();
|
||||
case ENOSPC:
|
||||
Genode::error("op.mkdir() error while expanding directory");
|
||||
throw Lookup_failed();
|
||||
case EROFS:
|
||||
throw Permission_denied();
|
||||
default:
|
||||
Genode::error("op.mkdir() returned unexpected error code: ", res);
|
||||
throw Lookup_failed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res = Fuse::fuse()->op.opendir(path, &_file_info);
|
||||
|
||||
if (res < 0) {
|
||||
int err = -res;
|
||||
switch (err) {
|
||||
case EACCES:
|
||||
Genode::error("op.opendir() permission denied");
|
||||
throw Permission_denied();
|
||||
case EIO:
|
||||
Genode::error("op.opendir() I/O error occurred");
|
||||
throw Lookup_failed();
|
||||
case ENOENT:
|
||||
throw Lookup_failed();
|
||||
case ENOTDIR:
|
||||
throw Lookup_failed();
|
||||
case ENOSPC:
|
||||
Genode::error("op.opendir() error while expanding directory");
|
||||
throw Lookup_failed();
|
||||
case EROFS:
|
||||
throw Permission_denied();
|
||||
default:
|
||||
Genode::error("op.opendir() returned unexpected error code: ", res);
|
||||
throw Lookup_failed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t _num_entries()
|
||||
{
|
||||
char buf[4096];
|
||||
|
||||
Genode::memset(buf, 0, sizeof (buf));
|
||||
|
||||
struct fuse_dirhandle dh = {
|
||||
.filler = Fuse::fuse()->filler,
|
||||
.buf = buf,
|
||||
.size = sizeof (buf),
|
||||
.offset = 0,
|
||||
};
|
||||
|
||||
int res = Fuse::fuse()->op.readdir(_path.base(), &dh,
|
||||
Fuse::fuse()->filler, 0,
|
||||
&_file_info);
|
||||
|
||||
if (res != 0)
|
||||
return 0;
|
||||
|
||||
return dh.offset / sizeof (struct dirent);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Directory(Allocator &alloc, char const *path, bool create)
|
||||
:
|
||||
Node(path),
|
||||
_path(path),
|
||||
_alloc(alloc)
|
||||
{
|
||||
if (!create && !_is_dir(path))
|
||||
throw Lookup_failed();
|
||||
|
||||
_open_path(path, create);
|
||||
}
|
||||
|
||||
virtual ~Directory()
|
||||
{
|
||||
Fuse::fuse()->op.release(_path.base(), &_file_info);
|
||||
}
|
||||
|
||||
Node *node(char const *path)
|
||||
{
|
||||
Path node_path(path, _path.base());
|
||||
|
||||
struct stat s;
|
||||
int res = Fuse::fuse()->op.getattr(node_path.base(), &s);
|
||||
if (res != 0)
|
||||
throw Lookup_failed();
|
||||
|
||||
Node *node = 0;
|
||||
|
||||
if (S_ISDIR(s.st_mode))
|
||||
node = new (&_alloc) Directory(_alloc, node_path.base(), false);
|
||||
else if (S_ISREG(s.st_mode))
|
||||
node = new (&_alloc) File(this, path, STAT_ONLY);
|
||||
else if (S_ISLNK(s.st_mode))
|
||||
node = new (&_alloc) Symlink(this, path, false);
|
||||
else
|
||||
throw Lookup_failed();
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
struct fuse_file_info *file_info() { return &_file_info; }
|
||||
|
||||
Status status() override
|
||||
{
|
||||
struct stat s;
|
||||
int res = Fuse::fuse()->op.getattr(_path.base(), &s);
|
||||
if (res != 0)
|
||||
return Status();
|
||||
|
||||
Status status;
|
||||
status.inode = s.st_ino ? s.st_ino : 1;
|
||||
status.size = _num_entries() * sizeof(Directory_entry);
|
||||
status.mode = File_system::Status::MODE_DIRECTORY;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
size_t read(char *dst, size_t len, seek_off_t seek_offset) override
|
||||
{
|
||||
if (len < sizeof(Directory_entry)) {
|
||||
Genode::error("read buffer too small for directory entry");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (seek_offset % sizeof(Directory_entry)) {
|
||||
Genode::error("seek offset not aligned to sizeof(Directory_entry)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
seek_off_t index = seek_offset / sizeof(Directory_entry);
|
||||
|
||||
char buf[4096];
|
||||
|
||||
Genode::memset(buf, 0, sizeof (buf));
|
||||
struct dirent *de = (struct dirent *)buf;
|
||||
|
||||
struct fuse_dirhandle dh = {
|
||||
.filler = Fuse::fuse()->filler,
|
||||
.buf = buf,
|
||||
.size = sizeof (buf),
|
||||
.offset = 0,
|
||||
};
|
||||
|
||||
int res = Fuse::fuse()->op.readdir(_path.base(), &dh,
|
||||
Fuse::fuse()->filler, 0,
|
||||
&_file_info);
|
||||
if (res != 0)
|
||||
return 0;
|
||||
|
||||
if (index > (seek_off_t)(dh.offset / sizeof (struct dirent)))
|
||||
return 0;
|
||||
|
||||
struct dirent *dent = de + index;
|
||||
if (!dent)
|
||||
return 0;
|
||||
|
||||
Directory_entry *e = (Directory_entry *)(dst);
|
||||
|
||||
switch (dent->d_type) {
|
||||
case DT_REG: e->type = Directory_entry::TYPE_FILE; break;
|
||||
case DT_DIR: e->type = Directory_entry::TYPE_DIRECTORY; break;
|
||||
case DT_LNK: e->type = Directory_entry::TYPE_SYMLINK; break;
|
||||
/**
|
||||
* There are FUSE file system implementations that do not fill-out
|
||||
* d_type when calling readdir(). We mark these entries by setting
|
||||
* their type to DT_UNKNOWN in our libfuse implementation. Afterwards
|
||||
* we call getattr() on each entry that, hopefully, will yield proper
|
||||
* results.
|
||||
*/
|
||||
case DT_UNKNOWN:
|
||||
{
|
||||
Genode::Path<4096> path(dent->d_name, _path.base());
|
||||
struct stat sbuf;
|
||||
res = Fuse::fuse()->op.getattr(path.base(), &sbuf);
|
||||
if (res == 0) {
|
||||
switch (IFTODT(sbuf.st_mode)) {
|
||||
case DT_REG: e->type = Directory_entry::TYPE_FILE; break;
|
||||
case DT_DIR: e->type = Directory_entry::TYPE_DIRECTORY; break;
|
||||
}
|
||||
/* break outer switch */
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
strncpy(e->name, dent->d_name, sizeof(e->name));
|
||||
|
||||
return sizeof(Directory_entry);
|
||||
}
|
||||
|
||||
size_t write(char const *src, size_t len, seek_off_t seek_offset) override
|
||||
{
|
||||
/* writing to directory nodes is not supported */
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _DIRECTORY_H_ */
|
@ -1,18 +0,0 @@
|
||||
EXFAT_DIR := $(call select_from_ports,exfat)/src/lib/exfat
|
||||
|
||||
TARGET = exfat_fuse_fs
|
||||
|
||||
SRC_C = $(notdir $(EXFAT_DIR)/fuse/main.c)
|
||||
SRC_CC = fuse_fs_main.cc \
|
||||
init.cc
|
||||
|
||||
LIBS = libc libfuse libexfat
|
||||
INC_DIR += $(PRG_DIR)/..
|
||||
|
||||
CC_OPT += -Wno-unused-function
|
||||
|
||||
vpath %.c $(EXFAT_DIR)/fuse
|
||||
vpath fuse_fs_main.cc $(PRG_DIR)/..
|
||||
vpath init.cc $(PRG_DIR)/../../../lib/exfat
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -1,34 +0,0 @@
|
||||
FUSE_EXT2_DIR = $(call select_from_ports,fuse-ext2)/src/lib/fuse-ext2/fuse-ext2
|
||||
|
||||
TARGET = ext2_fuse_fs
|
||||
|
||||
FILTER_OUT = fuse-ext2.probe.c fuse-ext2.wait.c
|
||||
SRC_C = $(filter-out $(FILTER_OUT), $(notdir $(wildcard $(FUSE_EXT2_DIR)/*.c)))
|
||||
|
||||
|
||||
SRC_CC = fuse_fs_main.cc \
|
||||
init.cc
|
||||
|
||||
LIBS = libc libfuse libext2fs
|
||||
|
||||
CC_OPT += -DHAVE_CONFIG_H -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64
|
||||
|
||||
CC_OPT += -Wno-unused-function -Wno-unused-variable \
|
||||
-Wno-unused-but-set-variable -Wno-cpp \
|
||||
-Wno-maybe-uninitialized
|
||||
|
||||
CC_C_OPT += -std=gnu89
|
||||
|
||||
CC_C_OPT += -Wno-implicit-function-declaration
|
||||
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/lib/fuse-ext2 \
|
||||
$(FUSE_EXT2_DIR)
|
||||
|
||||
INC_DIR += $(PRG_DIR)/..
|
||||
|
||||
vpath %.c $(FUSE_EXT2_DIR)
|
||||
vpath fuse_fs_main.cc $(PRG_DIR)/..
|
||||
vpath init.cc $(PRG_DIR)/../../../lib/fuse-ext2
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -1,159 +0,0 @@
|
||||
/*
|
||||
* \brief File node
|
||||
* \author Norman Feske
|
||||
* \author Christian Helmuth
|
||||
* \author Josef Soentgen
|
||||
* \date 2013-11-26
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 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 _FILE_H_
|
||||
#define _FILE_H_
|
||||
|
||||
/* local includes */
|
||||
#include <mode_util.h>
|
||||
#include <node.h>
|
||||
|
||||
#include <fuse.h>
|
||||
#include <fuse_private.h>
|
||||
|
||||
namespace Fuse_fs {
|
||||
class File;
|
||||
}
|
||||
|
||||
|
||||
class Fuse_fs::File : public Node
|
||||
{
|
||||
private:
|
||||
|
||||
Node *_parent;
|
||||
|
||||
typedef Genode::Path<MAX_PATH_LEN> Path;
|
||||
Path _path;
|
||||
|
||||
struct fuse_file_info _file_info;
|
||||
|
||||
void _open_path(char const *path, Mode mode, bool create, bool trunc)
|
||||
{
|
||||
int res;
|
||||
int tries = 0;
|
||||
do {
|
||||
/* first try to open pathname */
|
||||
res = Fuse::fuse()->op.open(path, &_file_info);
|
||||
if (res == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* try to create pathname if open failed and create is true */
|
||||
if (create && !tries) {
|
||||
mode_t mode = S_IFREG | 0644;
|
||||
int res = Fuse::fuse()->op.mknod(path, mode, 0);
|
||||
switch (res) {
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
Genode::error("could not create '", path, "'");
|
||||
throw Lookup_failed();
|
||||
}
|
||||
|
||||
tries++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (res < 0) {
|
||||
throw Lookup_failed();
|
||||
}
|
||||
}
|
||||
while (true);
|
||||
|
||||
if (trunc) {
|
||||
res = Fuse::fuse()->op.ftruncate(path, 0, &_file_info);
|
||||
|
||||
if (res != 0) {
|
||||
Fuse::fuse()->op.release(path, &_file_info);
|
||||
throw Lookup_failed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t _length()
|
||||
{
|
||||
struct stat s;
|
||||
int res = Fuse::fuse()->op.getattr(_path.base(), &s);
|
||||
if (res != 0)
|
||||
return 0;
|
||||
|
||||
return s.st_size;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
File(Node *parent, char const *name, Mode mode,
|
||||
bool create = false, bool trunc = false)
|
||||
:
|
||||
Node(name),
|
||||
_parent(parent),
|
||||
_path(name, _parent->name())
|
||||
{
|
||||
_open_path(_path.base(), mode, create, trunc);
|
||||
}
|
||||
|
||||
~File()
|
||||
{
|
||||
Fuse::fuse()->op.release(_path.base(), &_file_info);
|
||||
}
|
||||
|
||||
struct fuse_file_info *file_info() { return &_file_info; }
|
||||
|
||||
Status status() override
|
||||
{
|
||||
struct stat s;
|
||||
int res = Fuse::fuse()->op.getattr(_path.base(), &s);
|
||||
if (res != 0)
|
||||
return Status();
|
||||
|
||||
Status status;
|
||||
status.inode = s.st_ino ? s.st_ino : 1;
|
||||
status.size = s.st_size;
|
||||
status.mode = File_system::Status::MODE_FILE;
|
||||
return status;
|
||||
}
|
||||
|
||||
size_t read(char *dst, size_t len, seek_off_t seek_offset) override
|
||||
{
|
||||
/* append mode, use actual length as offset */
|
||||
if (seek_offset == ~0ULL)
|
||||
seek_offset = _length();
|
||||
|
||||
int ret = Fuse::fuse()->op.read(_path.base(), dst, len,
|
||||
seek_offset, &_file_info);
|
||||
return ret < 0 ? 0 : ret;
|
||||
}
|
||||
|
||||
size_t write(char const *src, size_t len, seek_off_t seek_offset) override
|
||||
{
|
||||
/* append mode, use actual length as offset */
|
||||
if (seek_offset == ~0ULL)
|
||||
seek_offset = _length();
|
||||
|
||||
int ret = Fuse::fuse()->op.write(_path.base(), src, len,
|
||||
seek_offset, &_file_info);
|
||||
return ret < 0 ? 0 : ret;
|
||||
}
|
||||
|
||||
void truncate(file_size_t size) override
|
||||
{
|
||||
int res = Fuse::fuse()->op.ftruncate(_path.base(), size,
|
||||
&_file_info);
|
||||
if (res == 0)
|
||||
mark_as_updated();
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _FILE_H_ */
|
@ -1,595 +0,0 @@
|
||||
/*
|
||||
* \brief FUSE file system
|
||||
* \author Josef Soentgen
|
||||
* \date 2013-11-27
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/heap.h>
|
||||
#include <file_system_session/rpc_object.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <os/session_policy.h>
|
||||
#include <root/component.h>
|
||||
#include <util/xml_node.h>
|
||||
#include <libc/component.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <errno.h>
|
||||
|
||||
/* local includes */
|
||||
#include <directory.h>
|
||||
#include <open_node.h>
|
||||
#include <util.h>
|
||||
|
||||
|
||||
namespace Fuse_fs {
|
||||
|
||||
using namespace Genode;
|
||||
using File_system::Packet_descriptor;
|
||||
using File_system::Path;
|
||||
|
||||
struct Main;
|
||||
struct Session_component;
|
||||
struct Root;
|
||||
}
|
||||
|
||||
|
||||
class Fuse_fs::Session_component : public Session_rpc_object
|
||||
{
|
||||
private:
|
||||
|
||||
typedef File_system::Open_node<Node> Open_node;
|
||||
|
||||
Genode::Env &_env;
|
||||
Allocator &_md_alloc;
|
||||
Directory &_root;
|
||||
Id_space<File_system::Node> _open_node_registry;
|
||||
bool _writeable;
|
||||
|
||||
Signal_handler<Session_component> _process_packet_handler;
|
||||
|
||||
|
||||
/******************************
|
||||
** Packet-stream processing **
|
||||
******************************/
|
||||
|
||||
/**
|
||||
* Perform packet operation
|
||||
*
|
||||
* \return true on success, false on failure
|
||||
*/
|
||||
void _process_packet_op(Packet_descriptor &packet, Open_node &open_node)
|
||||
{
|
||||
void * const content = tx_sink()->packet_content(packet);
|
||||
size_t const length = packet.length();
|
||||
|
||||
/* resulting length */
|
||||
size_t res_length = 0;
|
||||
bool succeeded = false;
|
||||
|
||||
switch (packet.operation()) {
|
||||
|
||||
case Packet_descriptor::READ:
|
||||
if (content && (packet.length() <= packet.size())) {
|
||||
res_length = open_node.node().read((char *)content, length,
|
||||
packet.position());
|
||||
|
||||
succeeded = res_length > 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case Packet_descriptor::WRITE:
|
||||
if (content && (packet.length() <= packet.size())) {
|
||||
res_length = open_node.node().write((char const *)content, length, packet.position());
|
||||
|
||||
/* File system session can't handle partial writes */
|
||||
if (res_length != length) {
|
||||
Genode::error("partial write detected ",
|
||||
res_length, " vs ", length);
|
||||
/* don't acknowledge */
|
||||
return;
|
||||
}
|
||||
succeeded = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case Packet_descriptor::CONTENT_CHANGED:
|
||||
open_node.register_notify(*tx_sink());
|
||||
/* notify_listeners may bounce the packet back*/
|
||||
open_node.node().notify_listeners();
|
||||
/* otherwise defer acknowledgement of this packet */
|
||||
return;
|
||||
|
||||
case Packet_descriptor::READ_READY:
|
||||
succeeded = true;
|
||||
/* not supported */
|
||||
break;
|
||||
|
||||
case Packet_descriptor::SYNC:
|
||||
Fuse::sync_fs();
|
||||
succeeded = true;
|
||||
break;
|
||||
}
|
||||
|
||||
packet.length(res_length);
|
||||
packet.succeeded(succeeded);
|
||||
tx_sink()->acknowledge_packet(packet);
|
||||
}
|
||||
|
||||
void _process_packet()
|
||||
{
|
||||
Packet_descriptor packet = tx_sink()->get_packet();
|
||||
|
||||
/* assume failure by default */
|
||||
packet.succeeded(false);
|
||||
|
||||
auto process_packet_fn = [&] (Open_node &open_node) {
|
||||
_process_packet_op(packet, open_node);
|
||||
};
|
||||
|
||||
try {
|
||||
_open_node_registry.apply<Open_node>(packet.handle(), process_packet_fn);
|
||||
} catch (Id_space<File_system::Node>::Unknown_id const &) {
|
||||
Genode::error("Invalid_handle");
|
||||
tx_sink()->acknowledge_packet(packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by signal handler, executed in the context of the main
|
||||
* thread (not serialized with the RPC functions)
|
||||
*/
|
||||
void _process_packets()
|
||||
{
|
||||
while (tx_sink()->packet_avail()) {
|
||||
|
||||
/*
|
||||
* Make sure that the '_process_packet' function does not
|
||||
* block.
|
||||
*
|
||||
* If the acknowledgement queue is full, we defer packet
|
||||
* processing until the client processed pending
|
||||
* acknowledgements and thereby emitted a ready-to-ack
|
||||
* signal. Otherwise, the call of 'acknowledge_packet()'
|
||||
* in '_process_packet' would infinitely block the context
|
||||
* of the main thread. The main thread is however needed
|
||||
* for receiving any subsequent 'ready-to-ack' signals.
|
||||
*/
|
||||
if (!tx_sink()->ready_to_ack())
|
||||
return;
|
||||
|
||||
_process_packet();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if string represents a valid path (must start with '/')
|
||||
*/
|
||||
static void _assert_valid_path(char const *path)
|
||||
{
|
||||
if (!path || path[0] != '/') {
|
||||
Genode::warning("malformed path '", path, "'");
|
||||
throw Lookup_failed();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Session_component(size_t tx_buf_size,
|
||||
Genode::Env &env,
|
||||
char const *root_dir,
|
||||
bool writeable,
|
||||
Allocator &md_alloc)
|
||||
:
|
||||
Session_rpc_object(env.ram().alloc(tx_buf_size), env.rm(), env.ep().rpc_ep()),
|
||||
_env(env),
|
||||
_md_alloc(md_alloc),
|
||||
_root(*new (&_md_alloc) Directory(_md_alloc, root_dir, false)),
|
||||
_writeable(writeable),
|
||||
_process_packet_handler(_env.ep(), *this, &Session_component::_process_packets)
|
||||
{
|
||||
_tx.sigh_packet_avail(_process_packet_handler);
|
||||
_tx.sigh_ready_to_ack(_process_packet_handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Session_component()
|
||||
{
|
||||
Fuse::sync_fs();
|
||||
|
||||
Dataspace_capability ds = tx_sink()->dataspace();
|
||||
_env.ram().free(static_cap_cast<Ram_dataspace>(ds));
|
||||
destroy(&_md_alloc, &_root);
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
** File_system interface **
|
||||
***************************/
|
||||
|
||||
File_handle file(Dir_handle dir_handle, Name const &name, Mode mode, bool create)
|
||||
{
|
||||
if (!valid_filename(name.string()))
|
||||
throw Invalid_name();
|
||||
|
||||
auto file_fn = [&] (Open_node &open_node) {
|
||||
|
||||
Node &dir = open_node.node();
|
||||
|
||||
if (create && !_writeable)
|
||||
throw Permission_denied();
|
||||
|
||||
File *file = new (&_md_alloc) File(&dir, name.string(), mode, create);
|
||||
|
||||
Open_node *open_file =
|
||||
new (_md_alloc) Open_node(*file, _open_node_registry);
|
||||
|
||||
return open_file->id();
|
||||
};
|
||||
|
||||
try {
|
||||
return File_handle {
|
||||
_open_node_registry.apply<Open_node>(dir_handle, file_fn).value
|
||||
};
|
||||
} catch (Id_space<File_system::Node>::Unknown_id const &) {
|
||||
throw Invalid_handle();
|
||||
}
|
||||
}
|
||||
|
||||
Symlink_handle symlink(Dir_handle dir_handle, Name const &name, bool create)
|
||||
{
|
||||
if (! Fuse::support_symlinks()) {
|
||||
Genode::error("FUSE file system does not support symlinks");
|
||||
throw Permission_denied();
|
||||
}
|
||||
|
||||
if (!valid_filename(name.string()))
|
||||
throw Invalid_name();
|
||||
|
||||
auto symlink_fn = [&] (Open_node &open_node) {
|
||||
|
||||
Node &dir = open_node.node();
|
||||
|
||||
if (create && !_writeable)
|
||||
throw Permission_denied();
|
||||
|
||||
Symlink *symlink = new (&_md_alloc) Symlink(&dir, name.string(), create);
|
||||
|
||||
Open_node *open_symlink =
|
||||
new (_md_alloc) Open_node(*symlink, _open_node_registry);
|
||||
|
||||
return Symlink_handle { open_symlink->id().value };
|
||||
};
|
||||
|
||||
try {
|
||||
return _open_node_registry.apply<Open_node>(dir_handle, symlink_fn);
|
||||
} catch (Id_space<File_system::Node>::Unknown_id const &) {
|
||||
throw Invalid_handle();
|
||||
}
|
||||
}
|
||||
|
||||
Dir_handle dir(Path const &path, bool create)
|
||||
{
|
||||
char const *path_str = path.string();
|
||||
|
||||
_assert_valid_path(path_str);
|
||||
|
||||
if (create && !_writeable)
|
||||
throw Permission_denied();
|
||||
|
||||
if (!path.valid_string())
|
||||
throw Name_too_long();
|
||||
|
||||
Directory *dir_node = new (&_md_alloc) Directory(_md_alloc, path_str, create);
|
||||
|
||||
Open_node *open_dir =
|
||||
new (_md_alloc) Open_node(*dir_node, _open_node_registry);
|
||||
|
||||
return Dir_handle { open_dir->id().value };
|
||||
}
|
||||
|
||||
Node_handle node(Path const &path)
|
||||
{
|
||||
char const *path_str = path.string();
|
||||
|
||||
_assert_valid_path(path_str);
|
||||
|
||||
/**
|
||||
* FIXME this leads to '/' as parent and 'the rest' as name,
|
||||
* which fortunatly is in this case not a problem.
|
||||
*/
|
||||
Node *node = _root.node(path_str + 1);
|
||||
|
||||
Open_node *open_node =
|
||||
new (_md_alloc) Open_node(*node, _open_node_registry);
|
||||
|
||||
return open_node->id();
|
||||
}
|
||||
|
||||
void close(Node_handle handle)
|
||||
{
|
||||
auto close_fn = [&] (Open_node &open_node) {
|
||||
Node &node = open_node.node();
|
||||
destroy(_md_alloc, &open_node);
|
||||
destroy(_md_alloc, &node);
|
||||
};
|
||||
|
||||
try {
|
||||
_open_node_registry.apply<Open_node>(handle, close_fn);
|
||||
} catch (Id_space<File_system::Node>::Unknown_id const &) {
|
||||
throw Invalid_handle();
|
||||
}
|
||||
}
|
||||
|
||||
Status status(Node_handle node_handle)
|
||||
{
|
||||
auto status_fn = [&] (Open_node &open_node) {
|
||||
return open_node.node().status();
|
||||
};
|
||||
|
||||
try {
|
||||
return _open_node_registry.apply<Open_node>(node_handle, status_fn);
|
||||
} catch (Id_space<File_system::Node>::Unknown_id const &) {
|
||||
throw Invalid_handle();
|
||||
}
|
||||
}
|
||||
|
||||
void control(Node_handle, Control)
|
||||
{
|
||||
Genode::error(__func__, " not implemented");
|
||||
}
|
||||
|
||||
void unlink(Dir_handle dir_handle, Name const &name)
|
||||
{
|
||||
if (!_writeable)
|
||||
throw Permission_denied();
|
||||
|
||||
auto unlink_fn = [&] (Open_node &open_node) {
|
||||
|
||||
Node &dir = open_node.node();
|
||||
|
||||
Absolute_path absolute_path(_root.name());
|
||||
|
||||
try {
|
||||
absolute_path.append(dir.name());
|
||||
absolute_path.append("/");
|
||||
absolute_path.append(name.string());
|
||||
} catch (Path_base::Path_too_long) {
|
||||
throw Invalid_name();
|
||||
}
|
||||
|
||||
/* XXX remove direct use of FUSE operations */
|
||||
int res = Fuse::fuse()->op.unlink(absolute_path.base());
|
||||
|
||||
if (res != 0) {
|
||||
Genode::error("fuse()->op.unlink() returned unexpected error code: ", res);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
_open_node_registry.apply<Open_node>(dir_handle, unlink_fn);
|
||||
} catch (Id_space<File_system::Node>::Unknown_id const &) {
|
||||
throw Invalid_handle();
|
||||
}
|
||||
}
|
||||
|
||||
void truncate(File_handle file_handle, file_size_t size)
|
||||
{
|
||||
if (!_writeable)
|
||||
throw Permission_denied();
|
||||
|
||||
auto truncate_fn = [&] (Open_node &open_node) {
|
||||
open_node.node().truncate(size);
|
||||
};
|
||||
|
||||
try {
|
||||
_open_node_registry.apply<Open_node>(file_handle, truncate_fn);
|
||||
} catch (Id_space<File_system::Node>::Unknown_id const &) {
|
||||
throw Invalid_handle();
|
||||
}
|
||||
}
|
||||
|
||||
void move(Dir_handle from_dir_handle, Name const &from_name,
|
||||
Dir_handle to_dir_handle, Name const &to_name)
|
||||
{
|
||||
if (!_writeable)
|
||||
throw Permission_denied();
|
||||
|
||||
auto move_fn = [&] (Open_node &open_from_dir_node) {
|
||||
|
||||
auto inner_move_fn = [&] (Open_node &open_to_dir_node) {
|
||||
|
||||
Node &from_dir = open_from_dir_node.node();
|
||||
Node &to_dir = open_to_dir_node.node();
|
||||
|
||||
Absolute_path absolute_from_path(_root.name());
|
||||
Absolute_path absolute_to_path(_root.name());
|
||||
|
||||
try {
|
||||
absolute_from_path.append(from_dir.name());
|
||||
absolute_from_path.append("/");
|
||||
absolute_from_path.append(from_name.string());
|
||||
absolute_to_path.append(to_dir.name());
|
||||
absolute_to_path.append("/");
|
||||
absolute_to_path.append(to_name.string());
|
||||
} catch (Path_base::Path_too_long) {
|
||||
throw Invalid_name();
|
||||
}
|
||||
|
||||
/* XXX remove direct use of FUSE operations */
|
||||
int res = Fuse::fuse()->op.rename(absolute_to_path.base(),
|
||||
absolute_from_path.base());
|
||||
|
||||
if (res != 0) {
|
||||
Genode::error("fuse()->op.rename() returned unexpected error code: ", res);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
_open_node_registry.apply<Open_node>(to_dir_handle, inner_move_fn);
|
||||
} catch (Id_space<File_system::Node>::Unknown_id const &) {
|
||||
throw Invalid_handle();
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
_open_node_registry.apply<Open_node>(from_dir_handle, move_fn);
|
||||
} catch (Id_space<File_system::Node>::Unknown_id const &) {
|
||||
throw Invalid_handle();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Fuse_fs::Root : public Root_component<Session_component>
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
Genode::Attached_rom_dataspace _config { _env, "config" };
|
||||
|
||||
protected:
|
||||
|
||||
Session_component *_create_session(const char *args)
|
||||
{
|
||||
/*
|
||||
* Determine client-specific policy defined implicitly by
|
||||
* the client's label.
|
||||
*/
|
||||
|
||||
char const *root_dir = ".";
|
||||
bool writeable = false;
|
||||
|
||||
enum { ROOT_MAX_LEN = 256 };
|
||||
char root[ROOT_MAX_LEN];
|
||||
root[0] = 0;
|
||||
|
||||
Session_label const label = label_from_args(args);
|
||||
try {
|
||||
Session_policy policy(label, _config.xml());
|
||||
|
||||
/*
|
||||
* Determine directory that is used as root directory of
|
||||
* the session.
|
||||
*/
|
||||
try {
|
||||
policy.attribute("root").value(root, sizeof(root));
|
||||
|
||||
/*
|
||||
* Make sure the root path is specified with a
|
||||
* leading path delimiter. For performing the
|
||||
* lookup, we skip the first character.
|
||||
*/
|
||||
if (root[0] != '/')
|
||||
throw Lookup_failed();
|
||||
|
||||
root_dir = root;
|
||||
}
|
||||
catch (Xml_node::Nonexistent_attribute) {
|
||||
Genode::error("missing \"root\" attribute in policy definition");
|
||||
throw Service_denied();
|
||||
}
|
||||
catch (Lookup_failed) {
|
||||
Genode::error("session root directory \"",
|
||||
Genode::Cstring(root), "\" does not exist");
|
||||
throw Service_denied();
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if write access is permitted for the session.
|
||||
*/
|
||||
writeable = policy.attribute_value("writeable", false);
|
||||
if (writeable)
|
||||
Genode::warning("write support in fuse_fs is considered experimental, data-loss may occur.");
|
||||
|
||||
} catch (Session_policy::No_policy_defined) {
|
||||
Genode::error("Invalid session request, no matching policy");
|
||||
throw Genode::Service_denied();
|
||||
}
|
||||
|
||||
size_t ram_quota =
|
||||
Arg_string::find_arg(args, "ram_quota" ).ulong_value(0);
|
||||
size_t tx_buf_size =
|
||||
Arg_string::find_arg(args, "tx_buf_size").ulong_value(0);
|
||||
|
||||
if (!tx_buf_size) {
|
||||
Genode::error(label, " requested a session with a zero length transmission buffer");
|
||||
throw Genode::Service_denied();
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if donated ram quota suffices for session data,
|
||||
* and communication buffer.
|
||||
*/
|
||||
size_t session_size = sizeof(Session_component) + tx_buf_size;
|
||||
if (max((size_t)4096, session_size) > ram_quota) {
|
||||
Genode::error("insufficient 'ram_quota', got ", ram_quota, " , "
|
||||
"need ", session_size);
|
||||
throw Insufficient_ram_quota();
|
||||
}
|
||||
return new (md_alloc())
|
||||
Session_component(tx_buf_size, _env, root_dir, writeable, *md_alloc());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param env environment
|
||||
* \param md_alloc meta-data allocator
|
||||
*/
|
||||
Root(Genode::Env & env, Allocator &md_alloc)
|
||||
: Root_component<Session_component>(env.ep(), md_alloc),
|
||||
_env(env) { }
|
||||
};
|
||||
|
||||
|
||||
struct Fuse_fs::Main
|
||||
{
|
||||
Genode::Env & env;
|
||||
Sliced_heap sliced_heap { env.ram(), env.rm() };
|
||||
Root fs_root { env, sliced_heap };
|
||||
|
||||
Main(Genode::Env & env) : env(env)
|
||||
{
|
||||
if (!Fuse::init_fs()) {
|
||||
Genode::error("FUSE fs initialization failed");
|
||||
return;
|
||||
}
|
||||
|
||||
env.parent().announce(env.ep().manage(fs_root));
|
||||
}
|
||||
|
||||
~Main()
|
||||
{
|
||||
if (Fuse::initialized()) {
|
||||
Fuse::deinit_fs();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/***************
|
||||
** Component **
|
||||
***************/
|
||||
|
||||
void Libc::Component::construct(Libc::Env &env)
|
||||
{
|
||||
static Fuse_fs::Main inst(env);
|
||||
}
|
||||
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
* \brief Mode utilities
|
||||
* \author Josef Soentgen
|
||||
* \date 2013-11-26
|
||||
*/
|
||||
|
||||
#ifndef _MODE_UTIL_H_
|
||||
#define _MODE_UTIL_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <file_system_session/file_system_session.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
namespace File_system {
|
||||
int access_mode(File_system::Mode const &mode);
|
||||
}
|
||||
|
||||
|
||||
int File_system::access_mode(File_system::Mode const &mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case STAT_ONLY:
|
||||
case READ_ONLY: return O_RDONLY;
|
||||
case WRITE_ONLY: return O_WRONLY;
|
||||
case READ_WRITE: return O_RDWR;
|
||||
}
|
||||
|
||||
return O_RDONLY;
|
||||
}
|
||||
|
||||
#endif /* _MODE_UTIL_H_ */
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* \brief File-system node
|
||||
* \author Norman Feske
|
||||
* \author Christian Helmuth
|
||||
* \author Josef Soentgen
|
||||
* \date 2013-11-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 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 _NODE_H_
|
||||
#define _NODE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <file_system/node.h>
|
||||
#include <base/lock.h>
|
||||
#include <base/signal.h>
|
||||
#include <os/path.h>
|
||||
|
||||
|
||||
namespace Fuse_fs {
|
||||
|
||||
using namespace Genode;
|
||||
using namespace File_system;
|
||||
|
||||
typedef Genode::Path<MAX_PATH_LEN> Absolute_path;
|
||||
|
||||
class Node;
|
||||
}
|
||||
|
||||
class Fuse_fs::Node : public Node_base
|
||||
{
|
||||
protected:
|
||||
|
||||
unsigned long _inode;
|
||||
Absolute_path _name;
|
||||
|
||||
public:
|
||||
|
||||
Node(char const *name) : _name(name) { }
|
||||
|
||||
char const *name() const { return _name.base(); }
|
||||
|
||||
virtual size_t read(char *dst, size_t len, seek_off_t) = 0;
|
||||
virtual size_t write(char const *src, size_t len, seek_off_t) = 0;
|
||||
virtual Status status() = 0;
|
||||
|
||||
/*
|
||||
* File functionality
|
||||
*/
|
||||
virtual void truncate(file_size_t size)
|
||||
{
|
||||
Genode::error(__PRETTY_FUNCTION__, " called on a non-file node");
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _NODE_H_ */
|
@ -1,23 +0,0 @@
|
||||
NTFS_3G_DIR := $(call select_from_ports,ntfs-3g)/src/lib/ntfs-3g
|
||||
|
||||
TARGET := ntfs-3g_fuse_fs
|
||||
|
||||
SRC_C := ntfs-3g.c ntfs-3g_common.c
|
||||
SRC_CC := fuse_fs_main.cc \
|
||||
init.cc
|
||||
|
||||
LIBS := libc libfuse libntfs-3g
|
||||
|
||||
CC_OPT := -DHAVE_TIMESPEC -DHAVE_CONFIG_H -DRECORD_LOCKING_NOT_IMPLEMENTED
|
||||
|
||||
INC_DIR += $(PRG_DIR)/..
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/lib/ntfs-3g \
|
||||
$(NTFS_3G_DIR)/src \
|
||||
$(REP_DIR)/contrib/$(NTFS_3G)/src
|
||||
|
||||
vpath %.c $(NTFS_3G_DIR)/src
|
||||
vpath fuse_fs_main.cc $(PRG_DIR)/..
|
||||
vpath %.cc $(REP_DIR)/src/lib/ntfs-3g
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -1,95 +0,0 @@
|
||||
/*
|
||||
* \brief Representation of an open file system node within the component (deprecated)
|
||||
* \author Christian Prochaska
|
||||
* \date 2017-06-09
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 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 _OPEN_NODE_H_
|
||||
#define _OPEN_NODE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <file_system/listener.h>
|
||||
#include <file_system_session/file_system_session.h>
|
||||
|
||||
namespace File_system {
|
||||
/*
|
||||
* \param NODE component-specific node type
|
||||
*/
|
||||
template <typename NODE> class Open_node;
|
||||
}
|
||||
|
||||
template <typename NODE>
|
||||
class File_system::Open_node : public File_system::Node
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Id_space<File_system::Node>::Element _element;
|
||||
|
||||
NODE &_node;
|
||||
Genode::Constructible<File_system::Listener> _listener;
|
||||
|
||||
Listener::Version const _version_when_opened = _node.curr_version();
|
||||
|
||||
/*
|
||||
* Flag to track whether the underlying file-system node was
|
||||
* modified via this 'Open_node'. That is, if closing the 'Open_node'
|
||||
* should notify listeners of the file.
|
||||
*/
|
||||
bool _was_written = false;
|
||||
|
||||
public:
|
||||
|
||||
Open_node(NODE &node, Genode::Id_space<File_system::Node> &id_space)
|
||||
: _element(*this, id_space), _node(node) { }
|
||||
|
||||
~Open_node()
|
||||
{
|
||||
if (_listener.constructed()) {
|
||||
_node.remove_listener(&*_listener);
|
||||
_listener.destruct();
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify remaining listeners about the changed file
|
||||
*/
|
||||
if (_was_written)
|
||||
_node.notify_listeners();
|
||||
}
|
||||
|
||||
NODE &node() { return _node; }
|
||||
File_system::Listener &listener() { return *_listener; }
|
||||
|
||||
Genode::Id_space<File_system::Node>::Id id() { return _element.id(); }
|
||||
|
||||
/**
|
||||
* Register packet stream sink to be notified of node changes
|
||||
*/
|
||||
void register_notify(File_system::Sink &sink)
|
||||
{
|
||||
/*
|
||||
* If there was already a handler registered for the node,
|
||||
* remove the old handler.
|
||||
*/
|
||||
if (_listener.constructed()) {
|
||||
_node.remove_listener(&*_listener);
|
||||
_listener.destruct();
|
||||
}
|
||||
|
||||
/*
|
||||
* Register new handler
|
||||
*/
|
||||
_listener.construct(sink, id(), _version_when_opened);
|
||||
_node.add_listener(&*_listener);
|
||||
}
|
||||
|
||||
void mark_as_written() { _was_written = true; }
|
||||
};
|
||||
|
||||
#endif /* _OPEN_NODE_H_ */
|
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* \brief Symlink file-system node
|
||||
* \author Norman Feske
|
||||
* \author Christian Helmuth
|
||||
* \author Josef Soentgen
|
||||
* \date 2013-11-26
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 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 _SYMLINK_H_
|
||||
#define _SYMLINK_H_
|
||||
|
||||
/* local includes */
|
||||
#include <node.h>
|
||||
|
||||
|
||||
namespace Fuse_fs {
|
||||
class Symlink;
|
||||
}
|
||||
|
||||
|
||||
class Fuse_fs::Symlink : public Node
|
||||
{
|
||||
private:
|
||||
|
||||
Node *_parent;
|
||||
typedef Genode::Path<MAX_PATH_LEN> Path;
|
||||
Path _path;
|
||||
|
||||
size_t _length() const
|
||||
{
|
||||
struct stat s;
|
||||
int res = Fuse::fuse()->op.getattr(_path.base(), &s);
|
||||
if (res != 0)
|
||||
return 0;
|
||||
|
||||
return s.st_size;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Symlink(Node *parent, char const *name, bool create = false)
|
||||
:
|
||||
Node(name),
|
||||
_parent(parent),
|
||||
_path(name, parent->name())
|
||||
{ }
|
||||
|
||||
Status status() override
|
||||
{
|
||||
struct stat s;
|
||||
int res = Fuse::fuse()->op.getattr(_path.base(), &s);
|
||||
if (res != 0)
|
||||
return Status();
|
||||
|
||||
Status status;
|
||||
status.inode = s.st_ino ? s.st_ino : 1;
|
||||
status.size = s.st_size;
|
||||
status.mode = File_system::Status::MODE_FILE;
|
||||
return status;
|
||||
}
|
||||
|
||||
size_t read(char *dst, size_t len, seek_off_t seek_offset) override
|
||||
{
|
||||
int res = Fuse::fuse()->op.readlink(_path.base(), dst, len);
|
||||
if (res != 0)
|
||||
return 0;
|
||||
|
||||
return Genode::strlen(dst);
|
||||
}
|
||||
|
||||
size_t write(char const *src, size_t len, seek_off_t seek_offset) override
|
||||
{
|
||||
/* Ideal symlink operations are atomic. */
|
||||
if (seek_offset) return 0;
|
||||
|
||||
int res = Fuse::fuse()->op.symlink(src, _path.base());
|
||||
if (res != 0)
|
||||
return 0;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
file_size_t length() const { return _length(); }
|
||||
};
|
||||
|
||||
#endif /* _SYMLINK_H_ */
|
@ -1,103 +0,0 @@
|
||||
/*
|
||||
* \brief Utilities
|
||||
* \author Norman Feske
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-04-11
|
||||
*/
|
||||
|
||||
#ifndef _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/string.h>
|
||||
#include <file_system/util.h>
|
||||
|
||||
|
||||
/**
|
||||
* Return base-name portion of null-terminated path string
|
||||
*/
|
||||
static inline char const *basename(char const *path)
|
||||
{
|
||||
char const *start = path;
|
||||
|
||||
for (; *path; path++)
|
||||
if (*path == '/')
|
||||
start = path + 1;
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if null-terminated string 'substr' occurs in null-terminated
|
||||
* string 'str'
|
||||
*/
|
||||
static bool string_contains(char const *str, char const *substr)
|
||||
{
|
||||
using namespace Genode;
|
||||
using Genode::size_t;
|
||||
|
||||
size_t str_len = strlen(str);
|
||||
size_t substr_len = strlen(substr);
|
||||
|
||||
if (str_len < substr_len)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i <= (str_len - substr_len); i++)
|
||||
if (strcmp(&str[i], substr, substr_len) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if 'str' is a valid file name
|
||||
*/
|
||||
static inline bool valid_filename(char const *str)
|
||||
{
|
||||
if (!str) return false;
|
||||
|
||||
/* must have at least one character */
|
||||
if (str[0] == 0) return false;
|
||||
|
||||
/* must not contain '/' or '\' or ':' */
|
||||
if (File_system::string_contains(str, '/') ||
|
||||
File_system::string_contains(str, '\\') ||
|
||||
File_system::string_contains(str, ':'))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if 'str' is a valid path
|
||||
*/
|
||||
static inline bool valid_path(char const *str)
|
||||
{
|
||||
if (!str) return false;
|
||||
|
||||
/* must start with '/' */
|
||||
if (str[0] != '/')
|
||||
return false;
|
||||
|
||||
/* must not contain '\' or ':' */
|
||||
if (File_system::string_contains(str, '\\') ||
|
||||
File_system::string_contains(str, ':'))
|
||||
return false;
|
||||
|
||||
/* must not contain "/../" */
|
||||
if (string_contains(str, "/../")) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if 'str' is "/"
|
||||
*/
|
||||
static inline bool is_root(const char *str)
|
||||
{
|
||||
return (Genode::strcmp(str, "/") == 0);
|
||||
}
|
||||
|
||||
#endif /* _UTIL_H_ */
|
@ -1,7 +0,0 @@
|
||||
TARGET = test-libc_fuse_exfat
|
||||
LIBS = libc libc_fuse_exfat
|
||||
SRC_CC = main.cc
|
||||
|
||||
vpath %.cc $(REP_DIR)/src/test/libc_vfs
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -1,7 +0,0 @@
|
||||
TARGET = test-libc_fuse_ext2
|
||||
LIBS = libc libc_fuse_ext2
|
||||
SRC_CC = main.cc
|
||||
|
||||
vpath %.cc $(REP_DIR)/src/test/libc_vfs
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -1,7 +0,0 @@
|
||||
TARGET = test-libc_fuse_ntfs-3g
|
||||
LIBS = libc libc_fuse_ntfs-3g
|
||||
SRC_CC = main.cc
|
||||
|
||||
vpath %.cc $(REP_DIR)/src/test/libc_vfs
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
Loading…
Reference in New Issue
Block a user