FUSE compat: add Haiku extension
* Add a way for a FUSE module to supply Haiku-specific extensions.
This allows it to integrate better with Haiku while only requiring
minimal changes on the FUSE module itself.
* For now, there is only one extension: another function pointer for
"get_fs_info", which lets the FUSE module fill in an fs_info struct.
FUSE provides no good way to otherwise communicate extra information,
such as the volume flags (e.g. B_FS_IS_SHARED).
* A FUSE module can signal that it supports the Haiku extensions by
a) defining HAS_HAIKU_FUSE_EXTENSIONS before including the fuse
headers
b) setting the global variable gHasHaikuFuseExtensions to 1 in
its initialization
Otherwise, the Haiku extensions are completely invisible to the
FUSE module.
This commit is contained in:
@@ -36,6 +36,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FUSE_HAIKU_EXTENSIONS
|
||||
struct fs_info;
|
||||
extern int gHasHaikuFuseExtensions;
|
||||
#endif
|
||||
|
||||
/* ----------------------------------------------------------- *
|
||||
* Basic FUSE API *
|
||||
* ----------------------------------------------------------- */
|
||||
@@ -423,6 +428,10 @@ struct fuse_operations {
|
||||
* Introduced in version 2.6
|
||||
*/
|
||||
int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
|
||||
|
||||
#ifdef HAS_FUSE_HAIKU_EXTENSIONS
|
||||
int (*get_fs_info) (struct fs_info*);
|
||||
#endif
|
||||
};
|
||||
|
||||
/** Extra context that may be needed by some filesystems
|
||||
@@ -658,6 +667,10 @@ int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize,
|
||||
void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn);
|
||||
void fuse_fs_destroy(struct fuse_fs *fs);
|
||||
|
||||
#ifdef HAS_FUSE_HAIKU_EXTENSIONS
|
||||
int fuse_fs_get_fs_info(struct fuse_fs* fs, struct fs_info* info);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Create a new fuse filesystem object
|
||||
*
|
||||
|
||||
@@ -783,6 +783,15 @@ FUSEVolume::Sync()
|
||||
status_t
|
||||
FUSEVolume::ReadFSInfo(fs_info* info)
|
||||
{
|
||||
if (gHasHaikuFuseExtensions == 1 && fFS->ops.get_fs_info != NULL) {
|
||||
int fuseError = fuse_fs_get_fs_info(fFS, info);
|
||||
if (fuseError != 0)
|
||||
return fuseError;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// No Haiku FUSE extensions, so our knowledge is limited: use some values
|
||||
// from statfs and make reasonable guesses for the rest of them.
|
||||
if (fFS->ops.statfs == NULL)
|
||||
return B_UNSUPPORTED;
|
||||
|
||||
@@ -791,6 +800,7 @@ FUSEVolume::ReadFSInfo(fs_info* info)
|
||||
if (fuseError != 0)
|
||||
return fuseError;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->flags = B_FS_IS_PERSISTENT; // assume the FS is persistent
|
||||
info->block_size = st.f_bsize;
|
||||
info->io_size = 64 * 1024; // some value
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#define FUSE_USE_VERSION FUSE_VERSION
|
||||
|
||||
#define HAS_FUSE_HAIKU_EXTENSIONS
|
||||
|
||||
#include <fuse.h>
|
||||
#include <fuse_lowlevel.h>
|
||||
#include <fuse_opt.h>
|
||||
|
||||
@@ -380,3 +380,12 @@ fuse_fs_new(const struct fuse_operations* ops, size_t opSize, void* userData)
|
||||
|
||||
return fs;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fuse_fs_get_fs_info(struct fuse_fs* fs, struct fs_info* info)
|
||||
{
|
||||
if (fs->ops.get_fs_info == NULL)
|
||||
return ENOSYS;
|
||||
return fs->ops.get_fs_info(info);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
#include "../RequestThread.h"
|
||||
|
||||
|
||||
int gHasHaikuFuseExtensions = 0;
|
||||
// This global can be set to 1 by a Haiku-aware FUSE add-on to signal
|
||||
// that it implements the Haiku-specific functions in struct
|
||||
// fuse_operations (those which are guarded by HAS_FUSE_HAIKU_EXTENSIONS).
|
||||
|
||||
int
|
||||
fuse_main_real(int argc, char* argv[], const struct fuse_operations* op,
|
||||
size_t opSize, void* userData)
|
||||
|
||||
Reference in New Issue
Block a user