| Current File : //usr/include/libuvfs.h |
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
*/
/*
*
* libuvfs - user-level file systems
*
* Linking with libuvfs allows implementation of file systems in user (not
* kernel) space. There is also libfuse, which supports the fuse API.
* libuvfs is more Solaris-specific.
*
* To use, start with an executable linked with libuvfs. Then mount it:
*
* # mount -F uvfs /path/to/executable /path/to/mount/point
*
* The executable must take the following steps:
*
* Use libuvfs_create_fs() to create a libuvfs_fs_t
*
* Use libuvfs_register_callbacks() to register a set of callbacks
*
* Call libuvfs_daemon_ready()
*
* CALLBACKS
*
* The bulk of the work is done in callbacks. A callback is called for
* every operation, e.g., open, write, read, .... Callbacks receive an
* argument structure, and return a result structure. The structures are
* specific for each operation.
*
* The signature for each callback is:
*
* callback(libuvfs_fs_t *fs, void *arg, size_t arglen)
*
* fs: a pointer to the fs structure that was created when
* libuvfs_create_fs() was called. It can hold user-defined data in its
* fs_data field.
*
* arg: a pointer to the operation-specific structure relevant for the
* given operation.
*
* argsize: the size of the arg. Usually sizeof (specific_type), but
* can be more if arbitrarily-sized data is following, e.g., the write
* operation can contain a variable number of bytes.
*
*/
#ifndef _LIBUVFS_H
#define _LIBUVFS_H
#include <sys/libuvfs_ki.h>
#include <sys/int_limits.h>
#include <thread.h>
#include <synch.h>
#include <umem.h>
#include <libscf.h>
#include <sys/avl.h>
#include <ucred.h>
#ifdef __cplusplus
extern "C" {
#endif
#define LIBUVFS_STACK_OVERHEAD (2 * 1024 * 1024)
#define LIBUVFS_FSID_SVC (0)
#define LIBUVFS_FSID_NONE (1)
/*
* libuvfs types
*/
struct libuvfs_fs;
typedef void (*libuvfs_callback_t)(struct libuvfs_fs *, void *, size_t,
ucred_t *cr);
typedef struct {
libuvfs_optag_t lcr_optag; /* which operation */
libuvfs_callback_t lcr_callback; /* the callback */
} libuvfs_callback_reg_t;
typedef struct libuvfs_fs {
uint64_t fs_fid_random; /* randomly generated at create time */
uint64_t fs_fid_seq;
mutex_t fs_lock;
uint32_t fs_flags;
uint64_t fs_fsid;
int fs_dev;
int fs_door;
libuvfs_callback_reg_t fs_callback[UVFS_CB_NUM_OPS];
cond_t fs_daemon_cv;
pthread_attr_t fs_pthread_attr;
uint32_t fs_io_maxread;
uint32_t fs_io_maxwrite;
uint32_t fs_max_dthreads;
uint32_t fs_cur_dthreads;
/* data stash */
mutex_t fs_stash_lock;
avl_tree_t fs_stash;
/* namespace */
rwlock_t fs_name_user_lock;
mutex_t fs_name_lock;
avl_tree_t fs_name_info_tree;
/* SMF/libscf interaction */
scf_handle_t *fs_scf_handle;
scf_error_t fs_scf_error;
scf_simple_app_props_t *fs_scf_props;
int fs_daemon_fmri_size;
char *fs_daemon_fmri;
} libuvfs_fs_t;
/* for fs_flags above */
#define LIBUVFS_FS_FLAG_DOOR_VALID 0x01
#define LIBUVFS_VERSION 1
typedef int libuvfs_version_t;
#define LIBUVFS_SERVER_FMRI "svc:/system/filesystem/uvfs-server"
/* minimum daemon mount timeout value */
#define LIBUVFS_DAEMON_TIMEOUT 30
/*
* libuvfs functions
*/
/* basics */
libuvfs_fs_t *libuvfs_create_fs(libuvfs_version_t, uint64_t);
void libuvfs_destroy_fs(libuvfs_fs_t *);
int libuvfs_set_fsparam(libuvfs_fs_t *);
/* callbacks and event loops */
int libuvfs_register_callback(libuvfs_fs_t *, const libuvfs_callback_reg_t *);
int libuvfs_register_callbacks(libuvfs_fs_t *, const libuvfs_callback_reg_t *);
void libuvfs_return(void *, size_t);
int libuvfs_daemon_launch(libuvfs_fs_t *, const char *, const char *,
const char *, uint64_t, const char *, const char *, uint64_t);
int libuvfs_is_daemon(void);
int libuvfs_daemon_ready(libuvfs_fs_t *);
void libuvfs_daemon_abort(libuvfs_fs_t *);
void libuvfs_daemon_exit(libuvfs_fs_t *);
/* smf helpers */
const char *libuvfs_scf_error(const libuvfs_fs_t *, scf_error_t *);
char *libuvfs_get_special(libuvfs_fs_t *);
char *libuvfs_get_daemon_executable(libuvfs_fs_t *);
char *libuvfs_get_daemon_options(libuvfs_fs_t *);
uint64_t libuvfs_get_daemon_timeout(libuvfs_fs_t *);
int libuvfs_set_daemon_options(libuvfs_fs_t *, char *);
int libuvfs_remove_disabled_instances(libuvfs_fs_t *);
void libuvfs_daemon_atexit(void);
/* callback helpers */
void libuvfs_fid_unique(libuvfs_fs_t *, libuvfs_fid_t *);
uint64_t libuvfs_fid_to_id(libuvfs_fs_t *, const libuvfs_fid_t *);
size_t libuvfs_add_direntry(void *buf, size_t buflen, const char *,
ino64_t, off64_t off, void **);
char *libuvfs_strdup(const char *);
void libuvfs_strfree(char *);
int libuvfs_fid_compare(const libuvfs_fid_t *, const libuvfs_fid_t *);
/* data stash */
void *libuvfs_stash_fid_get(libuvfs_fs_t *, libuvfs_fid_t *, uint32_t, int *);
void *libuvfs_stash_fs_get(libuvfs_fs_t *, uint32_t, int *);
void *libuvfs_stash_fid_store(libuvfs_fs_t *, libuvfs_fid_t *, uint32_t, int,
void *);
void *libuvfs_stash_fid_remove(libuvfs_fs_t *, libuvfs_fid_t *, uint32_t);
void *libuvfs_stash_fs_store(libuvfs_fs_t *, uint32_t, int, void *);
void *libuvfs_stash_fs_remove(libuvfs_fs_t *, uint32_t);
/* namespace helpers */
void libuvfs_name_fs_rdlock(libuvfs_fs_t *);
void libuvfs_name_fs_wrlock(libuvfs_fs_t *);
void libuvfs_name_fs_unlock(libuvfs_fs_t *);
int libuvfs_name_fid_rdlock(libuvfs_fs_t *, const libuvfs_fid_t *);
int libuvfs_name_fid_wrlock(libuvfs_fs_t *, const libuvfs_fid_t *);
int libuvfs_name_fid_unlock(libuvfs_fs_t *, const libuvfs_fid_t *);
void libuvfs_name_root_create(libuvfs_fs_t *, const libuvfs_fid_t *);
void libuvfs_name_store(libuvfs_fs_t *, const libuvfs_fid_t *, const char *,
const libuvfs_fid_t *, int, libuvfs_fid_t *);
void libuvfs_name_delete(libuvfs_fs_t *, const libuvfs_fid_t *, const char *,
libuvfs_fid_t *);
void libuvfs_name_lookup(libuvfs_fs_t *, const libuvfs_fid_t *, const char *,
libuvfs_fid_t *);
int libuvfs_name_parent(libuvfs_fs_t *, const libuvfs_fid_t *, int,
libuvfs_fid_t *);
uint32_t libuvfs_name_dirent(libuvfs_fs_t *, const libuvfs_fid_t *, int,
libuvfs_fid_t *, char *, uint32_t);
uint32_t libuvfs_name_dirent_next(libuvfs_fs_t *, const libuvfs_fid_t *,
libuvfs_fid_t *, char *, uint32_t);
int libuvfs_name_dirents(libuvfs_fs_t *, const libuvfs_fid_t *,
void *, uint32_t, void **, uint64_t *, uint64_t *);
uint32_t libuvfs_name_count(libuvfs_fs_t *, const libuvfs_fid_t *);
uint32_t libuvfs_name_path(libuvfs_fs_t *, const libuvfs_fid_t *, uint32_t,
const char *, char *, uint32_t);
/* fsid helpers */
void libuvfs_fsid_to_str(const uint64_t, char *, int);
uint64_t libuvfs_str_to_fsid(const char *);
uint64_t libuvfs_get_fsid(const char *);
/* device helpers */
uint64_t libuvfs_expldev(dev_t);
dev_t libuvfs_cmpldev(uint64_t);
/* functions for the mount command */
int libuvfs_daemon_start_wait(libuvfs_fs_t *, uint64_t);
int libuvfs_daemon_register(libuvfs_fs_t *);
#ifdef __cplusplus
}
#endif
#endif /* _LIBUVFS_H */