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" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_FUSE_HAIKU_EXTENSIONS
|
||||||
|
struct fs_info;
|
||||||
|
extern int gHasHaikuFuseExtensions;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ----------------------------------------------------------- *
|
/* ----------------------------------------------------------- *
|
||||||
* Basic FUSE API *
|
* Basic FUSE API *
|
||||||
* ----------------------------------------------------------- */
|
* ----------------------------------------------------------- */
|
||||||
@@ -423,6 +428,10 @@ struct fuse_operations {
|
|||||||
* Introduced in version 2.6
|
* Introduced in version 2.6
|
||||||
*/
|
*/
|
||||||
int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
|
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
|
/** 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_init(struct fuse_fs *fs, struct fuse_conn_info *conn);
|
||||||
void fuse_fs_destroy(struct fuse_fs *fs);
|
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
|
* Create a new fuse filesystem object
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -783,6 +783,15 @@ FUSEVolume::Sync()
|
|||||||
status_t
|
status_t
|
||||||
FUSEVolume::ReadFSInfo(fs_info* info)
|
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)
|
if (fFS->ops.statfs == NULL)
|
||||||
return B_UNSUPPORTED;
|
return B_UNSUPPORTED;
|
||||||
|
|
||||||
@@ -791,6 +800,7 @@ FUSEVolume::ReadFSInfo(fs_info* info)
|
|||||||
if (fuseError != 0)
|
if (fuseError != 0)
|
||||||
return fuseError;
|
return fuseError;
|
||||||
|
|
||||||
|
memset(info, 0, sizeof(*info));
|
||||||
info->flags = B_FS_IS_PERSISTENT; // assume the FS is persistent
|
info->flags = B_FS_IS_PERSISTENT; // assume the FS is persistent
|
||||||
info->block_size = st.f_bsize;
|
info->block_size = st.f_bsize;
|
||||||
info->io_size = 64 * 1024; // some value
|
info->io_size = 64 * 1024; // some value
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#define FUSE_USE_VERSION FUSE_VERSION
|
#define FUSE_USE_VERSION FUSE_VERSION
|
||||||
|
|
||||||
|
#define HAS_FUSE_HAIKU_EXTENSIONS
|
||||||
|
|
||||||
#include <fuse.h>
|
#include <fuse.h>
|
||||||
#include <fuse_lowlevel.h>
|
#include <fuse_lowlevel.h>
|
||||||
#include <fuse_opt.h>
|
#include <fuse_opt.h>
|
||||||
|
|||||||
@@ -380,3 +380,12 @@ fuse_fs_new(const struct fuse_operations* ops, size_t opSize, void* userData)
|
|||||||
|
|
||||||
return fs;
|
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"
|
#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
|
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 opSize, void* userData)
|
size_t opSize, void* userData)
|
||||||
|
|||||||
Reference in New Issue
Block a user