* Added "fuse_api.h" header wrapping the inclusion of <fuse.h>.
* Implemented the fuse_fs_*() functions. * More work on the initialization procedure for the client file system. We do now start a separate thread which calls the main() function. It won't return from fuse_main_real() until unmounting the FS. We create a fuse_fs structure and call the client FS initialization and cleanup hooks. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29613 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -118,13 +118,27 @@ FUSEFileSystem::FUSEFileSystem(const char* fsName,
|
|||||||
int (*mainFunction)(int, const char* const*))
|
int (*mainFunction)(int, const char* const*))
|
||||||
:
|
:
|
||||||
FileSystem(fsName),
|
FileSystem(fsName),
|
||||||
fMainFunction(mainFunction)
|
fMainFunction(mainFunction),
|
||||||
|
fInitThread(-1),
|
||||||
|
fInitStatus(B_NO_INIT),
|
||||||
|
fInitSemaphore(-1),
|
||||||
|
fExitSemaphore(-1),
|
||||||
|
fInitParameters(NULL),
|
||||||
|
fFS(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FUSEFileSystem::~FUSEFileSystem()
|
FUSEFileSystem::~FUSEFileSystem()
|
||||||
{
|
{
|
||||||
|
if (fInitSemaphore >= 0)
|
||||||
|
delete_sem(fInitSemaphore);
|
||||||
|
|
||||||
|
if (fExitSemaphore >= 0)
|
||||||
|
delete_sem(fExitSemaphore);
|
||||||
|
|
||||||
|
if (fInitThread >= 0)
|
||||||
|
wait_for_thread(fInitThread, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -132,6 +146,10 @@ status_t
|
|||||||
FUSEFileSystem::CreateVolume(Volume** _volume, dev_t id)
|
FUSEFileSystem::CreateVolume(Volume** _volume, dev_t id)
|
||||||
{
|
{
|
||||||
printf("FUSEFileSystem::CreateVolume()\n");
|
printf("FUSEFileSystem::CreateVolume()\n");
|
||||||
|
// Only one volume is possible
|
||||||
|
if (!fVolumes.IsEmpty())
|
||||||
|
RETURN_ERROR(B_BUSY);
|
||||||
|
|
||||||
// create the volume
|
// create the volume
|
||||||
FUSEVolume* volume = new(std::nothrow) FUSEVolume(this, id);
|
FUSEVolume* volume = new(std::nothrow) FUSEVolume(this, id);
|
||||||
if (volume == NULL)
|
if (volume == NULL)
|
||||||
@@ -152,17 +170,131 @@ FUSEFileSystem::DeleteVolume(Volume* volume)
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
FUSEFileSystem::InitClientFS(const char* parameters)
|
FUSEFileSystem::InitClientFS(const char* parameters)
|
||||||
|
{
|
||||||
|
// create the semaphores we need
|
||||||
|
fInitSemaphore = create_sem(0, "FUSE init sem");
|
||||||
|
if (fInitSemaphore < 0)
|
||||||
|
RETURN_ERROR(fInitSemaphore);
|
||||||
|
|
||||||
|
fExitSemaphore = create_sem(0, "FUSE exit sem");
|
||||||
|
if (fExitSemaphore < 0)
|
||||||
|
RETURN_ERROR(fExitSemaphore);
|
||||||
|
|
||||||
|
fInitStatus = 1;
|
||||||
|
fInitParameters = parameters;
|
||||||
|
|
||||||
|
// Start the initialization thread -- it will call main() and won't return
|
||||||
|
// until unmounting.
|
||||||
|
fInitThread = spawn_thread(&_InitializationThreadEntry,
|
||||||
|
"FUSE init", B_NORMAL_PRIORITY, this);
|
||||||
|
if (fInitThread < 0)
|
||||||
|
RETURN_ERROR(fInitThread);
|
||||||
|
|
||||||
|
resume_thread(fInitThread);
|
||||||
|
|
||||||
|
// wait for the initialization to finish
|
||||||
|
while (acquire_sem(fInitSemaphore) == B_INTERRUPTED) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fInitSemaphore = -1;
|
||||||
|
|
||||||
|
if (fInitStatus > 0)
|
||||||
|
RETURN_ERROR(B_ERROR);
|
||||||
|
if (fInitStatus != B_OK)
|
||||||
|
RETURN_ERROR(fInitStatus);
|
||||||
|
|
||||||
|
// initialization went fine
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FUSEFileSystem::ExitClientFS(status_t status)
|
||||||
|
{
|
||||||
|
// set the exit status and notify the initialization thread
|
||||||
|
fExitStatus = status;
|
||||||
|
if (fExitSemaphore >= 0)
|
||||||
|
delete_sem(fExitSemaphore);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
FUSEFileSystem::FinishInitClientFS(const fuse_operations* ops, size_t opSize,
|
||||||
|
void* userData)
|
||||||
|
{
|
||||||
|
fExitStatus = B_ERROR;
|
||||||
|
|
||||||
|
// do the initialization
|
||||||
|
status_t error = _InitClientFS(ops, opSize, userData);
|
||||||
|
|
||||||
|
// notify the mount thread
|
||||||
|
fInitStatus = error;
|
||||||
|
delete_sem(fInitSemaphore);
|
||||||
|
|
||||||
|
// loop until unmounting
|
||||||
|
while (acquire_sem(fExitSemaphore) == B_INTERRUPTED) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fExitSemaphore = -1;
|
||||||
|
|
||||||
|
if (error == B_OK)
|
||||||
|
fuse_fs_destroy(fFS);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ status_t
|
||||||
|
FUSEFileSystem::_InitializationThreadEntry(void* data)
|
||||||
|
{
|
||||||
|
return ((FUSEFileSystem*)data)->_InitializationThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
FUSEFileSystem::_InitializationThread()
|
||||||
{
|
{
|
||||||
// parse the parameters
|
// parse the parameters
|
||||||
ArgumentVector args;
|
ArgumentVector args;
|
||||||
status_t error = args.Init(GetName(), parameters);
|
status_t error = args.Init(GetName(), fInitParameters);
|
||||||
if (error != B_OK)
|
if (error != B_OK) {
|
||||||
RETURN_ERROR(error);
|
fInitStatus = error;
|
||||||
|
delete_sem(fInitSemaphore);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// call main
|
// call main -- should not return until unmounting
|
||||||
fMainFunction(args.ArgumentCount(), args.Arguments());
|
fMainFunction(args.ArgumentCount(), args.Arguments());
|
||||||
|
printf("FUSEFileSystem::_InitializationThread(): main() returned!\n");
|
||||||
|
|
||||||
// TODO: Check whether everything went fine!
|
if (fInitStatus > 0 && fInitSemaphore >= 0) {
|
||||||
|
// something went wrong early -- main() returned without calling
|
||||||
|
// fuse_main()
|
||||||
|
fInitStatus = B_ERROR;
|
||||||
|
delete_sem(fInitSemaphore);
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
FUSEFileSystem::_InitClientFS(const fuse_operations* ops, size_t opSize,
|
||||||
|
void* userData)
|
||||||
|
{
|
||||||
|
// create a fuse_fs object
|
||||||
|
fFS = fuse_fs_new(ops, opSize, userData);
|
||||||
|
if (fFS == NULL)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
// init connection info
|
||||||
|
fConnectionInfo.proto_major = 0;
|
||||||
|
fConnectionInfo.proto_minor = 0;
|
||||||
|
fConnectionInfo.async_read = false;
|
||||||
|
fConnectionInfo.max_write = 64 * 1024;
|
||||||
|
fConnectionInfo.max_readahead = 64 * 1024;
|
||||||
|
|
||||||
|
fuse_fs_init(fFS, &fConnectionInfo);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include "../FileSystem.h"
|
#include "../FileSystem.h"
|
||||||
|
|
||||||
|
#include "fuse_api.h"
|
||||||
|
|
||||||
|
|
||||||
namespace UserlandFS {
|
namespace UserlandFS {
|
||||||
|
|
||||||
@@ -17,16 +19,38 @@ public:
|
|||||||
const char* const*));
|
const char* const*));
|
||||||
virtual ~FUSEFileSystem();
|
virtual ~FUSEFileSystem();
|
||||||
|
|
||||||
|
static FUSEFileSystem* GetInstance();
|
||||||
|
|
||||||
virtual status_t CreateVolume(Volume** _volume, dev_t id);
|
virtual status_t CreateVolume(Volume** _volume, dev_t id);
|
||||||
virtual status_t DeleteVolume(Volume* volume);
|
virtual status_t DeleteVolume(Volume* volume);
|
||||||
|
|
||||||
status_t InitClientFS(const char* parameters);
|
status_t InitClientFS(const char* parameters);
|
||||||
|
void ExitClientFS(status_t status);
|
||||||
|
|
||||||
|
status_t FinishInitClientFS(const fuse_operations* ops,
|
||||||
|
size_t opSize, void* userData);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class ArgumentVector;
|
class ArgumentVector;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static status_t _InitializationThreadEntry(void* data);
|
||||||
|
status_t _InitializationThread();
|
||||||
|
|
||||||
|
status_t _InitClientFS(const fuse_operations* ops,
|
||||||
|
size_t opSize, void* userData);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int (*fMainFunction)(int, const char* const*);
|
int (*fMainFunction)(int, const char* const*);
|
||||||
|
thread_id fInitThread;
|
||||||
|
status_t fInitStatus;
|
||||||
|
status_t fExitStatus;
|
||||||
|
sem_id fInitSemaphore;
|
||||||
|
sem_id fExitSemaphore;
|
||||||
|
fuse_operations fOps;
|
||||||
|
const char* fInitParameters;
|
||||||
|
fuse_fs* fFS;
|
||||||
|
fuse_conn_info fConnectionInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace UserlandFS
|
} // namespace UserlandFS
|
||||||
@@ -34,4 +58,11 @@ private:
|
|||||||
using UserlandFS::FUSEFileSystem;
|
using UserlandFS::FUSEFileSystem;
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ inline FUSEFileSystem*
|
||||||
|
FUSEFileSystem::GetInstance()
|
||||||
|
{
|
||||||
|
return static_cast<FUSEFileSystem*>(sInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // USERLAND_FS_FUSE_FILE_SYSTEM_H
|
#endif // USERLAND_FS_FUSE_FILE_SYSTEM_H
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ printf("FUSEVolume::Mount()\n");
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
|
_FileSystem()->ExitClientFS(B_UNSUPPORTED);
|
||||||
|
|
||||||
return B_UNSUPPORTED;
|
return B_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ DEFINES += _FILE_OFFSET_BITS=64 ;
|
|||||||
# the library providing the FUSE interface for add-ons
|
# the library providing the FUSE interface for add-ons
|
||||||
SharedLibrary libuserlandfs_fuse.so
|
SharedLibrary libuserlandfs_fuse.so
|
||||||
:
|
:
|
||||||
|
fuse_fs.cpp
|
||||||
fuse_main.cpp
|
fuse_main.cpp
|
||||||
FUSEFileSystem.cpp
|
FUSEFileSystem.cpp
|
||||||
FUSEVolume.cpp
|
FUSEVolume.cpp
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef USERLAND_FS_FUSE_FUSE_API_H
|
||||||
|
#define USERLAND_FS_FUSE_FUSE_API_H
|
||||||
|
|
||||||
|
#define FUSE_USE_VERSION FUSE_VERSION
|
||||||
|
|
||||||
|
#include <fuse.h>
|
||||||
|
|
||||||
|
#endif // USERLAND_FS_FUSE_FUSE_API_H
|
||||||
@@ -0,0 +1,373 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "fuse_fs.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include "Debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_getattr(struct fuse_fs* fs, const char* path, struct stat* buf)
|
||||||
|
{
|
||||||
|
if (fs->ops.getattr == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.getattr(path, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_fgetattr(struct fuse_fs* fs, const char* path, struct stat* buf,
|
||||||
|
struct fuse_file_info* fi)
|
||||||
|
{
|
||||||
|
if (fs->ops.fgetattr == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.fgetattr(path, buf, fi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_rename(struct fuse_fs* fs, const char* oldpath, const char* newpath)
|
||||||
|
{
|
||||||
|
if (fs->ops.rename == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.rename(oldpath, newpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_unlink(struct fuse_fs* fs, const char* path)
|
||||||
|
{
|
||||||
|
if (fs->ops.unlink == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.unlink(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_rmdir(struct fuse_fs* fs, const char* path)
|
||||||
|
{
|
||||||
|
if (fs->ops.rmdir == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.rmdir(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_symlink(struct fuse_fs* fs, const char* linkname, const char* path)
|
||||||
|
{
|
||||||
|
if (fs->ops.symlink == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.symlink(linkname, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_link(struct fuse_fs* fs, const char* oldpath, const char* newpath)
|
||||||
|
{
|
||||||
|
if (fs->ops.link == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.link(oldpath, newpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_release(struct fuse_fs* fs, const char* path,
|
||||||
|
struct fuse_file_info* fi)
|
||||||
|
{
|
||||||
|
if (fs->ops.release == NULL)
|
||||||
|
return 0;
|
||||||
|
return fs->ops.release(path, fi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_open(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi)
|
||||||
|
{
|
||||||
|
if (fs->ops.open == NULL)
|
||||||
|
return 0;
|
||||||
|
return fs->ops.open(path, fi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_read(struct fuse_fs* fs, const char* path, char *buf, size_t size,
|
||||||
|
off_t off, struct fuse_file_info* fi)
|
||||||
|
{
|
||||||
|
if (fs->ops.read == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.read(path, buf, size, off, fi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_write(struct fuse_fs* fs, const char* path, const char* buf,
|
||||||
|
size_t size, off_t off, struct fuse_file_info* fi)
|
||||||
|
{
|
||||||
|
if (fs->ops.write == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.write(path, buf, size, off, fi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_fsync(struct fuse_fs* fs, const char* path, int datasync,
|
||||||
|
struct fuse_file_info* fi)
|
||||||
|
{
|
||||||
|
if (fs->ops.fsync == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.fsync(path, datasync, fi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_flush(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi)
|
||||||
|
{
|
||||||
|
if (fs->ops.flush == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.flush(path, fi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_statfs(struct fuse_fs* fs, const char* path, struct statvfs* buf)
|
||||||
|
{
|
||||||
|
if (fs->ops.statfs == NULL)
|
||||||
|
return 0;
|
||||||
|
return fs->ops.statfs(path, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_opendir(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi)
|
||||||
|
{
|
||||||
|
if (fs->ops.opendir == NULL)
|
||||||
|
return 0;
|
||||||
|
return fs->ops.opendir(path, fi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_readdir(struct fuse_fs* fs, const char* path, void* buf,
|
||||||
|
fuse_fill_dir_t filler, off_t off, struct fuse_file_info* fi)
|
||||||
|
{
|
||||||
|
if (fs->ops.readdir == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.readdir(path, buf, filler, off, fi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_fsyncdir(struct fuse_fs* fs, const char* path, int datasync,
|
||||||
|
struct fuse_file_info* fi)
|
||||||
|
{
|
||||||
|
if (fs->ops.fsyncdir == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.fsyncdir(path, datasync, fi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_releasedir(struct fuse_fs* fs, const char* path,
|
||||||
|
struct fuse_file_info* fi)
|
||||||
|
{
|
||||||
|
if (fs->ops.releasedir == NULL)
|
||||||
|
return 0;
|
||||||
|
return fs->ops.releasedir(path, fi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_create(struct fuse_fs* fs, const char* path, mode_t mode,
|
||||||
|
struct fuse_file_info* fi)
|
||||||
|
{
|
||||||
|
if (fs->ops.create == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.create(path, mode, fi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_lock(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi,
|
||||||
|
int cmd, struct flock* lock)
|
||||||
|
{
|
||||||
|
if (fs->ops.lock == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.lock(path, fi, cmd, lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_chmod(struct fuse_fs* fs, const char* path, mode_t mode)
|
||||||
|
{
|
||||||
|
if (fs->ops.chmod == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.chmod(path, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_chown(struct fuse_fs* fs, const char* path, uid_t uid, gid_t gid)
|
||||||
|
{
|
||||||
|
if (fs->ops.chown == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.chown(path, uid, gid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_truncate(struct fuse_fs* fs, const char* path, off_t size)
|
||||||
|
{
|
||||||
|
if (fs->ops.truncate == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.truncate(path, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_ftruncate(struct fuse_fs* fs, const char* path, off_t size,
|
||||||
|
struct fuse_file_info* fi)
|
||||||
|
{
|
||||||
|
if (fs->ops.ftruncate == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.ftruncate(path, size, fi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_utimens(struct fuse_fs* fs, const char* path,
|
||||||
|
const struct timespec tv[2])
|
||||||
|
{
|
||||||
|
if (fs->ops.utimens == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.utimens(path, tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_access(struct fuse_fs* fs, const char* path, int mask)
|
||||||
|
{
|
||||||
|
if (fs->ops.access == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.access(path, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_readlink(struct fuse_fs* fs, const char* path, char* buf, size_t len)
|
||||||
|
{
|
||||||
|
if (fs->ops.readlink == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.readlink(path, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_mknod(struct fuse_fs* fs, const char* path, mode_t mode, dev_t rdev)
|
||||||
|
{
|
||||||
|
if (fs->ops.mknod == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.mknod(path, mode, rdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_mkdir(struct fuse_fs* fs, const char* path, mode_t mode)
|
||||||
|
{
|
||||||
|
if (fs->ops.mkdir == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.mkdir(path, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_setxattr(struct fuse_fs* fs, const char* path, const char* name,
|
||||||
|
const char* value, size_t size, int flags)
|
||||||
|
{
|
||||||
|
if (fs->ops.setxattr == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.setxattr(path, name, value, size, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_getxattr(struct fuse_fs* fs, const char* path, const char* name,
|
||||||
|
char* value, size_t size)
|
||||||
|
{
|
||||||
|
if (fs->ops.getxattr == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.getxattr(path, name, value, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_listxattr(struct fuse_fs* fs, const char* path, char* list, size_t size)
|
||||||
|
{
|
||||||
|
if (fs->ops.listxattr == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.listxattr(path, list, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_removexattr(struct fuse_fs* fs, const char* path, const char* name)
|
||||||
|
{
|
||||||
|
if (fs->ops.removexattr == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.removexattr(path, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
fuse_fs_bmap(struct fuse_fs* fs, const char* path, size_t blocksize,
|
||||||
|
uint64_t* idx)
|
||||||
|
{
|
||||||
|
if (fs->ops.bmap == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
return fs->ops.bmap(path, blocksize, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
fuse_fs_init(struct fuse_fs* fs, struct fuse_conn_info* conn)
|
||||||
|
{
|
||||||
|
if (fs->ops.init == NULL)
|
||||||
|
return;
|
||||||
|
fs->ops.init(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
fuse_fs_destroy(struct fuse_fs* fs)
|
||||||
|
{
|
||||||
|
if (fs->ops.destroy != NULL)
|
||||||
|
fs->ops.destroy(fs->userData);
|
||||||
|
|
||||||
|
delete fs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct fuse_fs*
|
||||||
|
fuse_fs_new(const struct fuse_operations* ops, size_t opSize, void* userData)
|
||||||
|
{
|
||||||
|
if (sizeof(fuse_operations) < opSize) {
|
||||||
|
ERROR(("fuse_fs_new(): Client FS built with newer library version!\n"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fuse_fs* fs = new(std::nothrow) fuse_fs;
|
||||||
|
if (fs == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memset(&fs->ops, 0, sizeof(fuse_operations));
|
||||||
|
memcpy(&fs->ops, ops, opSize);
|
||||||
|
|
||||||
|
fs->userData = userData;
|
||||||
|
|
||||||
|
return fs;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef USERLAND_FS_FUSE_FUSE_FS_H
|
||||||
|
#define USERLAND_FS_FUSE_FUSE_FS_H
|
||||||
|
|
||||||
|
#include "fuse_api.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct fuse_fs {
|
||||||
|
void* userData;
|
||||||
|
fuse_operations ops;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // USERLAND_FS_FUSE_FUSE_FS_H
|
||||||
@@ -7,22 +7,27 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <fuse.h>
|
#include "fuse_api.h"
|
||||||
|
#include "FUSEFileSystem.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
fuse_main_real(int argc, char* argv[], const struct fuse_operations* op,
|
fuse_main_real(int argc, char* argv[], const struct fuse_operations* op,
|
||||||
size_t op_size, void *user_data)
|
size_t opSize, void* userData)
|
||||||
{
|
{
|
||||||
printf("fuse_main_real(%d, %p, %p, %ld, %p)\n", argc, argv, op, op_size,
|
printf("fuse_main_real(%d, %p, %p, %ld, %p)\n", argc, argv, op, opSize,
|
||||||
user_data);
|
userData);
|
||||||
// TODO: Implement!
|
|
||||||
return 0;
|
// run the main loop
|
||||||
|
status_t error = FUSEFileSystem::GetInstance()->FinishInitClientFS(op,
|
||||||
|
opSize, userData);
|
||||||
|
|
||||||
|
return error == B_OK ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
fuse_is_lib_option(const char *opt)
|
fuse_is_lib_option(const char* opt)
|
||||||
{
|
{
|
||||||
printf("fuse_is_lib_option(\"%s\")\n", opt);
|
printf("fuse_is_lib_option(\"%s\")\n", opt);
|
||||||
// TODO: Implement!
|
// TODO: Implement!
|
||||||
|
|||||||
Reference in New Issue
Block a user