basic version of direct FUSE interface (ie. not relying on libfuse)

This commit is contained in:
Csaba Henk 2009-07-13 22:28:07 +02:00
parent 57a6cb9806
commit d5910898f1
6 changed files with 1469 additions and 986 deletions

View File

@ -206,47 +206,8 @@ AC_ARG_ENABLE([fuse-client],
AC_HELP_STRING([--disable-fuse-client],
[Do not build the fuse client. NOTE: you cannot mount glusterfs without the client]))
if test "x$enable_fuse_client" != "xno"; then
AC_CHECK_LIB([fuse],
[fuse_req_interrupt_func],
[HAVE_LIBFUSE="yes"],
[HAVE_LIBFUSE="no"])
if test "x$HAVE_LIBFUSE" = "xyes"; then
AC_TRY_COMPILE([#define FUSE_USE_VERSION 26
#define _FILE_OFFSET_BITS 64
#include <fuse.h>],
#define _GLFS_FUSE_VERSION_28 28
#if (FUSE_VERSION < _GLFS_FUSE_VERSION_28)
#error "fuse version 2.8 not found"
#endif
,
[HAVE_FUSE_VERSION_28="yes"],
[HAVE_FUSE_VERSION_28="no"])
AC_CHECK_LIB([fuse],
[fuse_reply_iov],
[HAVE_FUSE_REPLY_IOV="yes"],
[HAVE_FUSE_REPLY_IOV="no"])
fi
fi
if test "x$HAVE_FUSE_REPLY_IOV" = "xyes"; then
AC_DEFINE(HAVE_FUSE_REPLY_IOV, 1, [found fuse_reply_iov])
fi
if test "x$HAVE_LIBFUSE" = "xyes" -a "x$HAVE_FUSE_VERSION_28" = "xyes"; then
AC_DEFINE(HAVE_FUSE_VERSION_28, 1, [found fuse 2.8 version])
fi
if test "x$enable_fuse_client" = "xyes" -a "x$HAVE_LIBFUSE" = "xno"; then
echo "FUSE requested but not found."
exit 1
fi
BUILD_FUSE_CLIENT=no
if test "x$enable_fuse_client" != "xno" -a "x$HAVE_LIBFUSE" = "xyes"; then
if test "x$enable_fuse_client" != "xno"; then
FUSE_CLIENT_SUBDIR=fuse
BUILD_FUSE_CLIENT="yes"
fi

View File

@ -1,10 +1,10 @@
noinst_HEADERS = fuse-extra.h
noinst_HEADERS = fuse_kernel.h
xlator_LTLIBRARIES = fuse.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/mount
fuse_la_SOURCES = fuse-bridge.c fuse-extra.c
fuse_la_LDFLAGS = -module -avoidversion -shared -nostartfiles $(GF_FUSE_LDADD)
fuse_la_SOURCES = fuse-bridge.c
fuse_la_LDFLAGS = -module -avoidversion -shared -nostartfiles
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS) -Wall \
-I$(top_srcdir)/libglusterfs/src $(GF_CFLAGS) -DFUSE_USE_VERSION=26

File diff suppressed because it is too large Load Diff

View File

@ -1,155 +0,0 @@
/*
Copyright (c) 2006-2009 Z RESEARCH, Inc. <http://www.zresearch.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif /* _CONFIG_H */
#include "fuse-extra.h"
#include "common-utils.h"
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include "common-utils.h"
struct fuse_req;
struct fuse_ll;
struct fuse_req {
struct fuse_ll *f;
uint64_t unique;
int ctr;
pthread_mutex_t lock;
struct fuse_ctx ctx;
struct fuse_chan *ch;
int interrupted;
union {
struct {
uint64_t unique;
} i;
struct {
fuse_interrupt_func_t func;
void *data;
} ni;
} u;
struct fuse_req *next;
struct fuse_req *prev;
};
#ifdef HAVE_FUSE_VERSION_28
struct fuse_ll {
int debug;
int allow_root;
int atomic_o_trunc;
int big_writes;
struct fuse_lowlevel_ops op;
int got_init;
void *userdata;
uid_t owner;
struct fuse_conn_info conn;
struct fuse_req list;
struct fuse_req interrupts;
pthread_mutex_t lock;
int got_destroy;
};
#else
struct fuse_ll {
int debug;
int allow_root;
struct fuse_lowlevel_ops op;
int got_init;
void *userdata;
uid_t owner;
struct fuse_conn_info conn;
struct fuse_req list;
struct fuse_req interrupts;
pthread_mutex_t lock;
int got_destroy;
};
#endif /* FUSE 2.8 */
struct fuse_out_header {
uint32_t len;
int32_t error;
uint64_t unique;
};
uint64_t req_callid (fuse_req_t req)
{
return req->unique;
}
static void destroy_req(fuse_req_t req)
{
pthread_mutex_destroy (&req->lock);
FREE (req);
}
static void list_del_req(struct fuse_req *req)
{
struct fuse_req *prev = req->prev;
struct fuse_req *next = req->next;
prev->next = next;
next->prev = prev;
}
static void
free_req (fuse_req_t req)
{
int ctr;
struct fuse_ll *f = req->f;
pthread_mutex_lock(&req->lock);
req->u.ni.func = NULL;
req->u.ni.data = NULL;
pthread_mutex_unlock(&req->lock);
pthread_mutex_lock(&f->lock);
list_del_req(req);
ctr = --req->ctr;
pthread_mutex_unlock(&f->lock);
if (!ctr)
destroy_req(req);
}
int32_t
fuse_reply_vec (fuse_req_t req,
struct iovec *vector,
int32_t count)
{
int32_t error = 0;
struct fuse_out_header out;
struct iovec *iov;
int res;
iov = alloca ((count + 1) * sizeof (*vector));
out.unique = req->unique;
out.error = error;
iov[0].iov_base = &out;
iov[0].iov_len = sizeof(struct fuse_out_header);
memcpy (&iov[1], vector, count * sizeof (*vector));
count++;
out.len = iov_length(iov, count);
res = fuse_chan_send(req->ch, iov, count);
free_req(req);
return res;
}

View File

@ -1,42 +0,0 @@
/*
Copyright (c) 2007-2009 Z RESEARCH, Inc. <http://www.zresearch.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
#ifndef _FUSE_EXTRA_H
#define _FUSE_EXTRA_H
#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif /* _CONFIG_H */
#include <stdlib.h>
#include <fuse/fuse_lowlevel.h>
#define GLUSTERFS_XATTR_LEN_MAX 65536
uint64_t req_callid (fuse_req_t req);
size_t fuse_dirent_size (size_t dname_len);
int32_t
fuse_reply_vec (fuse_req_t req,
struct iovec *vector,
int32_t count);
#endif /* _FUSE_EXTRA_H */

View File

@ -0,0 +1,509 @@
/*
This file defines the kernel interface of FUSE
Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
This -- and only this -- header file may also be distributed under
the terms of the BSD Licence as follows:
Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/*
* This file defines the kernel interface of FUSE
*
* Protocol changelog:
*
* 7.9:
* - new fuse_getattr_in input argument of GETATTR
* - add lk_flags in fuse_lk_in
* - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
* - add blksize field to fuse_attr
* - add file flags field to fuse_read_in and fuse_write_in
*
* 7.10
* - add nonseekable open flag
*
* 7.11
* - add IOCTL message
* - add unsolicited notification support
* - add POLL message and NOTIFY_POLL notification
*/
#ifndef _LINUX_FUSE_H
#define _LINUX_FUSE_H
#include <sys/types.h>
#define __u64 uint64_t
#define __u32 uint32_t
#define __s32 int32_t
/** Version number of this interface */
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
#define FUSE_KERNEL_MINOR_VERSION 11
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
/* Make sure all structures are padded to 64bit boundary, so 32bit
userspace works under 64bit kernels */
struct fuse_attr {
__u64 ino;
__u64 size;
__u64 blocks;
__u64 atime;
__u64 mtime;
__u64 ctime;
__u32 atimensec;
__u32 mtimensec;
__u32 ctimensec;
__u32 mode;
__u32 nlink;
__u32 uid;
__u32 gid;
__u32 rdev;
__u32 blksize;
__u32 padding;
};
struct fuse_kstatfs {
__u64 blocks;
__u64 bfree;
__u64 bavail;
__u64 files;
__u64 ffree;
__u32 bsize;
__u32 namelen;
__u32 frsize;
__u32 padding;
__u32 spare[6];
};
struct fuse_file_lock {
__u64 start;
__u64 end;
__u32 type;
__u32 pid; /* tgid */
};
/**
* Bitmasks for fuse_setattr_in.valid
*/
#define FATTR_MODE (1 << 0)
#define FATTR_UID (1 << 1)
#define FATTR_GID (1 << 2)
#define FATTR_SIZE (1 << 3)
#define FATTR_ATIME (1 << 4)
#define FATTR_MTIME (1 << 5)
#define FATTR_FH (1 << 6)
#define FATTR_ATIME_NOW (1 << 7)
#define FATTR_MTIME_NOW (1 << 8)
#define FATTR_LOCKOWNER (1 << 9)
/**
* Flags returned by the OPEN request
*
* FOPEN_DIRECT_IO: bypass page cache for this open file
* FOPEN_KEEP_CACHE: don't invalidate the data cache on open
* FOPEN_NONSEEKABLE: the file is not seekable
*/
#define FOPEN_DIRECT_IO (1 << 0)
#define FOPEN_KEEP_CACHE (1 << 1)
#define FOPEN_NONSEEKABLE (1 << 2)
/**
* INIT request/reply flags
*
* FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
*/
#define FUSE_ASYNC_READ (1 << 0)
#define FUSE_POSIX_LOCKS (1 << 1)
#define FUSE_FILE_OPS (1 << 2)
#define FUSE_ATOMIC_O_TRUNC (1 << 3)
#define FUSE_EXPORT_SUPPORT (1 << 4)
#define FUSE_BIG_WRITES (1 << 5)
/**
* Release flags
*/
#define FUSE_RELEASE_FLUSH (1 << 0)
/**
* Getattr flags
*/
#define FUSE_GETATTR_FH (1 << 0)
/**
* Lock flags
*/
#define FUSE_LK_FLOCK (1 << 0)
/**
* WRITE flags
*
* FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed
* FUSE_WRITE_LOCKOWNER: lock_owner field is valid
*/
#define FUSE_WRITE_CACHE (1 << 0)
#define FUSE_WRITE_LOCKOWNER (1 << 1)
/**
* Read flags
*/
#define FUSE_READ_LOCKOWNER (1 << 1)
/**
* Ioctl flags
*
* FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine
* FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed
* FUSE_IOCTL_RETRY: retry with new iovecs
*
* FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs
*/
#define FUSE_IOCTL_COMPAT (1 << 0)
#define FUSE_IOCTL_UNRESTRICTED (1 << 1)
#define FUSE_IOCTL_RETRY (1 << 2)
#define FUSE_IOCTL_MAX_IOV 256
/**
* Poll flags
*
* FUSE_POLL_SCHEDULE_NOTIFY: request poll notify
*/
#define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0)
enum fuse_opcode {
FUSE_LOOKUP = 1,
FUSE_FORGET = 2, /* no reply */
FUSE_GETATTR = 3,
FUSE_SETATTR = 4,
FUSE_READLINK = 5,
FUSE_SYMLINK = 6,
FUSE_MKNOD = 8,
FUSE_MKDIR = 9,
FUSE_UNLINK = 10,
FUSE_RMDIR = 11,
FUSE_RENAME = 12,
FUSE_LINK = 13,
FUSE_OPEN = 14,
FUSE_READ = 15,
FUSE_WRITE = 16,
FUSE_STATFS = 17,
FUSE_RELEASE = 18,
FUSE_FSYNC = 20,
FUSE_SETXATTR = 21,
FUSE_GETXATTR = 22,
FUSE_LISTXATTR = 23,
FUSE_REMOVEXATTR = 24,
FUSE_FLUSH = 25,
FUSE_INIT = 26,
FUSE_OPENDIR = 27,
FUSE_READDIR = 28,
FUSE_RELEASEDIR = 29,
FUSE_FSYNCDIR = 30,
FUSE_GETLK = 31,
FUSE_SETLK = 32,
FUSE_SETLKW = 33,
FUSE_ACCESS = 34,
FUSE_CREATE = 35,
FUSE_INTERRUPT = 36,
FUSE_BMAP = 37,
FUSE_DESTROY = 38,
FUSE_IOCTL = 39,
FUSE_POLL = 40,
};
enum fuse_notify_code {
FUSE_NOTIFY_POLL = 1,
FUSE_NOTIFY_CODE_MAX,
};
/* The read buffer is required to be at least 8k, but may be much larger */
#define FUSE_MIN_READ_BUFFER 8192
#define FUSE_COMPAT_ENTRY_OUT_SIZE 120
struct fuse_entry_out {
__u64 nodeid; /* Inode ID */
__u64 generation; /* Inode generation: nodeid:gen must
be unique for the fs's lifetime */
__u64 entry_valid; /* Cache timeout for the name */
__u64 attr_valid; /* Cache timeout for the attributes */
__u32 entry_valid_nsec;
__u32 attr_valid_nsec;
struct fuse_attr attr;
};
struct fuse_forget_in {
__u64 nlookup;
};
struct fuse_getattr_in {
__u32 getattr_flags;
__u32 dummy;
__u64 fh;
};
#define FUSE_COMPAT_ATTR_OUT_SIZE 96
struct fuse_attr_out {
__u64 attr_valid; /* Cache timeout for the attributes */
__u32 attr_valid_nsec;
__u32 dummy;
struct fuse_attr attr;
};
struct fuse_mknod_in {
__u32 mode;
__u32 rdev;
};
struct fuse_mkdir_in {
__u32 mode;
__u32 padding;
};
struct fuse_rename_in {
__u64 newdir;
};
struct fuse_link_in {
__u64 oldnodeid;
};
struct fuse_setattr_in {
__u32 valid;
__u32 padding;
__u64 fh;
__u64 size;
__u64 lock_owner;
__u64 atime;
__u64 mtime;
__u64 unused2;
__u32 atimensec;
__u32 mtimensec;
__u32 unused3;
__u32 mode;
__u32 unused4;
__u32 uid;
__u32 gid;
__u32 unused5;
};
struct fuse_open_in {
__u32 flags;
__u32 mode;
};
struct fuse_open_out {
__u64 fh;
__u32 open_flags;
__u32 padding;
};
struct fuse_release_in {
__u64 fh;
__u32 flags;
__u32 release_flags;
__u64 lock_owner;
};
struct fuse_flush_in {
__u64 fh;
__u32 unused;
__u32 padding;
__u64 lock_owner;
};
struct fuse_read_in {
__u64 fh;
__u64 offset;
__u32 size;
__u32 read_flags;
__u64 lock_owner;
__u32 flags;
__u32 padding;
};
#define FUSE_COMPAT_WRITE_IN_SIZE 24
struct fuse_write_in {
__u64 fh;
__u64 offset;
__u32 size;
__u32 write_flags;
__u64 lock_owner;
__u32 flags;
__u32 padding;
};
struct fuse_write_out {
__u32 size;
__u32 padding;
};
#define FUSE_COMPAT_STATFS_SIZE 48
struct fuse_statfs_out {
struct fuse_kstatfs st;
};
struct fuse_fsync_in {
__u64 fh;
__u32 fsync_flags;
__u32 padding;
};
struct fuse_setxattr_in {
__u32 size;
__u32 flags;
};
struct fuse_getxattr_in {
__u32 size;
__u32 padding;
};
struct fuse_getxattr_out {
__u32 size;
__u32 padding;
};
struct fuse_lk_in {
__u64 fh;
__u64 owner;
struct fuse_file_lock lk;
__u32 lk_flags;
__u32 padding;
};
struct fuse_lk_out {
struct fuse_file_lock lk;
};
struct fuse_access_in {
__u32 mask;
__u32 padding;
};
struct fuse_init_in {
__u32 major;
__u32 minor;
__u32 max_readahead;
__u32 flags;
};
struct fuse_init_out {
__u32 major;
__u32 minor;
__u32 max_readahead;
__u32 flags;
__u32 unused;
__u32 max_write;
};
struct fuse_interrupt_in {
__u64 unique;
};
struct fuse_bmap_in {
__u64 block;
__u32 blocksize;
__u32 padding;
};
struct fuse_bmap_out {
__u64 block;
};
struct fuse_ioctl_in {
__u64 fh;
__u32 flags;
__u32 cmd;
__u64 arg;
__u32 in_size;
__u32 out_size;
};
struct fuse_ioctl_out {
__s32 result;
__u32 flags;
__u32 in_iovs;
__u32 out_iovs;
};
struct fuse_poll_in {
__u64 fh;
__u64 kh;
__u32 flags;
__u32 padding;
};
struct fuse_poll_out {
__u32 revents;
__u32 padding;
};
struct fuse_notify_poll_wakeup_out {
__u64 kh;
};
struct fuse_in_header {
__u32 len;
__u32 opcode;
__u64 unique;
__u64 nodeid;
__u32 uid;
__u32 gid;
__u32 pid;
__u32 padding;
};
struct fuse_out_header {
__u32 len;
__s32 error;
__u64 unique;
};
struct fuse_dirent {
__u64 ino;
__u64 off;
__u32 namelen;
__u32 type;
char name[0];
};
#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name)
#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1))
#define FUSE_DIRENT_SIZE(d) \
FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
#endif /* _LINUX_FUSE_H */