summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorCsaba Henk <csaba@gluster.com>2010-05-17 07:06:58 +0000
committerAnand V. Avati <avati@dev.gluster.com>2010-05-21 00:31:41 -0700
commit18d982e6d0d330af8ccd2b12252ae29fe0932023 (patch)
treef13c3ac28b549d5bf343715de32d16b28d93ab3c /contrib
parent86ee9d3e144d2371e5ae7edf663916b8da6d2616 (diff)
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
Diffstat (limited to 'contrib')
-rw-r--r--contrib/fuse-include/fuse_kernel_macfuse.h439
-rw-r--r--contrib/macfuse/COPYING.txt128
-rw-r--r--contrib/macfuse/fuse_ioctl.h64
-rw-r--r--contrib/macfuse/fuse_param.h147
-rw-r--r--contrib/macfuse/mount_darwin.c355
5 files changed, 1133 insertions, 0 deletions
diff --git a/contrib/fuse-include/fuse_kernel_macfuse.h b/contrib/fuse-include/fuse_kernel_macfuse.h
new file mode 100644
index 000000000..3fbf24f70
--- /dev/null
+++ b/contrib/fuse-include/fuse_kernel_macfuse.h
@@ -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)
diff --git a/contrib/macfuse/COPYING.txt b/contrib/macfuse/COPYING.txt
new file mode 100644
index 000000000..3f89bb08d
--- /dev/null
+++ b/contrib/macfuse/COPYING.txt
@@ -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/
diff --git a/contrib/macfuse/fuse_ioctl.h b/contrib/macfuse/fuse_ioctl.h
new file mode 100644
index 000000000..054968cb1
--- /dev/null
+++ b/contrib/macfuse/fuse_ioctl.h
@@ -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_ */
diff --git a/contrib/macfuse/fuse_param.h b/contrib/macfuse/fuse_param.h
new file mode 100644
index 000000000..81d753c6c
--- /dev/null
+++ b/contrib/macfuse/fuse_param.h
@@ -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_ */
diff --git a/contrib/macfuse/mount_darwin.c b/contrib/macfuse/mount_darwin.c
new file mode 100644
index 000000000..f7fcc2a70
--- /dev/null
+++ b/contrib/macfuse/mount_darwin.c
@@ -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;
+}