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:
Julian Harnath
2017-02-27 19:58:13 +00:00
parent 94d8409150
commit 1263be8fc4
5 changed files with 39 additions and 0 deletions
+13
View File
@@ -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)