OS X: basic additions for OS X client support

Signed-off-by: Csaba Henk <csaba@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>

BUG: 361 (GlusterFS 3.0 should work on Mac OS/X)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=361
This commit is contained in:
Csaba Henk 2010-05-17 07:06:58 +00:00 committed by Anand V. Avati
parent 86ee9d3e14
commit 18d982e6d0
13 changed files with 1290 additions and 47 deletions

View File

@ -158,6 +158,14 @@ AC_CHECK_HEADERS([sys/xattr.h])
AC_CHECK_HEADERS([sys/extattr.h])
case $host_os in
darwin*)
if ! test "`/usr/bin/sw_vers | grep ProductVersion: | cut -f 2 | cut -d. -f2`" -ge 5; then
AC_MSG_ERROR([You need at least OS X 10.5 (Leopard) to build Glusterfs])
fi
;;
esac
dnl Mac OS X does not have spinlocks
AC_CHECK_FUNC([pthread_spin_init], [have_spinlock=yes])
if test "x${have_spinlock}" = "xyes"; then
@ -333,6 +341,7 @@ case $host_os in
GF_CFLAGS="${ARGP_STANDALONE_CPPFLAGS}"
GF_GLUSTERFS_CFLAGS="${GF_CFLAGS}"
GF_LDADD="${ARGP_STANDALONE_LDADD}"
GF_FUSE_CFLAGS="-DFUSERMOUNT_DIR=\\\"\$(bindir)\\\""
;;
solaris*)
GF_HOST_OS="GF_SOLARIS_HOST_OS"
@ -352,7 +361,7 @@ case $host_os in
if test "x$ac_cv_header_execinfo_h" = "xyes"; then
GF_GLUSTERFS_LDFLAGS="-lexecinfo"
fi
GF_FUSE_LDADD="-liconv -lfuse"
BUILD_FUSE_CLIENT=no
;;
darwin*)
GF_HOST_OS="GF_DARWIN_HOST_OS"
@ -360,7 +369,7 @@ case $host_os in
GF_CFLAGS="${ARGP_STANDALONE_CPPFLAGS} -D__DARWIN_64_BIT_INO_T -bundle -undefined suppress -flat_namespace"
GF_GLUSTERFS_CFLAGS="${ARGP_STANDALONE_CPPFLAGS} -D__DARWIN_64_BIT_INO_T -undefined suppress -flat_namespace"
GF_LDADD="${ARGP_STANDALONE_LDADD}"
GF_FUSE_LDADD="-liconv -lfuse_ino64"
GF_FUSE_CFLAGS="-I\$(CONTRIBDIR)/macfuse"
;;
esac
@ -370,7 +379,7 @@ AC_SUBST(GF_GLUSTERFS_CFLAGS)
AC_SUBST(GF_CFLAGS)
AC_SUBST(GF_LDFLAGS)
AC_SUBST(GF_LDADD)
AC_SUBST(GF_FUSE_LDADD)
AC_SUBST(GF_FUSE_CFLAGS)
CONTRIBDIR='$(top_srcdir)/contrib'
AC_SUBST(CONTRIBDIR)

View File

@ -0,0 +1,439 @@
/*
This file defines the kernel interface of FUSE
Copyright (C) 2001-2007 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.
*/
#ifndef linux
#include <sys/types.h>
#define __u64 uint64_t
#define __u32 uint32_t
#define __s32 int32_t
#else
#include <asm/types.h>
#include <linux/major.h>
#endif
/** Version number of this interface */
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
#define FUSE_KERNEL_MINOR_VERSION 8
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
/** The major number of the fuse character device */
#define FUSE_MAJOR MISC_MAJOR
/** The minor number of the fuse character device */
#define FUSE_MINOR 229
/* 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;
#if (__FreeBSD__ >= 10)
__u64 crtime;
#endif /* __FreeBSD__ >= 10 */
__u32 atimensec;
__u32 mtimensec;
__u32 ctimensec;
#if (__FreeBSD__ >= 10)
__u32 crtimensec;
#endif /* __FreeBSD__ >= 10 */
__u32 mode;
__u32 nlink;
__u32 uid;
__u32 gid;
__u32 rdev;
#if (__FreeBSD__ >= 10)
__u32 flags; /* file flags; see chflags(2) */
#endif /* __FreeBSD__ >= 10 */
};
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)
#if (__FreeBSD__ >= 10)
#define FATTR_CRTIME (1 << 28)
#define FATTR_CHGTIME (1 << 29)
#define FATTR_BKUPTIME (1 << 30)
#define FATTR_FLAGS (1 << 31)
#endif /* __FreeBSD__ >= 10 */
/**
* 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
*/
#define FOPEN_DIRECT_IO (1 << 0)
#define FOPEN_KEEP_CACHE (1 << 1)
#if (__FreeBSD__ >= 10)
#define FOPEN_PURGE_ATTR (1 << 30)
#define FOPEN_PURGE_UBC (1 << 31)
#endif
/**
* INIT request/reply flags
*/
#define FUSE_ASYNC_READ (1 << 0)
#define FUSE_POSIX_LOCKS (1 << 1)
#if (__FreeBSD__ >= 10)
#define FUSE_CASE_INSENSITIVE (1 << 29)
#define FUSE_VOL_RENAME (1 << 30)
#define FUSE_XTIMES (1 << 31)
#endif /* __FreeBSD__ >= 10 */
/**
* Release flags
*/
#define FUSE_RELEASE_FLUSH (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,
#if (__FreeBSD__ >= 10)
FUSE_SETVOLNAME = 61,
FUSE_GETXTIMES = 62,
FUSE_EXCHANGE = 63,
#endif /* __FreeBSD__ >= 10 */
};
/* The read buffer is required to be at least 8k, but may be much larger */
#define FUSE_MIN_READ_BUFFER 8192
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_attr_out {
__u64 attr_valid; /* Cache timeout for the attributes */
__u32 attr_valid_nsec;
__u32 dummy;
struct fuse_attr attr;
};
#if (__FreeBSD__ >= 10)
struct fuse_getxtimes_out {
__u64 bkuptime;
__u64 crtime;
__u32 bkuptimensec;
__u32 crtimensec;
};
#endif /* __FreeBSD__ >= 10 */
struct fuse_mknod_in {
__u32 mode;
__u32 rdev;
};
struct fuse_mkdir_in {
__u32 mode;
__u32 padding;
};
struct fuse_rename_in {
__u64 newdir;
};
#if (__FreeBSD__ >= 10)
struct fuse_exchange_in {
__u64 olddir;
__u64 newdir;
__u64 options;
};
#endif /* __FreeBSD__ >= 10 */
struct fuse_link_in {
__u64 oldnodeid;
};
struct fuse_setattr_in {
__u32 valid;
__u32 padding;
__u64 fh;
__u64 size;
__u64 unused1;
__u64 atime;
__u64 mtime;
__u64 unused2;
__u32 atimensec;
__u32 mtimensec;
__u32 unused3;
__u32 mode;
__u32 unused4;
__u32 uid;
__u32 gid;
__u32 unused5;
#if (__FreeBSD__ >= 10)
__u64 bkuptime;
__u64 chgtime;
__u64 crtime;
__u32 bkuptimensec;
__u32 chgtimensec;
__u32 crtimensec;
__u32 flags; /* file flags; see chflags(2) */
#endif /* __FreeBSD__ >= 10 */
};
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 padding;
};
struct fuse_write_in {
__u64 fh;
__u64 offset;
__u32 size;
__u32 write_flags;
};
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;
#if (__FreeBSD__ >= 10)
__u32 position;
__u32 padding;
#endif /* __FreeBSD__ >= 10 */
};
struct fuse_getxattr_in {
__u32 size;
__u32 padding;
#if (__FreeBSD__ >= 10)
__u32 position;
__u32 padding2;
#endif /* __FreeBSD__ >= 10 */
};
struct fuse_getxattr_out {
__u32 size;
__u32 padding;
};
struct fuse_lk_in {
__u64 fh;
__u64 owner;
struct fuse_file_lock lk;
};
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_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)

128
contrib/macfuse/COPYING.txt Normal file
View File

@ -0,0 +1,128 @@
MacFUSE is a package developed by Google and is covered under the following
BSD-style license:
================================================================
Copyright (c) 2007-2009 Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* 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.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT
OWNER 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.
================================================================
Note that Google's patches to the FUSE library (libfuse/*.patch) (and to
the SSHFS user-space program (filesystems/sshfs/*.patch) are also released
under the BSD license.
Portions of this package were derived from code developed by other authors.
Please read further for specific details.
* fusefs/fuse_kernel.h is an unmodified copy of the interface header from
the Linux FUSE distribution (http://fuse.sourceforge.net). fuse_kernel.h
can be redistributed either under the GPL or under the BSD license. It
is being redistributed here under the BSD license.
* Unless otherwise noted, parts of MacFUSE (multiple files in fusefs/) contain
code derived from the FreeBSD version of FUSE (http://fuse4bsd.creo.hu),
which is covered by the following BSD-style license:
================================================================
Copyright (C) 2005 Csaba Henk. 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.
================================================================
* fusefs/fuse_nodehash.c is a modified version of HashNode.c from an
Apple Developer Technical Support (DTS) sample code example. The original
source, which is available on http://developer.apple.com/samplecode/, has
the following disclaimer:
================================================================
Disclaimer: IMPORTANT: This Apple software is supplied to you by
Apple Computer, Inc. Apple") in consideration of your agreement
to the following terms, and your use, installation, modification
or redistribution of this Apple software constitutes acceptance
of these terms. If you do not agree with these terms, please do
not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms,
and subject to these terms, Apple grants you a personal, non-exclusive
license, under Apple's copyrights in this original Apple software
(the "Apple Software"), to use, reproduce, modify and redistribute
the Apple Software, with or without modifications, in source and/or
binary forms; provided that if you redistribute the Apple Software
in its entirety and without modifications, you must retain this
notice and the following text and disclaimers in all such
redistributions of the Apple Software. Neither the name,
trademarks, service marks or logos of Apple Computer, Inc. may be
used to endorse or promote products derived from the Apple Software
without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses,
express or implied, are granted by Apple herein, including but
not limited to any patent rights that may be infringed by your
derivative works or by other works in which the Apple Software
may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR
ITS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT,
INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE,
HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING
NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================
* Parts of the mount_fusefs and the load_fusefs command-line programs
(implemented in fusefs/mount_fusefs/ and fusefs/load_fusefs/, respectively)
come from Apple's Darwin sources and are covered under the Apple Public
Source License (APSL). You can read the APSL at:
http://www.publicsource.apple.com/apsl/

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2006-2008 Google. All Rights Reserved.
* Amit Singh <singh@>
*/
#ifndef _FUSE_IOCTL_H_
#define _FUSE_IOCTL_H_
#include <stdint.h>
#include <sys/ioctl.h>
/* FUSEDEVIOCxxx */
/* Get mounter's pid. */
#define FUSEDEVGETMOUNTERPID _IOR('F', 1, u_int32_t)
/* Check if FUSE_INIT kernel-user handshake is complete. */
#define FUSEDEVIOCGETHANDSHAKECOMPLETE _IOR('F', 2, u_int32_t)
/* Mark the daemon as dead. */
#define FUSEDEVIOCSETDAEMONDEAD _IOW('F', 3, u_int32_t)
/* Tell the kernel which operations the daemon implements. */
#define FUSEDEVIOCSETIMPLEMENTEDBITS _IOW('F', 4, u_int64_t)
/* Get device's random "secret". */
#define FUSEDEVIOCGETRANDOM _IOR('F', 5, u_int32_t)
/*
* The 'AVFI' (alter-vnode-for-inode) ioctls all require an inode number
* as an argument. In the user-space library, you can get the inode number
* from a path by using fuse_lookup_inode_by_path_np() [lib/fuse.c].
*
* To see an example of using this, see the implementation of
* fuse_purge_path_np() in lib/fuse_darwin.c.
*/
struct fuse_avfi_ioctl {
uint64_t inode;
uint64_t cmd;
uint32_t ubc_flags;
uint32_t note;
off_t size;
};
/* Alter the vnode (if any) specified by the given inode. */
#define FUSEDEVIOCALTERVNODEFORINODE _IOW('F', 6, struct fuse_avfi_ioctl)
#define FSCTLALTERVNODEFORINODE IOCBASECMD(FUSEDEVIOCALTERVNODEFORINODE)
/*
* Possible cmd values for AVFI.
*/
#define FUSE_AVFI_MARKGONE 0x00000001 /* no ubc_flags */
#define FUSE_AVFI_PURGEATTRCACHE 0x00000002 /* no ubc_flags */
#define FUSE_AVFI_PURGEVNCACHE 0x00000004 /* no ubc_flags */
#define FUSE_AVFI_UBC 0x00000008 /* uses ubc_flags */
#define FUSE_AVFI_UBC_SETSIZE 0x00000010 /* uses ubc_flags, size */
#define FUSE_AVFI_KNOTE 0x00000020 /* uses note */
#define FUSE_SETACLSTATE _IOW('h', 10, int32_t)
#define FSCTLSETACLSTATE IOCBASECMD(FUSE_SETACLSTATE)
#endif /* _FUSE_IOCTL_H_ */

View File

@ -0,0 +1,147 @@
/*
* Copyright (C) 2006-2008 Google. All Rights Reserved.
* Amit Singh <singh@>
*/
#ifndef _FUSE_PARAM_H_
#define _FUSE_PARAM_H_
/* Compile-time tunables (M_MACFUSE*) */
#define M_MACFUSE_ENABLE_FIFOFS 0
#define M_MACFUSE_ENABLE_INTERRUPT 1
#define M_MACFUSE_ENABLE_SPECFS 0
#define M_MACFUSE_ENABLE_TSLOCKING 0
#define M_MACFUSE_ENABLE_UNSUPPORTED 1
#define M_MACFUSE_ENABLE_XATTR 1
#if M_MACFUSE_ENABLE_UNSUPPORTED
#define M_MACFUSE_ENABLE_DSELECT 0
#define M_MACFUSE_ENABLE_EXCHANGE 1
#define M_MACFUSE_ENABLE_KQUEUE 1
#define M_MACFUSE_ENABLE_KUNC 0
#if __LP64__
#define M_MACFUSE_ENABLE_INTERIM_FSNODE_LOCK 1
#endif /* __LP64__ */
#endif /* M_MACFUSE_ENABLE_UNSUPPORTED */
#if M_MACFUSE_ENABLE_INTERIM_FSNODE_LOCK
#define FUSE_VNOP_EXPORT __private_extern__
#else
#define FUSE_VNOP_EXPORT static
#endif /* M_MACFUSE_ENABLE_INTERIM_FSNODE_LOCK */
/* User Control */
#define MACFUSE_POSTUNMOUNT_SIGNAL SIGKILL
#define MACOSX_ADMIN_GROUP_NAME "admin"
#define SYSCTL_MACFUSE_TUNABLES_ADMIN "macfuse.tunables.admin_group"
#define SYSCTL_MACFUSE_VERSION_NUMBER "macfuse.version.number"
/* Paths */
#define MACFUSE_BUNDLE_PATH "/Library/Filesystems/fusefs.fs"
#define MACFUSE_KEXT MACFUSE_BUNDLE_PATH "/Support/fusefs.kext"
#define MACFUSE_LOAD_PROG MACFUSE_BUNDLE_PATH "/Support/load_fusefs"
#define MACFUSE_MOUNT_PROG MACFUSE_BUNDLE_PATH "/Support/mount_fusefs"
#define SYSTEM_KEXTLOAD "/sbin/kextload"
#define SYSTEM_KEXTUNLOAD "/sbin/kextunload"
/* Compatible API version */
#define MACFUSE_MIN_USER_VERSION_MAJOR 7
#define MACFUSE_MIN_USER_VERSION_MINOR 5
/* Device Interface */
/*
* This is the prefix ("fuse" by default) of the name of a FUSE device node
* in devfs. The suffix is the device number. "/dev/fuse0" is the first FUSE
* device by default. If you change the prefix from the default to something
* else, the user-space FUSE library will need to know about it too.
*/
#define MACFUSE_DEVICE_BASENAME "fuse"
/*
* This is the number of /dev/fuse<n> nodes we will create. <n> goes from
* 0 to (FUSE_NDEVICES - 1).
*/
#define MACFUSE_NDEVICES 24
/*
* This is the default block size of the virtual storage devices that are
* implicitly implemented by the FUSE kernel extension. This can be changed
* on a per-mount basis (there's one such virtual device for each mount).
*/
#define FUSE_DEFAULT_BLOCKSIZE 4096
#define FUSE_MIN_BLOCKSIZE 512
#define FUSE_MAX_BLOCKSIZE MAXPHYS
#ifndef MAX_UPL_TRANSFER
#define MAX_UPL_TRANSFER 256
#endif
/*
* This is default I/O size used while accessing the virtual storage devices.
* This can be changed on a per-mount basis.
*
* Nevertheless, the I/O size must be at least as big as the block size.
*/
#define FUSE_DEFAULT_IOSIZE (16 * PAGE_SIZE)
#define FUSE_MIN_IOSIZE 512
#define FUSE_MAX_IOSIZE (MAX_UPL_TRANSFER * PAGE_SIZE)
#define FUSE_DEFAULT_INIT_TIMEOUT 10 /* s */
#define FUSE_MIN_INIT_TIMEOUT 1 /* s */
#define FUSE_MAX_INIT_TIMEOUT 300 /* s */
#define FUSE_INIT_WAIT_INTERVAL 100000 /* us */
#define FUSE_INIT_TIMEOUT_DEFAULT_BUTTON_TITLE "OK"
#define FUSE_INIT_TIMEOUT_NOTICE_MESSAGE \
"Timed out waiting for the file system to initialize. The volume has " \
"been ejected. You can use the init_timeout mount option to wait longer."
#define FUSE_DEFAULT_DAEMON_TIMEOUT 60 /* s */
#define FUSE_MIN_DAEMON_TIMEOUT 0 /* s */
#define FUSE_MAX_DAEMON_TIMEOUT 600 /* s */
#define FUSE_DAEMON_TIMEOUT_DEFAULT_BUTTON_TITLE "Keep Trying"
#define FUSE_DAEMON_TIMEOUT_OTHER_BUTTON_TITLE "Force Eject"
#define FUSE_DAEMON_TIMEOUT_ALTERNATE_BUTTON_TITLE "Don't Warn Again"
#define FUSE_DAEMON_TIMEOUT_ALERT_MESSAGE \
"There was a timeout waiting for the file system to respond. You can " \
"eject this volume immediately, but unsaved changes may be lost."
#define FUSE_DAEMON_TIMEOUT_ALERT_TIMEOUT 120 /* s */
#ifdef KERNEL
/*
* This is the soft upper limit on the number of "request tickets" FUSE's
* user-kernel IPC layer can have for a given mount. This can be modified
* through the fuse.* sysctl interface.
*/
#define FUSE_DEFAULT_MAX_FREE_TICKETS 1024
#define FUSE_DEFAULT_IOV_PERMANENT_BUFSIZE (1 << 19)
#define FUSE_DEFAULT_IOV_CREDIT 16
/* User-Kernel IPC Buffer */
#define FUSE_MIN_USERKERNEL_BUFSIZE (128 * 1024)
#define FUSE_MAX_USERKERNEL_BUFSIZE (4096 * 1024)
#define FUSE_REASONABLE_XATTRSIZE FUSE_MIN_USERKERNEL_BUFSIZE
#endif /* KERNEL */
#define FUSE_DEFAULT_USERKERNEL_BUFSIZE (4096 * 1024)
#define FUSE_LINK_MAX LINK_MAX
#define FUSE_UIO_BACKUP_MAX 8
#define FUSE_MAXNAMLEN 255
#endif /* _FUSE_PARAM_H_ */

View File

@ -0,0 +1,355 @@
/*
* Derived from mount_bsd.c from the fuse distribution.
*
* FUSE: Filesystem in Userspace
* Copyright (C) 2005-2006 Csaba Henk <csaba.henk@creo.hu>
* Copyright (C) 2007-2009 Amit Singh <asingh@gmail.com>
* Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
*
* This program can be distributed under the terms of the GNU LGPLv2.
* See the file COPYING.LIB.
*/
#undef _POSIX_C_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <paths.h>
#include <libproc.h>
#include <sys/utsname.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <AssertMacros.h>
#include "fuse_param.h"
#include "fuse_ioctl.h"
#include "glusterfs.h"
#include "logging.h"
#include "common-utils.h"
#define GFFUSE_LOGERR(...) \
gf_log ("glusterfs-fuse", GF_LOG_ERROR, ## __VA_ARGS__)
static long
fuse_os_version_major_np(void)
{
int ret = 0;
long major = 0;
char *c = NULL;
struct utsname u;
size_t oldlen;
oldlen = sizeof(u.release);
ret = sysctlbyname("kern.osrelease", u.release, &oldlen, NULL, 0);
if (ret != 0) {
return -1;
}
c = strchr(u.release, '.');
if (c == NULL) {
return -1;
}
*c = '\0';
errno = 0;
major = strtol(u.release, NULL, 10);
if ((errno == EINVAL) || (errno == ERANGE)) {
return -1;
}
return major;
}
static int
fuse_running_under_rosetta(void)
{
int result = 0;
int is_native = 1;
size_t sz = sizeof(result);
int ret = sysctlbyname("sysctl.proc_native", &result, &sz, NULL, (size_t)0);
if ((ret == 0) && !result) {
is_native = 0;
}
return !is_native;
}
static int
loadkmod(void)
{
int result = -1;
int pid, terminated_pid;
union wait status;
long major;
major = fuse_os_version_major_np();
if (major < 9) { /* not Mac OS X 10.5+ */
return EINVAL;
}
pid = fork();
if (pid == 0) {
execl(MACFUSE_LOAD_PROG, MACFUSE_LOAD_PROG, NULL);
/* exec failed */
exit(ENOENT);
}
require_action(pid != -1, Return, result = errno);
while ((terminated_pid = wait4(pid, (int *)&status, 0, NULL)) < 0) {
/* retry if EINTR, else break out with error */
if (errno != EINTR) {
break;
}
}
if ((terminated_pid == pid) && (WIFEXITED(status))) {
result = WEXITSTATUS(status);
} else {
result = -1;
}
Return:
check_noerr_string(result, strerror(errno));
return result;
}
int
gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param)
{
int fd, pid;
int result;
char *fdnam, *dev;
const char *mountprog = MACFUSE_MOUNT_PROG;
/* mount_fusefs should not try to spawn the daemon */
setenv("MOUNT_FUSEFS_SAFE", "1", 1);
/* to notify mount_fusefs it's called from lib */
setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1);
if (!mountpoint) {
fprintf(stderr, "missing or invalid mount point\n");
return -1;
}
if (fuse_running_under_rosetta()) {
fprintf(stderr, "MacFUSE does not work under Rosetta\n");
return -1;
}
signal(SIGCHLD, SIG_DFL); /* So that we can wait4() below. */
result = loadkmod();
if (result == EINVAL)
GFFUSE_LOGERR("OS X >= 10.5 (at least Leopard) required");
else if (result == 0 || result == ENOENT || result == EBUSY) {
/* Module loaded, but now need to check for user<->kernel match. */
char version[MAXHOSTNAMELEN + 1] = { 0 };
size_t version_len = MAXHOSTNAMELEN;
size_t version_len_desired = 0;
result = sysctlbyname(SYSCTL_MACFUSE_VERSION_NUMBER, version,
&version_len, NULL, (size_t)0);
if (result == 0) {
/* sysctlbyname() includes the trailing '\0' in version_len */
version_len_desired = strlen("2.x.y") + 1;
if (version_len != version_len_desired)
result = -1;
} else
strcpy(version, "?.?.?");
if (result == 0) {
char *ep;
char vstr[4];
unsigned vval;
int i;
for (i = 0; i < 3; i++)
vstr[i] = version[2*i];
vstr[3] = '\0';
vval = strtoul(vstr, &ep, 10);
if (*ep || vval < 203 || vval > 217)
result = -1;
else
gf_log("glusterfs-fuse", GF_LOG_INFO,
"MacFUSE kext version %s", version);
}
if (result != 0)
GFFUSE_LOGERR("MacFUSE version %s is not supported", version);
} else
GFFUSE_LOGERR("cannot load MacFUSE kext");
if (result != 0)
return -1;
fdnam = getenv("FUSE_DEV_FD");
if (fdnam) {
char *ep;
fd = strtol(fdnam, &ep, 10);
if (*ep != '\0' || fd < 0) {
GFFUSE_LOGERR("invalid value given in FUSE_DEV_FD");
return -1;
}
goto mount;
}
dev = getenv("FUSE_DEV_NAME");
if (dev) {
if ((fd = open(dev, O_RDWR)) < 0) {
GFFUSE_LOGERR("failed to open device (%s)", strerror(errno));
return -1;
}
} else {
int r, devidx = -1;
char devpath[MAXPATHLEN];
for (r = 0; r < MACFUSE_NDEVICES; r++) {
snprintf(devpath, MAXPATHLEN - 1,
_PATH_DEV MACFUSE_DEVICE_BASENAME "%d", r);
fd = open(devpath, O_RDWR);
if (fd >= 0) {
dev = devpath;
devidx = r;
break;
}
}
if (devidx == -1) {
GFFUSE_LOGERR("failed to open device (%s)", strerror(errno));
return -1;
}
}
mount:
if (getenv("FUSE_NO_MOUNT") || ! mountpoint)
goto out;
signal(SIGCHLD, SIG_IGN);
pid = fork();
if (pid == -1) {
GFFUSE_LOGERR("fork() failed (%s)", strerror(errno));
close(fd);
return -1;
}
if (pid == 0) {
pid = fork();
if (pid == -1) {
GFFUSE_LOGERR("fork() failed (%s)", strerror(errno));
close(fd);
exit(1);
}
if (pid == 0) {
const char *argv[32];
int a = 0;
char *opts = NULL;
if (asprintf(&opts, "%s,fssubtype=glusterfs", mnt_param) == -1) {
GFFUSE_LOGERR("Out of memory");
exit(1);
}
if (! fdnam)
asprintf(&fdnam, "%d", fd);
argv[a++] = mountprog;
if (opts) {
argv[a++] = "-o";
argv[a++] = opts;
}
argv[a++] = fdnam;
argv[a++] = mountpoint;
argv[a++] = NULL;
{
char title[MAXPATHLEN + 1] = { 0 };
u_int32_t len = MAXPATHLEN;
int ret = proc_pidpath(getpid(), title, len);
if (ret) {
setenv("MOUNT_FUSEFS_DAEMON_PATH", title, 1);
}
}
execvp(mountprog, (char **) argv);
GFFUSE_LOGERR("MacFUSE: failed to exec mount program (%s)", strerror(errno));
exit(1);
}
_exit(0);
}
out:
return fd;
}
void
gf_fuse_unmount(const char *mountpoint, int fd)
{
int ret;
struct stat sbuf;
char dev[128];
char resolved_path[PATH_MAX];
char *ep, *rp = NULL;
unsigned int hs_complete = 0;
ret = ioctl(fd, FUSEDEVIOCGETHANDSHAKECOMPLETE, &hs_complete);
if (ret || !hs_complete) {
return;
}
/* XXX does this have any use here? */
ret = ioctl(fd, FUSEDEVIOCSETDAEMONDEAD, &fd);
if (ret) {
return;
}
if (fstat(fd, &sbuf) == -1) {
return;
}
devname_r(sbuf.st_rdev, S_IFCHR, dev, 128);
if (strncmp(dev, MACFUSE_DEVICE_BASENAME,
sizeof(MACFUSE_DEVICE_BASENAME) - 1)) {
return;
}
strtol(dev + 4, &ep, 10);
if (*ep != '\0') {
return;
}
rp = realpath(mountpoint, resolved_path);
if (rp) {
ret = unmount(resolved_path, 0);
}
close(fd);
return;
}

View File

@ -1,6 +1,5 @@
mount/fuse:
* direct-io-mode GF_OPTION_TYPE_BOOL on|off|yes|no
* macfuse-local GF_OPTION_TYPE_BOOL on|off|yes|no
* mount-point (mountpoint) GF_OPTION_TYPE_PATH <any-posix-valid-path>
* attribute-timeout GF_OPTION_TYPE_DOUBLE 0.0
* entry-timeout GF_OPTION_TYPE_DOUBLE 0.0

View File

@ -158,10 +158,6 @@ static struct argp_option gf_options[] = {
"[default: 1]"},
{"volfile-check", ARGP_VOLFILE_CHECK_KEY, 0, 0,
"Enable strict volume file checking"},
#ifdef GF_DARWIN_HOST_OS
{"non-local", ARGP_NON_LOCAL_KEY, 0, 0,
"Mount the macfuse volume without '-o local' option"},
#endif
{0, 0, 0, 0, "Miscellaneous Options:"},
{0, }
};
@ -345,11 +341,6 @@ _add_fuse_mount (xlator_t *graph)
"if O_APPEND is used. disabling 'direct-io-mode'");
}
ret = dict_set_static_ptr (top->options, ZR_DIRECT_IO_OPT, "disable");
if (cmd_args->non_local)
ret = dict_set_uint32 (top->options, "macfuse-local",
cmd_args->non_local);
#else /* ! DARWIN HOST OS */
switch (cmd_args->fuse_direct_io_mode_flag) {
case 0: /* disable */
@ -994,13 +985,6 @@ parse_opts (int key, char *arg, struct argp_state *state)
gf_remember_xlator_option (&cmd_args->xlator_options, arg);
break;
#ifdef GF_DARWIN_HOST_OS
case ARGP_NON_LOCAL_KEY:
cmd_args->non_local = _gf_true;
break;
#endif /* DARWIN */
case ARGP_KEY_NO_ARGS:
break;

View File

@ -164,6 +164,10 @@ enum {
#define F_SETLK64 F_SETLK
#define F_SETLKW64 F_SETLKW
#ifndef FTW_CONTINUE
#define FTW_CONTINUE 0
#endif
int32_t gf_darwin_compat_listxattr (int len, dict_t *dict, int size);
int32_t gf_darwin_compat_getxattr (const char *key, dict_t *dict);
int32_t gf_darwin_compat_setxattr (dict_t *dict);
@ -298,7 +302,7 @@ size_t strnlen(const char *string, size_t maxlen);
}))
#endif
#define ALIGN(x) (((x) + sizeof (uint64_t) - 1) & ~(sizeof (uint64_t) - 1))
#define GF_DIR_ALIGN(x) (((x) + sizeof (uint64_t) - 1) & ~(sizeof (uint64_t) - 1))
#include <sys/types.h>
#include <dirent.h>
@ -307,16 +311,16 @@ static inline int32_t
dirent_size (struct dirent *entry)
{
#ifdef GF_BSD_HOST_OS
return ALIGN (24 /* FIX MEEEE!!! */ + entry->d_namlen);
return GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_namlen);
#endif
#ifdef GF_DARWIN_HOST_OS
return ALIGN (24 /* FIX MEEEE!!! */ + entry->d_namlen);
return GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_namlen);
#endif
#ifdef GF_LINUX_HOST_OS
return ALIGN (24 /* FIX MEEEE!!! */ + entry->d_reclen);
return GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_reclen);
#endif
#ifdef GF_SOLARIS_HOST_OS
return ALIGN (24 /* FIX MEEEE!!! */ + entry->d_reclen);
return GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_reclen);
#endif
}

View File

@ -219,11 +219,6 @@ struct _cmd_args {
double fuse_entry_timeout;
double fuse_attribute_timeout;
char *volume_name;
int non_local; /* Used only by darwin os,
used for '-o local' option */
char *icon_name; /* This string will appear as
Desktop icon name when mounted
on darwin */
int fuse_nodev;
int fuse_nosuid;

View File

@ -4,13 +4,20 @@ noinst_HEADERS = $(CONTRIBDIR)/fuse-include/fuse_kernel.h\
xlator_LTLIBRARIES = fuse.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/mount
if GF_DARWIN_HOST_OS
mount_source=$(CONTRIBDIR)/macfuse/mount_darwin.c
else
mount_source=$(CONTRIBDIR)/fuse-lib/mount.c
endif
fuse_la_SOURCES = fuse-bridge.c $(CONTRIBDIR)/fuse-lib/misc.c \
$(CONTRIBDIR)/fuse-lib/mount.c
$(mount_source)
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 -I$(CONTRIBDIR)/fuse-include \
$(GF_CFLAGS) -DFUSERMOUNT_DIR=\"$(bindir)\"
$(GF_CFLAGS) $(GF_FUSE_CFLAGS)
CLEANFILES =

View File

@ -25,6 +25,7 @@
* fuse_loc_fill() and inode_path() return success/failure.
*/
#include <stdint.h>
#include <signal.h>
#include <pthread.h>
@ -45,7 +46,13 @@
#include "common-utils.h"
#include "statedump.h"
#ifdef GF_DARWIN_HOST_OS
/* This is MacFUSE's marker for MacFUSE-specific code */
#define __FreeBSD__ 10
#include "fuse_kernel_macfuse.h"
#else
#include "fuse_kernel.h"
#endif
#include "fuse-misc.h"
#include "fuse-mount.h"
#include "fuse-mem-types.h"
@ -60,7 +67,12 @@
#define ZR_DIRECT_IO_OPT "direct-io-mode"
#define ZR_STRICT_VOLFILE_CHECK "strict-volfile-check"
#define FUSE_713_OP_HIGH (FUSE_POLL + 1)
#ifdef GF_LINUX_HOST_OS
#define FUSE_OP_HIGH (FUSE_POLL + 1)
#endif
#ifdef GF_DARWIN_HOST_OS
#define FUSE_OP_HIGH (FUSE_DESTROY + 1)
#endif
#define GLUSTERFS_XATTR_LEN_MAX 65536
#define MAX_FUSE_PROC_DELAY 1
@ -442,7 +454,14 @@ stat2attr (struct iatt *st, struct fuse_attr *fa)
fa->uid = st->ia_uid;
fa->gid = st->ia_gid;
fa->rdev = st->ia_rdev;
#if FUSE_KERNEL_MINOR_VERSION >= 9
fa->blksize = st->ia_blksize;
#endif
#ifdef GF_DARWIN_HOST_OS
fa->crtime = (uint64_t)-1;
fa->crtimensec = (uint32_t)-1;
fa->flags = 0;
#endif
}
@ -513,10 +532,14 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
feo.attr_valid_nsec =
calc_timeout_nsec (priv->attribute_timeout);
#if FUSE_KERNEL_MINOR_VERSION >= 9
priv->proto_minor >= 9 ?
send_fuse_obj (this, finh, &feo) :
send_fuse_data (this, finh, &feo,
FUSE_COMPAT_ENTRY_OUT_SIZE);
send_fuse_obj (this, finh, &feo) :
send_fuse_data (this, finh, &feo,
FUSE_COMPAT_ENTRY_OUT_SIZE);
#else
send_fuse_obj (this, finh, &feo);
#endif
} else {
gf_log ("glusterfs-fuse",
(op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_WARNING),
@ -664,10 +687,14 @@ fuse_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fao.attr_valid_nsec =
calc_timeout_nsec (priv->attribute_timeout);
#if FUSE_KERNEL_MINOR_VERSION >= 9
priv->proto_minor >= 9 ?
send_fuse_obj (this, finh, &fao) :
send_fuse_data (this, finh, &fao,
FUSE_COMPAT_ATTR_OUT_SIZE);
#else
send_fuse_obj (this, finh, &fao);
#endif
} else {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": %s() %s => -1 (%s)", frame->root->unique,
@ -714,10 +741,14 @@ fuse_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fao.attr_valid_nsec =
calc_timeout_nsec (priv->attribute_timeout);
#if FUSE_KERNEL_MINOR_VERSION >= 9
priv->proto_minor >= 9 ?
send_fuse_obj (this, finh, &fao) :
send_fuse_data (this, finh, &fao,
FUSE_COMPAT_ATTR_OUT_SIZE);
#else
send_fuse_obj (this, finh, &fao);
#endif
} else {
GF_LOG_OCCASIONALLY ( gf_fuse_conn_err_log, "glusterfs-fuse",
GF_LOG_WARNING,
@ -841,6 +872,19 @@ fuse_fd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (!IA_ISDIR (fd->inode->ia_type)) {
if (priv->direct_io_mode)
foo.open_flags |= FOPEN_DIRECT_IO;
#ifdef GF_DARWIN_HOST_OS
/* In Linux: by default, buffer cache
* is purged upon open, setting
* FOPEN_KEEP_CACHE implies no-purge
*
* In MacFUSE: by default, buffer cache
* is left intact upon open, setting
* FOPEN_PURGE_UBC implies purge
*
* [[Innnnteresting...]]
*/
foo.open_flags |= FOPEN_PURGE_UBC;
#endif
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
@ -923,10 +967,14 @@ fuse_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (state->truncate_needed) {
fuse_do_truncate (state, state->size);
} else {
#if FUSE_KERNEL_MINOR_VERSION >= 9
priv->proto_minor >= 9 ?
send_fuse_obj (this, finh, &fao) :
send_fuse_data (this, finh, &fao,
FUSE_COMPAT_ATTR_OUT_SIZE);
send_fuse_obj (this, finh, &fao) :
send_fuse_data (this, finh, &fao,
FUSE_COMPAT_ATTR_OUT_SIZE);
#else
send_fuse_obj (this, finh, &fao);
#endif
op_done = 1;
}
} else {
@ -1020,8 +1068,10 @@ fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
* linux-2.6.git;a=commit;h=v2.6.23-5896-gf333211
*/
priv = this->private;
#if FUSE_KERNEL_MINOR_VERSION >= 9
if (priv->proto_minor >= 9 && fsi->valid & FATTR_LOCKOWNER)
state->lk_owner = fsi->lock_owner;
#endif
if ((state->loc.inode == NULL && ret == 0) ||
(ret < 0)) {
@ -1286,8 +1336,10 @@ fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg)
int32_t ret = -1;
priv = this->private;
#if FUSE_KERNEL_MINOR_VERSION >= 12
if (priv->proto_minor < 12)
name = (char *)msg + FUSE_COMPAT_MKNOD_IN_SIZE;
#endif
GET_STATE (this, finh, state);
ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
@ -1653,9 +1705,13 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fouh.error = 0;
iov_out[0].iov_base = &fouh;
iov_out[1].iov_base = &feo;
#if FUSE_KERNEL_MINOR_VERSION >= 9
iov_out[1].iov_len = priv->proto_minor >= 9 ?
sizeof (feo) :
FUSE_COMPAT_ENTRY_OUT_SIZE;
#else
iov_out[1].iov_len = sizeof (feo);
#endif
iov_out[2].iov_base = &foo;
iov_out[2].iov_len = sizeof (foo);
if (send_fuse_iov (this, finh, iov_out, 3) == ENOENT) {
@ -1684,7 +1740,11 @@ out:
static void
fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
#if FUSE_KERNEL_MINOR_VERSION >= 12
struct fuse_create_in *fci = msg;
#else
struct fuse_open_in *fci = msg;
#endif
char *name = (char *)(fci + 1);
fuse_private_t *priv = NULL;
@ -1693,8 +1753,10 @@ fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)
int32_t ret = -1;
priv = this->private;
#if FUSE_KERNEL_MINOR_VERSION >= 12
if (priv->proto_minor < 12)
name = (char *)((struct fuse_open_in *)msg + 1);
#endif
GET_STATE (this, finh, state);
state->flags = fci->flags;
@ -1829,8 +1891,10 @@ fuse_readv (xlator_t *this, fuse_in_header_t *finh, void *msg)
/* See comment by similar code in fuse_settatr */
priv = this->private;
#if FUSE_KERNEL_MINOR_VERSION >= 9
if (priv->proto_minor >= 9 && fri->read_flags & FUSE_READ_LOCKOWNER)
state->lk_owner = fri->lock_owner;
#endif
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": READ (%p, size=%"PRIu32", offset=%"PRIu64")",
@ -1905,8 +1969,10 @@ fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg)
/* See comment by similar code in fuse_settatr */
priv = this->private;
#if FUSE_KERNEL_MINOR_VERSION >= 9
if (priv->proto_minor >= 9 && fwi->write_flags & FUSE_WRITE_LOCKOWNER)
state->lk_owner = fwi->lock_owner;
#endif
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": WRITE (%p, size=%"PRIu32", offset=%"PRId64")",
@ -2352,6 +2418,18 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
char *dict_value = NULL;
int32_t ret = -1;
#ifdef GF_DARWIN_HOST_OS
if (fsi->position) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": SETXATTR %s/%"PRIu64" (%s):"
"refusing positioned setxattr",
finh->unique, state->loc.path, finh->nodeid, name);
send_fuse_err (this, finh, EINVAL);
FREE (finh);
return;
}
#endif
#ifdef DISABLE_POSIX_ACL
if (!strncmp (name, "system.", 7)) {
send_fuse_err (this, finh, EOPNOTSUPP);
@ -2558,6 +2636,26 @@ fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
fuse_state_t *state = NULL;
int32_t ret = -1;
#ifdef GF_DARWIN_HOST_OS
if (fgxi->position) {
/* position can be used only for
* resource fork queries which we
* don't support anyway... so handling
* it separately is just sort of a
* matter of aesthetics, not strictly
* necessary.
*/
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": GETXATTR %s/%"PRIu64" (%s):"
"refusing positioned getxattr",
finh->unique, state->loc.path, finh->nodeid, name);
send_fuse_err (this, finh, EINVAL);
FREE (finh);
return;
}
#endif
#ifdef DISABLE_POSIX_ACL
if (!strncmp (name, "system.", 7)) {
send_fuse_err (this, finh, ENODATA);
@ -2843,6 +2941,7 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)
fino.max_readahead = 1 << 17;
fino.max_write = 1 << 17;
fino.flags = FUSE_ASYNC_READ | FUSE_POSIX_LOCKS;
#if FUSE_KERNEL_MINOR_VERSION >= 9
if (fini->minor >= 6 /* fuse_init_in has flags */ &&
fini->flags & FUSE_BIG_WRITES) {
/* no need for direct I/O mode by default if big writes are supported */
@ -2858,7 +2957,7 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)
}
if (fini->minor < 9)
*priv->msg0_len_p = sizeof(*finh) + FUSE_COMPAT_WRITE_IN_SIZE;
#endif
ret = send_fuse_obj (this, finh, &fino);
if (ret == 0)
gf_log ("glusterfs-fuse", GF_LOG_INFO,
@ -2895,7 +2994,7 @@ fuse_destroy (xlator_t *this, fuse_in_header_t *finh, void *msg)
GF_FREE (finh);
}
static fuse_handler_t *fuse_ops[FUSE_713_OP_HIGH];
static fuse_handler_t *fuse_ops[FUSE_OP_HIGH];
int
fuse_first_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
@ -3073,7 +3172,17 @@ fuse_thread_proc (void *data)
}
finh = (fuse_in_header_t *)iov_in[0].iov_base;
if (res != finh->len) {
if (res != finh->len
#ifdef GF_DARWIN_HOST_OS
/* work around fuse4bsd/MacFUSE msg size miscalculation bug,
* that is, payload size is not taken into account for
* buffered writes
*/
&& !(finh->opcode == FUSE_WRITE &&
finh->len == sizeof(*finh) + sizeof(struct fuse_write_in) &&
res == finh->len + ((struct fuse_write_in *)(finh + 1))->size)
#endif
) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING, "inconsistent read on /dev/fuse");
break;
}
@ -3105,6 +3214,12 @@ fuse_thread_proc (void *data)
msg = finh + 1;
}
#ifdef GF_DARWIN_HOST_OS
if (finh->opcode >= FUSE_OP_HIGH)
/* turn down MacFUSE specific messages */
fuse_enosys (this, finh, msg);
else
#endif
fuse_ops[finh->opcode] (this, finh, msg);
iobuf_unref (iobuf);
@ -3405,7 +3520,7 @@ init (xlator_t *this_xl)
pthread_mutex_init (&priv->child_up_mutex, NULL);
priv->child_up_value = 1;
for (i = 0; i < FUSE_713_OP_HIGH; i++)
for (i = 0; i < FUSE_OP_HIGH; i++)
fuse_ops[i] = fuse_enosys;
fuse_ops[FUSE_INIT] = fuse_init;
fuse_ops[FUSE_DESTROY] = fuse_destroy;
@ -3496,9 +3611,6 @@ struct volume_options options[] = {
{ .key = {"direct-io-mode"},
.type = GF_OPTION_TYPE_BOOL
},
{ .key = {"macfuse-local"},
.type = GF_OPTION_TYPE_BOOL
},
{ .key = {"mountpoint", "mount-point"},
.type = GF_OPTION_TYPE_PATH
},

View File

@ -884,7 +884,7 @@ out:
int32_t
bdb_dirent_size (DBT *key)
{
return ALIGN (24 /* FIX MEEEE!!! */ + key->size);
return GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + key->size);
}