/*
* Fuse: Filesystem in Userspace
*
*
* This program can be distributed under the terms of the GNU LGPLv2.
* See the file COPYING.LIB
*/
#include "fuse.h"
#include "fuse_opt.h"
#include <libuvfs.h>
#include "fuse_impl.h"
#include <libintl.h>
#include <strings.h>
#include <thread.h>
#include <limits.h>
#include <synch.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <umem.h>
#include <alloca.h>
#include <stddef.h>
#include <atomic.h>
#include <sys/sysmacros.h>
#include <stdio.h>
#include <ucred.h>
#include <errno.h>
#include <dirent.h>
#include <pthread.h>
enum fuse_fs_stash_t {
};
enum fuse_fid_stash_t {
};
typedef struct {
char *hidden_component;
typedef struct {
void *dh_data;
void *dh_cookie;
/* The total length of the buffer. */
int dh_len;
/* The amount of valid dirent data (out of dh_len) used. */
int dh_bytes_used;
/* The size of the user's buffer. */
int dh_response_size;
/* The amount of dirent data that fits in the user's buffer. */
int dh_return_bytes;
} dir_handle_t;
static struct fuse_context *
fuse_uvfs_get_context(void)
{
}
return (ctx);
}
static void
{
}
struct fuse_context *
fuse_get_context(void)
{
return (fuse_uvfs_get_context());
}
static struct fuse_file_info *
{
return (ffi);
}
static void
{
}
static struct fuse_file_info *
{
int len;
/*
* serialize access to this fid
*/
return (NULL);
/*
* see if we are already open
*/
goto out;
/*
* need to open and create new file handle
*/
goto out;
goto out;
if (isdir) {
goto out;
} else {
goto out;
}
/*
* We should never have a case where there was an existing ffi.
* If we run into it in the non-debug case, we clean up the
* mistake.
*/
if (isdir) {
} else {
}
}
out:
return (rc);
}
static void
{
}
static int
{
/* Caller can request we not set any fid data */
return (0);
if (known_pfid != NULL) {
return (0);
}
return (ESTALE);
/* This dir is the root? */
return (0);
return (ESTALE);
}
return (0);
}
static void
{
}
static struct fuse_fs *
{
fuse_fs);
}
return (info);
}
/*ARGSUSED*/
static void
{
int error = 0;
goto out;
}
rootfid);
out:
}
static void
{
int error = 0;
int len;
if (len == 0) {
goto out;
}
goto out;
}
out:
}
/*ARGSUSED*/
static void
{
int error = 0;
}
}
static void
{
return;
if (hidden) {
else
if (error == 0) {
}
}
}
static int
{
int error;
int len;
/*
* No work to do if count is not zero.
*/
if (count != 0)
return (0);
/*
* Serialize open with close
*/
return (ESTALE);
goto out;
}
goto out;
}
/*
* Get the current file info. If we can't get it, there's nothing
* to do. When we get it, free the slot where it was.
*/
error = 0;
goto out;
}
NULL);
}
} else {
}
out:
return (error);
}
static void
{
int error = 0;
}
static void
{
int len;
int error = 0;
if (len == 0) {
goto out;
}
goto out;
}
/*
* Now add it to name store if it isn't already known
*/
NULL);
}
out:
}
static void
{
}
static void
{
}
static void
{
int error;
}
static int
{
int bytes;
if (!statp) {
if (path[0])
else
} else {
}
void *old_data;
int cookie_off;
return (1);
}
if (bytes == 0)
return (1);
}
}
return (bytes ? 0 : 1);
}
static void
{
dirhp->dh_bytes_used = 0;
}
/*ARGSUSED*/
static void
{
int len;
int error = 0;
goto errout;
}
if (off)
goto out;
}
}
if (off == 0) {
goto out;
}
goto out;
/*
* No errors, set dh_filled to 1 to indicate that we have
* the data.
*/
} else {
void *start;
int bytes = 0;
/*
* There is a similar check below, but we must also do the
* check here so we don't bother with the for loop.
* If the offset requested is equal to or greater than
* the amount of dirent data that we have in the dirhp
* buffer, return eof.
*/
resp->lcrdr_length = 0;
goto out;
}
/*
* Determine how much dirent data will fit into the user's
* buffer.
*/
for (;;) {
break;
}
break;
}
dirhp->dh_bytes_used) {
break;
}
}
/* This is how much will fit into the user's buffer. */
}
/*
* Copy the data from the dirhp buffer into the user's buffer.
*/
int copy_amount;
else
else
} else {
resp->lcrdr_length = 0;
}
out:
}
static void
{
int len;
int error = 0;
goto out;
}
/*
* Add mount option to cache attributes?
*/
}
out:
}
static void
{
int error = 0;
int len;
goto out;
}
goto out;
out:
}
static void
{
int error = 0;
goto out;
}
goto out;
}
out:
}
static void
{
int error = 0;
int len;
goto out;
}
goto out;
}
goto out;
out:
}
static int
{
char *newname;
int i;
int error;
int f;
if (f == -1)
return (1);
return (ENOMEM);
for (i = 0; i != 10; ) {
int error;
continue;
break;
i++;
path[0] = '\0';
}
(void) close(f);
if (path[0] == '\0')
return (EBUSY);
if (error == 0) {
if (hidden) {
} else {
return (ENOMEM);
}
}
}
return (error);
}
static void
{
int len;
int error = 0;
goto errout;
}
goto out;
}
goto out;
}
/*
* if busy then rename entry
*/
} else {
if (error == 0) {
}
}
out:
}
static void
{
int len;
int error = 0;
goto errout;
}
goto out;
}
goto out;
}
/*
* Check to see if file is busy. If so then rename it
*/
} else {
goto out;
}
}
out:
}
static void
{
int error = 0;
int len;
goto errout;
}
/*
*/
goto out;
}
goto out;
}
/* Now get path to target directory */
goto out;
}
/*
* Does target exist?
*/
/*
* If file is busy then hide it
*/
goto out;
}
}
goto out;
out:
}
static void
{
int len;
int error = 0;
goto out;
}
goto out;
}
goto out;
}
goto out;
}
goto out;
}
goto out;
}
}
if (error)
goto out;
}
goto out;
}
out:
}
static void
{
int len;
int bytes;
int error = 0;
/* only for error returns */
goto out;
}
goto out;
}
/*
* bytes assigned by the FUSE_OP_READ macro, negative val indicates err
*/
if (bytes < 0) {
goto out;
}
goto out;
}
out:
}
/*ARGSUSED*/
static void
{
int len;
int bytes;
int error = 0;
goto out;
}
goto out;
}
/*
* bytes assigned by the FUSE_OP_WRITE macro, negative val indicates err
*/
if (bytes < 0) {
goto out;
}
goto out;
}
out:
}
static void
{
int len;
int error = 0;
goto out;
}
goto out;
}
goto out;
}
goto out;
}
out:
}
static void
{
int len;
int error = 0;
goto out;
}
goto out;
}
goto out;
}
goto out;
}
out:
}
static void
{
int len;
int error = 0;
goto out;
}
/*
* Only truncation is supported by fuse
*/
out:
}
static void
{
int len;
int error = 0;
goto out;
}
goto out;
}
goto out;
}
else
out:
}
};
typedef void *fuse_conn_info;
static void
{
}
void
{
}
void
{
}
void
{
f->fuse_exited = 1;
}
/*ARGSUSED*/
struct fuse *
{
return (NULL);
(void) pthread_mutex_lock(&tsd_mtx);
if (tsd_ref == 0) {
fuse_uvfs_tsd_free) != 0) {
(void) pthread_mutex_unlock(&tsd_mtx);
return (NULL);
}
}
tsd_ref++;
(void) pthread_mutex_unlock(&tsd_mtx);
if (sizeof (struct fuse_operations) < op_size) {
gettext("fuse: warning: library too old, "));
gettext("some operations may not not work\n"));
op_size = sizeof (struct fuse_operations);
}
if (!fs) {
gettext("fuse: failed to allocate fuse_fs\n"));
return (NULL);
}
if (op)
/*
* Set up context in case client needs to call
* fuse_get_context() during init function.
* Most likely use is probably for calling fuse_exit()
*/
ctx = fuse_get_context();
if (fuse->fuse_exited) {
return (NULL);
}
/*
* Store fuse_fs and other stuff
* in fs stash and setup root dir.
*/
return (NULL);
}
return (fuse);
}
/*ARGSUSED*/
int
{
int error;
char *mountpoint;
int multithreaded;
int foreground;
if (is_smf) {
mountpoint = "";
return (1);
} else {
&multithreaded, &foreground))
return (error);
return (1);
}
if (!is_smf)
return (1);
}
/*
* Call fuse_loop() to start processing upcalls.
*/
if (!is_smf)
return (error);
}
void
{
fuse_fs_destroy(f->fuse_fs);
(void) pthread_mutex_lock(&tsd_mtx);
tsd_ref--;
if (tsd_ref == 0) {
sizeof (struct fuse_context));
(void) pthread_key_delete(fuse_uvfs_tsd_key);
}
(void) pthread_mutex_unlock(&tsd_mtx);
}
int
{
if (f == NULL || f->fuse_exited)
return (-1);
return (libuvfs_daemon_ready(f->fuse_uvfs_fs));
}
int
{
}
#pragma init(fuse_uvfs_init)
static void
fuse_uvfs_init(void)
{
sizeof (struct fuse_file_info), 0,
}
#pragma fini(fuse_uvfs_fini)
static void
fuse_uvfs_fini(void)
{
}
int
fuse_main(void)
{
return (-1);
}