summaryrefslogtreecommitdiffstats
path: root/sys/xfs
diff options
context:
space:
mode:
authorart <art@openbsd.org>1999-04-30 01:58:59 +0000
committerart <art@openbsd.org>1999-04-30 01:58:59 +0000
commite09bdadb1962e70cc6e11d77adfe7d6a2dbb2c7e (patch)
treebd2fe53f0944ae30b5bb7ce3422bedb4455e3f7d /sys/xfs
parentmore cruft (diff)
downloadwireguard-openbsd-e09bdadb1962e70cc6e11d77adfe7d6a2dbb2c7e.tar.xz
wireguard-openbsd-e09bdadb1962e70cc6e11d77adfe7d6a2dbb2c7e.zip
upgrade Arla to fresher code. Too many new features and bugfixes.
Diffstat (limited to 'sys/xfs')
-rw-r--r--sys/xfs/nxfs.h41
-rw-r--r--sys/xfs/xfs_attr.h35
-rw-r--r--sys/xfs/xfs_common-bsd.c65
-rw-r--r--sys/xfs/xfs_common.h28
-rw-r--r--sys/xfs/xfs_config.h846
-rw-r--r--sys/xfs/xfs_deb.c20
-rw-r--r--sys/xfs/xfs_deb.h36
-rw-r--r--sys/xfs/xfs_debug.h65
-rw-r--r--sys/xfs/xfs_dev-bsd.c226
-rw-r--r--sys/xfs/xfs_dev-common.c564
-rw-r--r--sys/xfs/xfs_dev.h139
-rw-r--r--sys/xfs/xfs_fs.h62
-rw-r--r--sys/xfs/xfs_global.h9
-rw-r--r--sys/xfs/xfs_locl.h178
-rw-r--r--sys/xfs/xfs_message.c310
-rw-r--r--sys/xfs/xfs_message.h299
-rw-r--r--sys/xfs/xfs_msg_locl.h65
-rw-r--r--sys/xfs/xfs_node-bsd.c590
-rw-r--r--sys/xfs/xfs_node.h81
-rw-r--r--sys/xfs/xfs_pioctl.h46
-rw-r--r--sys/xfs/xfs_syscalls-common.c477
-rw-r--r--sys/xfs/xfs_syscalls-dummy.c11
-rw-r--r--sys/xfs/xfs_syscalls.h61
-rw-r--r--sys/xfs/xfs_vfsops-bsd.c381
-rw-r--r--sys/xfs/xfs_vfsops-bsd.h89
-rw-r--r--sys/xfs/xfs_vfsops-common.c269
-rw-r--r--sys/xfs/xfs_vfsops-openbsd.c185
-rw-r--r--sys/xfs/xfs_vfsops.h77
-rw-r--r--sys/xfs/xfs_vnodeops-bsd.c1030
-rw-r--r--sys/xfs/xfs_vnodeops-common.c948
-rw-r--r--sys/xfs/xfs_vnodeops.h195
-rw-r--r--sys/xfs/xfs_vopdefs.h43
32 files changed, 7018 insertions, 453 deletions
diff --git a/sys/xfs/nxfs.h b/sys/xfs/nxfs.h
index 5a584697642..1083484d7c8 100644
--- a/sys/xfs/nxfs.h
+++ b/sys/xfs/nxfs.h
@@ -1,40 +1 @@
-/* $OpenBSD: nxfs.h,v 1.2 1998/08/30 17:35:41 art Exp $ */
-/*
- * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * 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.
- *
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Kungliga Tekniska
- * Högskolan and its contributors.
- *
- * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
- */
-
-#define NXFS 2
+#define NXFS 2
diff --git a/sys/xfs/xfs_attr.h b/sys/xfs/xfs_attr.h
index de66a2ee837..a1a921ea7f8 100644
--- a/sys/xfs/xfs_attr.h
+++ b/sys/xfs/xfs_attr.h
@@ -1,4 +1,3 @@
-/* $OpenBSD: xfs_attr.h,v 1.1 1998/08/31 05:13:21 art Exp $ */
/*
* Copyright (c) 1998 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
@@ -37,10 +36,10 @@
* SUCH DAMAGE.
*/
-/* $KTH: xfs_attr.h,v 1.7 1998/07/12 15:29:09 map Exp $ */
+/* $Id: xfs_attr.h,v 1.2 1999/04/30 01:58:59 art Exp $ */
-#ifndef _SYS_XFS_ATTR_H_
-#define _SYS_XFS_ATTR_H_
+#ifndef _XFS_ATTR_H
+#define _XFS_ATTR_H
#define XA_V_NONE 0
#define XA_V_MODE (1 << 0)
@@ -55,11 +54,11 @@
#define XA_V_TYPE (1 << 9)
enum xfs_file_type { XFS_FILE_NON, XFS_FILE_REG, XFS_FILE_DIR,
- XFS_FILE_BLK, XFS_FILE_CHR, XFS_FILE_LNK,
- XFS_FILE_SOCK, XFS_FILE_FIFO, XFS_FILE_BAD };
+ XFS_FILE_BLK, XFS_FILE_CHR, XFS_FILE_LNK,
+ XFS_FILE_SOCK, XFS_FILE_FIFO, XFS_FILE_BAD };
#define XA_CLEAR(xa_p) \
- ((xa_p)->valid = XA_V_NONE)
+ ((xa_p)->valid = XA_V_NONE)
#define XA_SET_MODE(xa_p, value) \
(((xa_p)->valid) |= XA_V_MODE, ((xa_p)->xa_mode) = value)
#define XA_SET_NLINK(xa_p, value) \
@@ -117,17 +116,17 @@ typedef gid_t __kernel_gid_t;
#endif
struct xfs_attr {
- u_int32_t valid;
- __kernel_mode_t xa_mode;
- __kernel_nlink_t xa_nlink;
- __kernel_off_t xa_size;
- __kernel_uid_t xa_uid;
- __kernel_gid_t xa_gid;
- time_t xa_atime;
- time_t xa_mtime;
- time_t xa_ctime;
- u_int32_t xa_fileid;
- enum xfs_file_type xa_type;
+ u_int32_t valid;
+ __kernel_mode_t xa_mode;
+ __kernel_nlink_t xa_nlink;
+ __kernel_off_t xa_size;
+ __kernel_uid_t xa_uid;
+ __kernel_gid_t xa_gid;
+ time_t xa_atime;
+ time_t xa_mtime;
+ time_t xa_ctime;
+ u_int32_t xa_fileid;
+ enum xfs_file_type xa_type;
};
#endif /* _XFS_ATTR_H */
diff --git a/sys/xfs/xfs_common-bsd.c b/sys/xfs/xfs_common-bsd.c
new file mode 100644
index 00000000000..a157cbfd939
--- /dev/null
+++ b/sys/xfs/xfs_common-bsd.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef XFS_DEBUG
+#include <xfs/xfs_locl.h>
+#include <xfs/xfs_common.h>
+#include <xfs/xfs_deb.h>
+
+RCSID("$Id: xfs_common-bsd.c,v 1.1 1999/04/30 01:58:59 art Exp $");
+
+static u_int xfs_allocs;
+static u_int xfs_frees;
+
+void *
+xfs_alloc(u_int size)
+{
+ xfs_allocs++;
+ XFSDEB(XDEBMEM, ("xfs_alloc: xfs_allocs - xfs_frees %d\n",
+ xfs_allocs - xfs_frees));
+
+ return malloc(size, M_TEMP, M_WAITOK); /* What kind? */
+}
+
+void
+xfs_free(void *ptr, u_int size)
+{
+ xfs_frees++;
+ free(ptr, M_TEMP);
+}
+#endif
diff --git a/sys/xfs/xfs_common.h b/sys/xfs/xfs_common.h
index ea927f3858a..4193434a3e6 100644
--- a/sys/xfs/xfs_common.h
+++ b/sys/xfs/xfs_common.h
@@ -1,6 +1,5 @@
-/* $OpenBSD: xfs_common.h,v 1.2 1998/08/31 05:13:21 art Exp $ */
/*
- * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -37,20 +36,21 @@
* SUCH DAMAGE.
*/
-/* $KTH: xfs_common.h,v 1.5 1998/07/13 20:36:36 art Exp $ */
+/* $Id: xfs_common.h,v 1.3 1999/04/30 01:58:59 art Exp $ */
-#ifndef _XFS_XFS_COMMON_H_
-#define _XFS_XFS_COMMON_H_
+#ifndef _xfs_common_h
+#define _xfs_common_h
-#include <sys/malloc.h>
-
-#ifdef DEBUG
-void *xfs_alloc __P((u_int size));
-void xfs_free __P((void *, u_int size));
+#ifdef XFS_DEBUG
+void *xfs_alloc(u_int size);
+void xfs_free(void *, u_int size);
+#else
+#ifdef __osf__
+#define xfs_alloc(a) malloc((a), BUCKETINDEX(a), M_TEMP, M_WAITOK)
#else
-#define xfs_alloc(s) malloc((s), M_TEMP, M_WAITOK) /* XXX - what kind? */
-#define xfs_free(p, s) free((p), M_TEMP)
+#define xfs_alloc(a) malloc((a), M_TEMP, M_WAITOK)
#endif
+#define xfs_free(a, size) free(a, M_TEMP)
+#endif /* XFS_DEBUG */
-#define RCSID(x)
-#endif
+#endif /* _xfs_common_h */
diff --git a/sys/xfs/xfs_config.h b/sys/xfs/xfs_config.h
new file mode 100644
index 00000000000..aa8a53346de
--- /dev/null
+++ b/sys/xfs/xfs_config.h
@@ -0,0 +1,846 @@
+/* include/config.h. Generated automatically by configure. */
+/* include/config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if you have a working `mmap' system call. */
+#define HAVE_MMAP 1
+
+/* Define as __inline if that's what the C compiler calls it. */
+/* #undef inline */
+
+/* Define as the return type of signal handlers (int or void). */
+#define RETSIGTYPE void
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define if the X Window System is missing or not being used. */
+/* #undef X_DISPLAY_MISSING */
+
+/* Define this if we can include both sys/dir.h and dirent.h */
+#define USE_SYS_DIR_H 1
+
+/* Define this if RETSIGTYPE == void */
+/* #undef VOID_RETSIGTYPE */
+
+/* Define this if struct winsize is declared in sys/termios.h */
+#define HAVE_STRUCT_WINSIZE 1
+
+/* Define this if struct msghdr is declared in sys/socket.h */
+#define HAVE_STRUCT_MSGHDR 1
+
+/* Define this if struct iovec is declared in sys/uio.h */
+#define HAVE_STRUCT_IOVEC 1
+
+/* Define this if struct winsize have ws_xpixel */
+#define HAVE_WS_XPIXEL 1
+
+/* Define this if struct winsize have ws_ypixel */
+#define HAVE_WS_YPIXEL 1
+
+/* Define this if `struct sockaddr' includes sa_len */
+#define SOCKADDR_HAS_SA_LEN 1
+
+/* define if the system is missing a prototype for strtok_r() */
+/* #undef NEED_STRTOK_R_PROTO */
+
+/* define if you have h_errno */
+#define HAVE_H_ERRNO 1
+
+/* define if you have h_errlist but not hstrerror */
+#define HAVE_H_ERRLIST 1
+
+/* define if you have h_nerr but not hstrerror */
+#define HAVE_H_NERR 1
+
+/* define if your system has a declaration for h_errlist */
+/* #undef HAVE_H_ERRLIST_DECLARATION */
+
+/* define if your system has a declaration for h_nerr */
+/* #undef HAVE_H_NERR_DECLARATION */
+
+/* define if your system has a declaration for h_errno */
+#define HAVE_H_ERRNO_DECLARATION 1
+
+/* define if your system has optreset */
+#define HAVE_OPTRESET 1
+
+/* define if your system has a declaration for optreset */
+#define HAVE_OPTRESET_DECLARATION 1
+
+/* define if your compiler has __FUNCTION__ */
+#define HAVE___FUNCTION__ 1
+
+/* define if your compiler has __attribute__ */
+#define HAVE___ATTRIBUTE__ 1
+
+/* Check if select need a prototype */
+/* #undef NEED_SELECT_PROTO */
+
+/* Define if you have the FOUR_ARGUMENT_VFS_BUSY function. */
+#define HAVE_FOUR_ARGUMENT_VFS_BUSY 1
+
+/* Define if you have the FOUR_ARGUMENT_VFS_OBJECT_CREATE function. */
+/* #undef HAVE_FOUR_ARGUMENT_VFS_OBJECT_CREATE */
+
+/* Define if you have the ONE_ARGUMENT_VOP_LOCK function. */
+/* #undef HAVE_ONE_ARGUMENT_VOP_LOCK */
+
+/* Define if you have the THREE_ARGUMENT_VFS_BUSY function. */
+/* #undef HAVE_THREE_ARGUMENT_VFS_BUSY */
+
+/* Define if you have the THREE_ARGUMENT_VGET function. */
+#define HAVE_THREE_ARGUMENT_VGET 1
+
+/* Define if you have the THREE_ARGUMENT_VOP_LOCK function. */
+#define HAVE_THREE_ARGUMENT_VOP_LOCK 1
+
+/* Define if you have the TWO_ARGUMENT_VFS_GETNEWFSID function. */
+/* #undef HAVE_TWO_ARGUMENT_VFS_GETNEWFSID */
+
+/* Define if you have the TWO_ARGUMENT_VGET function. */
+/* #undef HAVE_TWO_ARGUMENT_VGET */
+
+/* Define if you have the TWO_ARGUMENT_VOP_LOCK function. */
+/* #undef HAVE_TWO_ARGUMENT_VOP_LOCK */
+
+/* Define if you have the asnprintf function. */
+/* #undef HAVE_ASNPRINTF */
+
+/* Define if you have the asprintf function. */
+#define HAVE_ASPRINTF 1
+
+/* Define if you have the chown function. */
+#define HAVE_CHOWN 1
+
+/* Define if you have the daemon function. */
+#define HAVE_DAEMON 1
+
+/* Define if you have the dbm_firstkey function. */
+#define HAVE_DBM_FIRSTKEY 1
+
+/* Define if you have the dn_expand function. */
+#define HAVE_DN_EXPAND 1
+
+/* Define if you have the el_init function. */
+#define HAVE_EL_INIT 1
+
+/* Define if you have the err function. */
+#define HAVE_ERR 1
+
+/* Define if you have the errx function. */
+#define HAVE_ERRX 1
+
+/* Define if you have the fchown function. */
+#define HAVE_FCHOWN 1
+
+/* Define if you have the fcntl function. */
+#define HAVE_FCNTL 1
+
+/* Define if you have the flock function. */
+#define HAVE_FLOCK 1
+
+/* Define if you have the getcwd function. */
+#define HAVE_GETCWD 1
+
+/* Define if you have the getdtablesize function. */
+#define HAVE_GETDTABLESIZE 1
+
+/* Define if you have the gethostbyname function. */
+#define HAVE_GETHOSTBYNAME 1
+
+/* Define if you have the getopt function. */
+#define HAVE_GETOPT 1
+
+/* Define if you have the getpagesize function. */
+#define HAVE_GETPAGESIZE 1
+
+/* Define if you have the getrlimit function. */
+#define HAVE_GETRLIMIT 1
+
+/* Define if you have the getspnam function. */
+/* #undef HAVE_GETSPNAM */
+
+/* Define if you have the getspuid function. */
+/* #undef HAVE_GETSPUID */
+
+/* Define if you have the getusershell function. */
+#define HAVE_GETUSERSHELL 1
+
+/* Define if you have the getvfsbyname function. */
+/* #undef HAVE_GETVFSBYNAME */
+
+/* Define if you have the hstrerror function. */
+#define HAVE_HSTRERROR 1
+
+/* Define if you have the inet_aton function. */
+#define HAVE_INET_ATON 1
+
+/* Define if you have the initgroups function. */
+#define HAVE_INITGROUPS 1
+
+/* Define if you have the kvm_nlist function. */
+#define HAVE_KVM_NLIST 1
+
+/* Define if you have the kvm_open function. */
+#define HAVE_KVM_OPEN 1
+
+/* Define if you have the lstat function. */
+#define HAVE_LSTAT 1
+
+/* Define if you have the memmove function. */
+#define HAVE_MEMMOVE 1
+
+/* Define if you have the mkstemp function. */
+#define HAVE_MKSTEMP 1
+
+/* Define if you have the mktime function. */
+#define HAVE_MKTIME 1
+
+/* Define if you have the putenv function. */
+#define HAVE_PUTENV 1
+
+/* Define if you have the rcmd function. */
+#define HAVE_RCMD 1
+
+/* Define if you have the readline function. */
+#define HAVE_READLINE 1
+
+/* Define if you have the readv function. */
+#define HAVE_READV 1
+
+/* Define if you have the recvmsg function. */
+#define HAVE_RECVMSG 1
+
+/* Define if you have the res_search function. */
+#define HAVE_RES_SEARCH 1
+
+/* Define if you have the sendmsg function. */
+#define HAVE_SENDMSG 1
+
+/* Define if you have the setegid function. */
+#define HAVE_SETEGID 1
+
+/* Define if you have the setenv function. */
+#define HAVE_SETENV 1
+
+/* Define if you have the seteuid function. */
+#define HAVE_SETEUID 1
+
+/* Define if you have the setregid function. */
+#define HAVE_SETREGID 1
+
+/* Define if you have the setresuid function. */
+/* #undef HAVE_SETRESUID */
+
+/* Define if you have the setreuid function. */
+#define HAVE_SETREUID 1
+
+/* Define if you have the setsid function. */
+#define HAVE_SETSID 1
+
+/* Define if you have the setsockopt function. */
+#define HAVE_SETSOCKOPT 1
+
+/* Define if you have the snprintf function. */
+#define HAVE_SNPRINTF 1
+
+/* Define if you have the socket function. */
+#define HAVE_SOCKET 1
+
+/* Define if you have the strcasecmp function. */
+#define HAVE_STRCASECMP 1
+
+/* Define if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define if you have the strerror function. */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strftime function. */
+#define HAVE_STRFTIME 1
+
+/* Define if you have the strlwr function. */
+/* #undef HAVE_STRLWR */
+
+/* Define if you have the strnlen function. */
+/* #undef HAVE_STRNLEN */
+
+/* Define if you have the strsep function. */
+#define HAVE_STRSEP 1
+
+/* Define if you have the strtok_r function. */
+/* #undef HAVE_STRTOK_R */
+
+/* Define if you have the strupr function. */
+/* #undef HAVE_STRUPR */
+
+/* Define if you have the sysconf function. */
+#define HAVE_SYSCONF 1
+
+/* Define if you have the sysctl function. */
+#define HAVE_SYSCTL 1
+
+/* Define if you have the syslog function. */
+#define HAVE_SYSLOG 1
+
+/* Define if you have the tgetent function. */
+#define HAVE_TGETENT 1
+
+/* Define if you have the thr_yield function. */
+/* #undef HAVE_THR_YIELD */
+
+/* Define if you have the unsetenv function. */
+#define HAVE_UNSETENV 1
+
+/* Define if you have the vasnprintf function. */
+/* #undef HAVE_VASNPRINTF */
+
+/* Define if you have the vasprintf function. */
+#define HAVE_VASPRINTF 1
+
+/* Define if you have the verr function. */
+#define HAVE_VERR 1
+
+/* Define if you have the verrx function. */
+#define HAVE_VERRX 1
+
+/* Define if you have the vfsisloadable function. */
+/* #undef HAVE_VFSISLOADABLE */
+
+/* Define if you have the vfsload function. */
+/* #undef HAVE_VFSLOAD */
+
+/* Define if you have the vsnprintf function. */
+#define HAVE_VSNPRINTF 1
+
+/* Define if you have the vsyslog function. */
+#define HAVE_VSYSLOG 1
+
+/* Define if you have the vwarn function. */
+#define HAVE_VWARN 1
+
+/* Define if you have the vwarnx function. */
+#define HAVE_VWARNX 1
+
+/* Define if you have the warn function. */
+#define HAVE_WARN 1
+
+/* Define if you have the warnx function. */
+#define HAVE_WARNX 1
+
+/* Define if you have the writev function. */
+#define HAVE_WRITEV 1
+
+/* Define if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define if you have the <arpa/nameser.h> header file. */
+#define HAVE_ARPA_NAMESER_H 1
+
+/* Define if you have the <asm/smp_lock.h> header file. */
+/* #undef HAVE_ASM_SMP_LOCK_H */
+
+/* Define if you have the <asm/smplock.h> header file. */
+/* #undef HAVE_ASM_SMPLOCK_H */
+
+/* Define if you have the <crypt.h> header file. */
+/* #undef HAVE_CRYPT_H */
+
+/* Define if you have the <dbm.h> header file. */
+#define HAVE_DBM_H 1
+
+/* Define if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <grp.h> header file. */
+#define HAVE_GRP_H 1
+
+/* Define if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define if you have the <ktypes.h> header file. */
+/* #undef HAVE_KTYPES_H */
+
+/* Define if you have the <kvm.h> header file. */
+#define HAVE_KVM_H 1
+
+/* Define if you have the <libelf/nlist.h> header file. */
+/* #undef HAVE_LIBELF_NLIST_H */
+
+/* Define if you have the <linux/devfs_fs.h> header file. */
+/* #undef HAVE_LINUX_DEVFS_FS_H */
+
+/* Define if you have the <linux/modversions.h> header file. */
+/* #undef HAVE_LINUX_MODVERSIONS_H */
+
+/* Define if you have the <linux/types.h> header file. */
+/* #undef HAVE_LINUX_TYPES_H */
+
+/* Define if you have the <machine/alpha/asm.h> header file. */
+/* #undef HAVE_MACHINE_ALPHA_ASM_H */
+
+/* Define if you have the <machine/asm.h> header file. */
+#define HAVE_MACHINE_ASM_H 1
+
+/* Define if you have the <machine/regdef.h> header file. */
+/* #undef HAVE_MACHINE_REGDEF_H */
+
+/* Define if you have the <miscfs/genfs/genfs.h> header file. */
+/* #undef HAVE_MISCFS_GENFS_GENFS_H */
+
+/* Define if you have the <ndbm.h> header file. */
+#define HAVE_NDBM_H 1
+
+/* Define if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define if you have the <netinet/in6.h> header file. */
+/* #undef HAVE_NETINET_IN6_H */
+
+/* Define if you have the <netinet/in6_machtypes.h> header file. */
+/* #undef HAVE_NETINET_IN6_MACHTYPES_H */
+
+/* Define if you have the <netinet6/in6.h> header file. */
+/* #undef HAVE_NETINET6_IN6_H */
+
+/* Define if you have the <nlist.h> header file. */
+#define HAVE_NLIST_H 1
+
+/* Define if you have the <paths.h> header file. */
+#define HAVE_PATHS_H 1
+
+/* Define if you have the <pwd.h> header file. */
+#define HAVE_PWD_H 1
+
+/* Define if you have the <regdef.h> header file. */
+/* #undef HAVE_REGDEF_H */
+
+/* Define if you have the <resolv.h> header file. */
+#define HAVE_RESOLV_H 1
+
+/* Define if you have the <rpcsvc/dbm.h> header file. */
+/* #undef HAVE_RPCSVC_DBM_H */
+
+/* Define if you have the <shadow.h> header file. */
+/* #undef HAVE_SHADOW_H */
+
+/* Define if you have the <sys/bitypes.h> header file. */
+/* #undef HAVE_SYS_BITYPES_H */
+
+/* Define if you have the <sys/cdefs.h> header file. */
+#define HAVE_SYS_CDEFS_H 1
+
+/* Define if you have the <sys/filedesc.h> header file. */
+#define HAVE_SYS_FILEDESC_H 1
+
+/* Define if you have the <sys/ioccom.h> header file. */
+#define HAVE_SYS_IOCCOM_H 1
+
+/* Define if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define if you have the <sys/lkm.h> header file. */
+#define HAVE_SYS_LKM_H 1
+
+/* Define if you have the <sys/mman.h> header file. */
+#define HAVE_SYS_MMAN_H 1
+
+/* Define if you have the <sys/module.h> header file. */
+/* #undef HAVE_SYS_MODULE_H */
+
+/* Define if you have the <sys/mount.h> header file. */
+#define HAVE_SYS_MOUNT_H 1
+
+/* Define if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define if you have the <sys/poll.h> header file. */
+#define HAVE_SYS_POLL_H 1
+
+/* Define if you have the <sys/proc.h> header file. */
+#define HAVE_SYS_PROC_H 1
+
+/* Define if you have the <sys/queue.h> header file. */
+#define HAVE_SYS_QUEUE_H 1
+
+/* Define if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define if you have the <sys/sockio.h> header file. */
+#define HAVE_SYS_SOCKIO_H 1
+
+/* Define if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define if you have the <sys/syscallargs.h> header file. */
+#define HAVE_SYS_SYSCALLARGS_H 1
+
+/* Define if you have the <sys/sysconfig.h> header file. */
+/* #undef HAVE_SYS_SYSCONFIG_H */
+
+/* Define if you have the <sys/sysctl.h> header file. */
+#define HAVE_SYS_SYSCTL_H 1
+
+/* Define if you have the <sys/sysent.h> header file. */
+/* #undef HAVE_SYS_SYSENT_H */
+
+/* Define if you have the <sys/sysproto.h> header file. */
+/* #undef HAVE_SYS_SYSPROTO_H */
+
+/* Define if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define if you have the <sys/tty.h> header file. */
+#define HAVE_SYS_TTY_H 1
+
+/* Define if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define if you have the <sys/user.h> header file. */
+#define HAVE_SYS_USER_H 1
+
+/* Define if you have the <sys/utsname.h> header file. */
+#define HAVE_SYS_UTSNAME_H 1
+
+/* Define if you have the <sys/vfs.h> header file. */
+/* #undef HAVE_SYS_VFS_H */
+
+/* Define if you have the <syslog.h> header file. */
+#define HAVE_SYSLOG_H 1
+
+/* Define if you have the <termios.h> header file. */
+#define HAVE_TERMIOS_H 1
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the <vm/vm.h> header file. */
+#define HAVE_VM_VM_H 1
+
+/* Define if you have the <vm/vm_extern.h> header file. */
+#define HAVE_VM_VM_EXTERN_H 1
+
+/* Define if you have the <vm/vm_object.h> header file. */
+#define HAVE_VM_VM_OBJECT_H 1
+
+/* Define if you have the <vm/vm_pager.h> header file. */
+#define HAVE_VM_VM_PAGER_H 1
+
+/* Define if you have the <vm/vm_zone.h> header file. */
+/* #undef HAVE_VM_VM_ZONE_H */
+
+/* Define if you have the <vm/vnode_pager.h> header file. */
+#define HAVE_VM_VNODE_PAGER_H 1
+
+/* Define if you have the curses library (-lcurses). */
+/* #undef HAVE_LIBCURSES */
+
+/* Define if you have the db library (-ldb). */
+/* #undef HAVE_LIBDB */
+
+/* Define if you have the edit library (-ledit). */
+#define HAVE_LIBEDIT 1
+
+/* Define if you have the gdbm library (-lgdbm). */
+/* #undef HAVE_LIBGDBM */
+
+/* Define if you have the kvm library (-lkvm). */
+#define HAVE_LIBKVM 1
+
+/* Define if you have the ndbm library (-lndbm). */
+/* #undef HAVE_LIBNDBM */
+
+/* Define if you have the nsl library (-lnsl). */
+/* #undef HAVE_LIBNSL */
+
+/* Define if you have the readline library (-lreadline). */
+/* #undef HAVE_LIBREADLINE */
+
+/* Define if you have the resolv library (-lresolv). */
+/* #undef HAVE_LIBRESOLV */
+
+/* Define if you have the socket library (-lsocket). */
+/* #undef HAVE_LIBSOCKET */
+
+/* Define if you have the syslog library (-lsyslog). */
+/* #undef HAVE_LIBSYSLOG */
+
+/* Define if you have the termcap library (-ltermcap). */
+#define HAVE_LIBTERMCAP 1
+
+#define HAVE_INT8_T 1
+#define HAVE_INT16_T 1
+#define HAVE_INT32_T 1
+#define HAVE_INT64_T 1
+#define HAVE_U_INT8_T 1
+#define HAVE_U_INT16_T 1
+#define HAVE_U_INT32_T 1
+#define HAVE_U_INT64_T 1
+/* #undef HAVE_BOOL */
+#define HAVE_SSIZE_T 1
+#define HAVE_REGISTER_T 1
+/* #undef HAVE_INT32 */
+/* #undef HAVE_U_INT32 */
+/* #undef HAVE_INTPTR_T */
+
+#define EFF_NTOHL ntohl
+
+/* RCSID */
+#define RCSID(msg) \
+static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
+
+#define VERSION "0.24pre"
+#define PACKAGE "arla"
+
+/* Check for posix signals */
+#define HAVE_POSIX_SIGNALS 1
+
+#define HAVE_READLINE 1
+
+/* prefix for /dev/fd */
+/* #undef DEV_FD_PREFIX */
+
+/* does the system have /dev/fd? */
+/* #undef HAVE_DEV_FD */
+
+/* we always have stds.h */
+#define HAVE_STDS_H
+
+/* We have krb_principal from kth-krb ? */
+#define HAVE_KRB_PRINCIPAL 1
+
+/* Define if you have a krb_get_err_text (otherwise, you should really
+ get more modern kerberos code) */
+#define HAVE_KRB_GET_ERR_TEXT 1
+
+/* If we have _res */
+/* #undef HAVE__RES */
+
+/* Define if you have kerberos */
+#define KERBEROS 1
+
+/* Define if your kernel has a vop_nolock */
+/* #undef HAVE_KERNEL_VOP_NOLOCK */
+
+/* Define if your kernel has a vop_nounlock */
+/* #undef HAVE_KERNEL_VOP_NOUNLOCK */
+
+/* Define if your kernel has a vop_noislocked */
+/* #undef HAVE_KERNEL_VOP_NOISLOCKED */
+
+/* Define if your kernel has a vop_stdnolock */
+/* #undef HAVE_KERNEL_VOP_STDLOCK */
+
+/* Define if your kernel has a vop_stdnounlock */
+/* #undef HAVE_KERNEL_VOP_STDUNLOCK */
+
+/* Define if your kernel has a vop_stdnoislocked */
+/* #undef HAVE_KERNEL_VOP_STDISLOCKED */
+
+/* Define if your kernel has a vop_revoke */
+/* #undef HAVE_KERNEL_VOP_REVOKE */
+
+/* Define if your kernel has a genfs_nolock */
+/* #undef HAVE_KERNEL_GENFS_NOLOCK */
+
+/* Define if your kernel has a genfs_nounlock */
+/* #undef HAVE_KERNEL_GENFS_NOUNLOCK */
+
+/* Define if your kernel has a genfs_noislocked */
+/* #undef HAVE_KERNEL_GENFS_NOISLOCKED */
+
+/* Define if your kernel has a genfs_revoke */
+/* #undef HAVE_KERNEL_GENFS_REVOKE */
+
+/* Define if your kernel has a vfs_opv_init */
+#define HAVE_KERNEL_VFS_OPV_INIT 1
+
+/* Define if your kernel has a vfs_opv_init_default */
+#define HAVE_KERNEL_VFS_OPV_INIT_DEFAULT 1
+
+/* Define if your kernel has a vfs_opv_init_explicit */
+#define HAVE_KERNEL_VFS_OPV_INIT_EXPLICIT 1
+
+/* Define if your kernel has a vfs_add_vnodeops */
+/* #undef HAVE_KERNEL_VFS_ADD_VNODEOPS */
+
+/* Define if your kernel has a vfs_attach */
+/* #undef HAVE_KERNEL_VFS_ATTACH */
+
+/* Define if your kernel has a vfs_register */
+#define HAVE_KERNEL_VFS_REGISTER 1
+
+/* Define if your kernel has a vfs_getnewfsid */
+#define HAVE_KERNEL_VFS_GETNEWFSID 1
+
+/* Define if your kernel has a vfs_getvfs */
+#define HAVE_KERNEL_VFS_GETVFS 1
+
+/* Define if your kernel has a vfs_object_create */
+/* #undef HAVE_KERNEL_VFS_OBJECT_CREATE */
+
+/* Define if your kernel has a zfreei */
+/* #undef HAVE_KERNEL_ZFREEI */
+
+/* Define if your kernel has a vfs_cache_lookup */
+/* #undef HAVE_KERNEL_VFS_CACHE_LOOKUP */
+
+/* Define if your kernel has a vnode_pager_generic_putpages */
+/* #undef HAVE_KERNEL_VNODE_PAGER_GENERIC_PUTPAGES */
+
+/* Define if your kernel has a vnode_pager_generic_getpages */
+/* #undef HAVE_KERNEL_VNODE_PAGER_GENERIC_GETPAGES */
+
+/* Define if your kernel has a vnode_pager_setsize */
+#define HAVE_KERNEL_VNODE_PAGER_SETSIZE 1
+
+/* Define if your kernel has a doforce */
+#define HAVE_KERNEL_DOFORCE 1
+
+/* Define if your struct dirent has a field d_type */
+#define HAVE_STRUCT_DIRENT_D_TYPE 1
+
+/* Define if your struct vfsconf has a field vfc_refcount */
+#define HAVE_STRUCT_VFSCONF_VFC_REFCOUNT 1
+
+/* Define if your struct vfsconf has a field vfc_mountroot */
+/* #undef HAVE_STRUCT_VFSCONF_VFC_MOUNTROOT */
+
+/* Define if your struct uio has a field uio_procp */
+#define HAVE_STRUCT_UIO_UIO_PROCP 1
+
+/* Define if your struct vfsops has a field vfs_opv_descs */
+/* #undef HAVE_STRUCT_VFSOPS_VFS_OPV_DESCS */
+
+/* Define if your struct vfsops has a field vfs_name */
+/* #undef HAVE_STRUCT_VFSOPS_VFS_NAME */
+
+/* Define if your struct vfsops has a field vfs_oid */
+/* #undef HAVE_STRUCT_VFSOPS_VFS_OID */
+
+/* Define if your struct vfsops has a field vfs_checkexp */
+/* #undef HAVE_STRUCT_VFSOPS_VFS_CHECKEXP */
+
+/* Define if your struct vfsops has a field vfs_uninit */
+/* #undef HAVE_STRUCT_VFSOPS_VFS_UNINIT */
+
+/* Define if you want to use mmap:ed time */
+/* #undef USE_MMAPTIME */
+
+/* Define if your hstrerror needs const like SunOS 5.6 */
+#define NEED_HSTRERROR_CONST 1
+
+/* Define if your hstrerror need proto */
+/* #undef NEED_HSTRERROR_PROTO */
+
+/* define if the system is missing a prototype for inet_aton() */
+/* #undef NEED_INET_ATON_PROTO */
+
+/* Define if you have gnu libc */
+/* #undef HAVE_GLIBC */
+
+/* Define this if `struct sockaddr' includes sa_len */
+#define SOCKADDR_HAS_SA_LEN 1
+
+/* Define this if htnol is broken, but can be fixed with define magic */
+/* #undef HAVE_REPAIRABLE_HTONL */
+
+/* Define this if struct ViceIoctl is defined by linux/fs.h */
+/* #undef HAVE_STRUCT_VICEIOCTL_IN */
+
+/* Linux kernel types */
+/* #undef HAVE_LINUX_KERNEL_INT8_T */
+/* #undef HAVE_LINUX_KERNEL_INT16_T */
+/* #undef HAVE_LINUX_KERNEL_INT32_T */
+/* #undef HAVE_LINUX_KERNEL_INT64_T */
+/* #undef HAVE_LINUX_KERNEL_U_INT8_T */
+/* #undef HAVE_LINUX_KERNEL_U_INT16_T */
+/* #undef HAVE_LINUX_KERNEL_U_INT32_T */
+/* #undef HAVE_LINUX_KERNEL_U_INT64_T */
+
+/* Define this if you have a struct new_stat */
+/* #undef HAVE_STRUCT_NEW_STAT */
+
+/* Define this if you have a type vop_t */
+/* #undef HAVE_VOP_T */
+
+/* Define this is you have a vfssw */
+/* #undef HAVE_VFSSW */
+
+/* Define this if struct mount have mnt_syncer */
+#define HAVE_STRUCT_MOUNT_MNT_SYNCER 1
+
+/* Define this if struct proc have p_sigmask */
+#define HAVE_STRUCT_PROC_P_SIGMASK 1
+
+/* Define this if you have struct a_flags instead of a_waitfor in vop_fseek*/
+/* #undef HAVE_STRUCT_VOP_FSYNC_ARGS_A_FLAGS */
+
+/* Define this if struct proc have p_retval */
+/* #undef HAVE_STRUCT_PROC_P_RETVAL */
+
+/* Define this if struct file_operations has flush */
+/* #undef HAVE_STRUCT_FILE_OPERATIONS_FLUSH */
+
+/* Define this if the read_super superoperation takes the dir_d argument */
+/* #undef HAVE_READ_SUPER_FOUR_ARGS */
+
+/* Define this if the follow_link inode-operation takes the follow argument */
+/* #undef HAVE_FOLLOW_LINK_THREE_ARGS */
+
+/* Define this if your full_name_hash works with 8bit characters */
+/* #undef HAVE_FULL_NAME_HASH_8BIT */
+
+/* Define if your getvfsbyname takes two arguments */
+/* #undef HAVE_GETVFSBYNAME_TWO_ARGS */
+
+/* Define if you have DIRSIZ in <dirent.h> */
+/* #undef DIRSIZ_IN_DIRENT_H */
+
+/* Define if you have DIRSIZ in <sys/dir.h> */
+#define DIRSIZ_IN_SYS_DIR_H 1
+
+/* Define if you have GENERIC_DIRENT in <sys/dirent.h> */
+/* #undef GENERIC_DIRSIZ_IN_SYS_DIRENT_H */
+
+/* Define if running on Irix 6.4 or later */
+/* #undef IRIX_64 */
+
+/*
+ * Defintions that are ugly but needed to get all the symbols used
+ */
+
+/*
+ * Defining this enables lots of useful (and used) extensions on
+ * glibc-based systems such as Linux
+ */
+
+#define _GNU_SOURCE
+
+/*
+ * Defining this enables us to get the definition of `sigset_t' and
+ * other importatnt definitions on Solaris.
+ */
+
+#define __EXTENSIONS__
diff --git a/sys/xfs/xfs_deb.c b/sys/xfs/xfs_deb.c
index f1f259404bb..2e838360af7 100644
--- a/sys/xfs/xfs_deb.c
+++ b/sys/xfs/xfs_deb.c
@@ -1,6 +1,5 @@
-/* $OpenBSD: xfs_deb.c,v 1.1 1998/08/30 16:47:20 art Exp $ */
/*
- * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -38,15 +37,24 @@
*/
#include <xfs/xfs_deb.h>
+#include <xfs/xfs_debug.h>
-/* $KTH: xfs_deb.c,v 1.3 1998/03/20 21:02:32 art Exp $ */
+/* $Id: xfs_deb.c,v 1.2 1999/04/30 01:59:00 art Exp $ */
/* X is on */
#define X(y) y
/* and x is off */
#define x(y) 0
-int xfsdeb = (0
- |
- x(XDEBANY)
+unsigned int xfsdeb = (0 |
+ x(XDEBDEV) |
+ x(XDEBMSG) |
+ x(XDEBDNLC) |
+ x(XDEBNODE) |
+ x(XDEBVNOPS) |
+ x(XDEBVFOPS) |
+ x(XDEBLKM) |
+ x(XDEBSYS) |
+ x(XDEBMEM) |
+ 0
);
diff --git a/sys/xfs/xfs_deb.h b/sys/xfs/xfs_deb.h
index cfec18d92af..dcfb21f97d9 100644
--- a/sys/xfs/xfs_deb.h
+++ b/sys/xfs/xfs_deb.h
@@ -1,4 +1,3 @@
-/* $OpenBSD: xfs_deb.h,v 1.2 1998/08/31 05:13:22 art Exp $ */
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
@@ -37,27 +36,30 @@
* SUCH DAMAGE.
*/
-#ifndef _XFS_XFS_DEB_H_
-#define _XFS_XFS_DEB_H_
+/* $Id: xfs_deb.h,v 1.3 1999/04/30 01:59:00 art Exp $ */
-/* masks */
-#define XDEBANY 0xffffffff
-#define XDEBDEV 0x00000001
-#define XDEBMSG 0x00000002
-#define XDEBDNLC 0x00000004
-#define XDEBNODE 0x00000008
-#define XDEBVNOPS 0x00000010
-#define XDEBVFOPS 0x00000020
-#define XDEBLKM 0x00000040
-#define XDEBSYS 0x00000080
-#define XDEBMEM 0x00000100
+#ifndef _xfs_deb_h
+#define _xfs_deb_h
-extern int xfsdeb;
+#include <xfs/xfs_debug.h>
-#ifdef DEBUG
+#define HAVE_XDEBDEV
+#define HAVE_XDEBMSG
+#define HAVE_XDEBDNLC
+#define HAVE_XDEBNODE
+#define HAVE_XDEBVNOPS
+#define HAVE_XDEBVFOPS
+#define HAVE_XDEBLKM
+#define HAVE_XDEBSYS
+#define HAVE_XDEBMEM
+#define HAVE_XDEBSYS
+
+extern unsigned int xfsdeb;
+
+#ifdef XFS_DEBUG
#define XFSDEB(mask, args) do { if (mask&xfsdeb) printf args; } while (0)
#else
#define XFSDEB(mask, args) do { ; } while (0)
#endif
-#endif
+#endif /* _xfs_deb_h */
diff --git a/sys/xfs/xfs_debug.h b/sys/xfs/xfs_debug.h
new file mode 100644
index 00000000000..04201a25b85
--- /dev/null
+++ b/sys/xfs/xfs_debug.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/* $Id: xfs_debug.h,v 1.1 1999/04/30 01:59:00 art Exp $ */
+
+#ifndef __XFS_DEBUG_H
+#define __XFS_DEBUG_H
+
+/*
+ * These are GLOBAL xfs debugging masks
+ *
+ * Define HAVE_XDEB in your local xfs_deb.h if
+ * you want your fs to handle the debugging flags.
+ */
+
+/* Masks for the debug macro */
+#define XDEBDEV 0x00000001 /* device handling */
+#define XDEBMSG 0x00000002 /* message sending */
+#define XDEBDNLC 0x00000004 /* name cache */
+#define XDEBNODE 0x00000008 /* xfs nodes */
+#define XDEBVNOPS 0x00000010 /* vnode operations */
+#define XDEBVFOPS 0x00000020 /* vfs operations */
+#define XDEBLKM 0x00000040 /* LKM handling */
+#define XDEBSYS 0x00000080 /* syscalls */
+#define XDEBMEM 0x00000100 /* memory allocation */
+#define XDEBREADDIR 0x00000200 /* readdir (linux) */
+#define XDEBLOCK 0x00000400 /* locking (linux) */
+#define XDEBCACHE 0x00000800 /* Cache handeling (linux) */
+
+#endif
diff --git a/sys/xfs/xfs_dev-bsd.c b/sys/xfs/xfs_dev-bsd.c
new file mode 100644
index 00000000000..b7c7ddf9f1d
--- /dev/null
+++ b/sys/xfs/xfs_dev-bsd.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include <xfs/xfs_locl.h>
+#include <xfs/xfs_message.h>
+#include <xfs/xfs_msg_locl.h>
+#include <xfs/xfs_fs.h>
+#include <xfs/xfs_dev.h>
+#include <xfs/xfs_deb.h>
+
+RCSID("$Id: xfs_dev-bsd.c,v 1.1 1999/04/30 01:59:00 art Exp $");
+
+int
+xfs_devopen(dev_t dev, int flag, int devtype, struct proc *proc)
+{
+ XFSDEB(XDEBDEV, ("xfsopen dev = %d.%d, flag = %d, devtype = %d\n",
+ major(dev), minor(dev), flag, devtype));
+ return xfs_devopen_common(dev);
+}
+
+/* XXX ugly function so we can keep xfs_devopen static */
+int
+xfs_func_is_devopen(void *func)
+{
+ return func == (void*)&xfs_devopen;
+}
+
+int
+xfs_devclose(dev_t dev, int flag, int devtype, struct proc *p)
+{
+ XFSDEB(XDEBDEV, ("xfs_devclose dev = %d, flag = %d\n", dev, flag));
+ return xfs_devclose_common(dev, p);
+}
+
+/*
+ * Not used.
+ */
+
+int
+xfs_devioctl(dev_t dev,
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+ u_long cmd,
+#elif defined(__FreeBSD__)
+ int cmd,
+#endif
+ caddr_t data, int flags, struct proc *p)
+{
+ XFSDEB(XDEBDEV, ("xfs_devioctl dev = %d.%d, cmd = %lu, "
+ "data = %p, flags = %x\n",
+ major(dev), minor(dev), (unsigned long)cmd, data, flags));
+ return ENOTTY;
+}
+
+static int
+xfs_realselect(dev_t dev, struct proc *p)
+{
+ struct xfs_channel *chan = &xfs_channel[minor(dev)];
+
+ if (!xfs_emptyq(&chan->messageq))
+ return 1; /* Something to read */
+
+ selrecord (p, &chan->selinfo);
+ return 0;
+}
+
+
+#ifdef HAVE_VOP_POLL
+static int
+xfs_devpoll(dev_t dev, int events, struct proc * p)
+{
+ XFSDEB(XDEBDEV, ("xfs_devpoll dev = %d, events = %d\n", dev, events));
+
+ if (!(events & POLLRDNORM))
+ return 0;
+
+ return xfs_realselect(dev, p);
+}
+
+#endif
+
+#ifdef HAVE_VOP_SELECT
+int
+xfs_devselect(dev_t dev, int which, struct proc * p)
+{
+ XFSDEB(XDEBDEV, ("xfs_devselect dev = %d, which = %d\n", dev, which));
+
+ if (which != FREAD)
+ return 0;
+
+ return xfs_realselect(dev, p);
+}
+
+#endif
+
+void
+xfs_select_wakeup(struct xfs_channel *chan)
+{
+ selwakeup (&chan->selinfo);
+}
+
+/*
+ * Install and uninstall device.
+ */
+
+#if defined(__NetBSD__)
+struct cdevsw xfs_dev = {
+ xfs_devopen,
+ xfs_devclose,
+ xfs_devread,
+ xfs_devwrite,
+ xfs_devioctl,
+ (dev_type_stop((*))) enodev,
+ 0,
+ xfs_devpoll,
+ (dev_type_mmap((*))) enodev,
+ 0
+};
+
+#elif defined(__OpenBSD__)
+struct cdevsw xfs_dev = {
+ xfs_devopen,
+ xfs_devclose,
+ xfs_devread,
+ xfs_devwrite,
+ xfs_devioctl,
+ (dev_type_stop((*))) enodev,
+ 0,
+ xfs_devselect,
+ (dev_type_mmap((*))) enodev,
+ 0
+};
+
+#elif defined(__FreeBSD__)
+struct cdevsw xfs_dev = {
+ xfs_devopen,
+ xfs_devclose,
+ xfs_devread,
+ xfs_devwrite,
+ xfs_devioctl,
+ nostop,
+ noreset,
+ nodevtotty,
+#if defined(HAVE_VOP_SELECT)
+ xfs_devselect,
+#elif defined(HAVE_VOP_POLL)
+ xfs_devpoll,
+#else
+#error select or poll: that is the question
+#endif
+ nommap,
+ nostrategy,
+ NULL,
+ 0
+};
+
+#endif /* FreeBSD */
+
+int
+xfs_install_device(void)
+{
+ int i;
+
+ for (i = 0; i < NXFS; i++) {
+ XFSDEB(XDEBDEV, ("before initq(messageq and sleepq)\n"));
+ xfs_initq(&xfs_channel[i].messageq);
+ xfs_initq(&xfs_channel[i].sleepq);
+ }
+
+ return 0;
+}
+
+int
+xfs_uninstall_device(void)
+{
+ int i;
+ struct xfs_channel *chan;
+
+ for (i = 0; i < NXFS; i++) {
+ chan = &xfs_channel[i];
+ if (chan->status & CHANNEL_OPENED)
+ xfs_devclose(makedev(0, i), 0, 0, NULL);
+ }
+
+ return 0;
+}
+
+int
+xfs_stat_device(void)
+{
+ return xfs_uprintf_device();
+}
diff --git a/sys/xfs/xfs_dev-common.c b/sys/xfs/xfs_dev-common.c
new file mode 100644
index 00000000000..d1ab98d67d8
--- /dev/null
+++ b/sys/xfs/xfs_dev-common.c
@@ -0,0 +1,564 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+
+#include <xfs/xfs_locl.h>
+#include <xfs/xfs_message.h>
+#include <xfs/xfs_msg_locl.h>
+#include <xfs/xfs_fs.h>
+#include <xfs/xfs_dev.h>
+#include <xfs/xfs_deb.h>
+
+RCSID("$Id: xfs_dev-common.c,v 1.1 1999/04/30 01:59:00 art Exp $");
+
+struct xfs_channel xfs_channel[NXFS];
+
+void
+xfs_initq(struct xfs_link *q)
+{
+ q->next = q;
+ q->prev = q;
+}
+
+/* Is this queue empty? */
+int
+xfs_emptyq(struct xfs_link *q)
+{
+ return q->next == q;
+}
+
+/* Is this link on any queue? Link *must* be inited! */
+int
+xfs_onq(struct xfs_link *link)
+{
+ return link->next != NULL || link->prev != NULL;
+}
+
+/* Append q with p */
+void
+xfs_appendq(struct xfs_link *q, struct xfs_link *p)
+{
+ p->next = q;
+ p->prev = q->prev;
+ p->prev->next = p;
+ q->prev = p;
+}
+
+void
+xfs_outq(struct xfs_link *p)
+{
+ p->next->prev = p->prev;
+ p->prev->next = p->next;
+ p->next = p->prev = 0;
+}
+
+/*
+ * Only allow one open.
+ */
+int
+xfs_devopen_common(dev_t dev)
+{
+ struct xfs_channel *chan;
+
+ if (minor(dev) < 0 || minor(dev) >= NXFS)
+ return ENXIO;
+
+ chan = &xfs_channel[minor(dev)];
+
+ /* Only allow one reader/writer */
+ if (chan->status & CHANNEL_OPENED) {
+ XFSDEB(XDEBDEV, ("xfs_devopen: already open\n"));
+ return EBUSY;
+ } else
+ chan->status |= CHANNEL_OPENED;
+
+ chan->message_buffer = xfs_alloc(MAX_XMSG_SIZE);
+
+ /* initalize the queues if they have not been initialized before */
+ xfs_initq(&chan->sleepq);
+ xfs_initq(&chan->messageq);
+
+ return 0;
+}
+
+#if defined(HAVE_THREE_ARGUMENT_VFS_BUSY)
+#define xfs_vfs_busy(mp, flags, lock, proc) vfs_busy((mp), (flags), (lock))
+#define xfs_vfs_unbusy(mp, proc) vfs_unbusy((mp))
+#elif defined(HAVE_FOUR_ARGUMENT_VFS_BUSY)
+#define xfs_vfs_busy(mp, flags, lock, proc) vfs_busy((mp), (flags), (lock), (proc))
+#define xfs_vfs_unbusy(mp, proc) vfs_unbusy((mp), (proc))
+#elif defined(__osf__)
+#define xfs_vfs_busy(mp, flags, lock, proc) (0)
+#define xfs_vfs_unbusy(mp, proc) (0)
+#else
+#define xfs_vfs_busy(mp, flags, lock, proc) vfs_busy((mp))
+#define xfs_vfs_unbusy(mp, proc) vfs_unbusy((mp))
+#endif
+
+/*
+ * Wakeup all sleepers and cleanup.
+ */
+int
+xfs_devclose_common(dev_t dev, struct proc *proc)
+{
+ struct xfs_channel *chan = &xfs_channel[minor(dev)];
+ struct xfs_link *first;
+
+ /* Sanity check, paranoia? */
+ if (!(chan->status & CHANNEL_OPENED))
+ panic("xfs_devclose never opened?");
+
+ chan->status &= ~CHANNEL_OPENED;
+
+ /* No one is going to read those messages so empty queue! */
+ while (!xfs_emptyq(&chan->messageq)) {
+ XFSDEB(XDEBDEV, ("before outq(messageq)\n"));
+
+ first = chan->messageq.next;
+ xfs_outq(first);
+ if (first->error_or_size != 0)
+ xfs_free(first, first->error_or_size);
+
+ XFSDEB(XDEBDEV, ("after outq(messageq)\n"));
+ }
+
+ /* Wakeup those waiting for replies that will never arrive. */
+ while (!xfs_emptyq(&chan->sleepq)) {
+ XFSDEB(XDEBDEV, ("before outq(sleepq)\n"));
+ first = chan->sleepq.next;
+ xfs_outq(first);
+ first->error_or_size = ENODEV;
+ wakeup((caddr_t) first);
+ XFSDEB(XDEBDEV, ("after outq(sleepq)\n"));
+ }
+
+ if (chan->status & CHANNEL_WAITING)
+ wakeup((caddr_t) chan);
+
+ if (chan->message_buffer) {
+ xfs_free(chan->message_buffer, MAX_XMSG_SIZE);
+ chan->message_buffer = NULL;
+ }
+
+ /*
+ * Free all xfs nodes.
+ */
+
+ if (xfs[minor(dev)].mp != NULL) {
+ if (xfs_vfs_busy(xfs[minor(dev)].mp, 0, NULL, proc)) {
+ XFSDEB(XDEBNODE, ("xfs_dev_close: vfs_busy() --> BUSY\n"));
+ return EBUSY;
+ }
+ free_all_xfs_nodes(&xfs[minor(dev)], FORCECLOSE, 0);
+
+ xfs_vfs_unbusy(xfs[minor(dev)].mp, proc);
+ }
+
+ return 0;
+}
+
+/*
+ * Move messages from kernel to user space.
+ */
+int
+xfs_devread(dev_t dev, struct uio * uiop, int ioflag)
+{
+ struct xfs_channel *chan = &xfs_channel[minor(dev)];
+ struct xfs_link *first;
+ int error = 0;
+
+ XFSDEB(XDEBDEV, ("xfs_devread dev = %d\n", dev));
+
+ XFSDEB(XDEBDEV, ("xfs_devread: m = %p, m->prev = %p, m->next = %p\n",
+ &chan->messageq, chan->messageq.prev, chan->messageq.next));
+
+ again:
+
+ if (!xfs_emptyq (&chan->messageq)) {
+ while (!xfs_emptyq (&chan->messageq)) {
+ /* Remove message */
+ first = chan->messageq.next;
+ XFSDEB(XDEBDEV, ("xfs_devread: first = %p, "
+ "first->prev = %p, first->next = %p\n",
+ first, first->prev, first->next));
+
+ XFSDEB(XDEBDEV, ("xfs_devread: message->size = %u\n",
+ first->message->size));
+
+ error = uiomove((caddr_t) first->message, first->message->size,
+ uiop);
+ if (error)
+ break;
+
+ xfs_outq(first);
+
+ if (first->error_or_size != 0)
+ xfs_free(first, first->error_or_size);
+ }
+ } else {
+ chan->status |= CHANNEL_WAITING;
+ if (tsleep((caddr_t) chan, (PZERO + 1) | PCATCH, "xfsr", 0)) {
+ XFSDEB(XDEBMSG, ("caught signal xfs_devread\n"));
+ error = EINTR;
+ } else if ((chan->status & CHANNEL_WAITING) == 0) {
+ goto again;
+ } else
+ error = EIO;
+ }
+
+
+ XFSDEB(XDEBDEV, ("xfs_devread done error = %d\n", error));
+
+ return error;
+}
+
+/*
+ * Move messages from user space to kernel space,
+ * wakeup sleepers, insert new data in VFS.
+ */
+int
+xfs_devwrite(dev_t dev, struct uio *uiop, int ioflag)
+{
+ struct xfs_channel *chan = &xfs_channel[minor(dev)];
+ char *p;
+ int error;
+ u_int cnt;
+ struct xfs_message_header *msg_buf;
+
+ XFSDEB(XDEBDEV, ("xfs_devwrite dev = %d\n", dev));
+
+ cnt = uiop->uio_resid;
+ error = uiomove((caddr_t) chan->message_buffer, MAX_XMSG_SIZE, uiop);
+ if (error != 0)
+ return error;
+
+ cnt -= uiop->uio_resid;
+
+ /*
+ * This thread handles the received message.
+ */
+ for (p = (char *)chan->message_buffer;
+ cnt > 0;
+ p += msg_buf->size, cnt -= msg_buf->size) {
+ struct proc *pp = xfs_uio_to_proc(uiop);
+
+ msg_buf = (struct xfs_message_header *)p;
+ error = xfs_message_receive (minor(dev),
+ msg_buf,
+ msg_buf->size,
+ pp);
+ }
+ XFSDEB(XDEBDEV, ("xfs_devwrite error = %d\n", error));
+ return error;
+}
+
+/*
+ * Send a message to user space.
+ */
+int
+xfs_message_send(int fd, struct xfs_message_header * message, u_int size)
+{
+ struct xfs_channel *chan = &xfs_channel[fd];
+ struct {
+ struct xfs_link this_message;
+ struct xfs_message_header msg;
+ } *t;
+
+ XFSDEB(XDEBMSG, ("xfs_message_send opcode = %d\n", message->opcode));
+
+ if (!(chan->status & CHANNEL_OPENED)) /* No receiver? */
+ return ENODEV;
+
+ /* Prepare message and copy it later */
+ message->size = size;
+ message->sequence_num = chan->nsequence++;
+
+ t = xfs_alloc(sizeof(t->this_message) + size);
+ t->this_message.error_or_size = sizeof(t->this_message) + size;
+ bcopy(message, &t->msg, size);
+
+ t->this_message.message = &t->msg;
+ xfs_appendq(&chan->messageq, &t->this_message);
+ if (chan->status & CHANNEL_WAITING) {
+ chan->status &= ~CHANNEL_WAITING;
+ wakeup((caddr_t) chan);
+ }
+ xfs_select_wakeup(chan);
+
+ return 0;
+}
+
+/*
+ * Send a message to user space and wait for reply.
+ */
+int
+xfs_message_rpc(int fd, struct xfs_message_header * message, u_int size)
+{
+ int ret;
+ struct xfs_channel *chan = &xfs_channel[fd];
+ struct xfs_link *this_message;
+ struct xfs_link *this_process;
+ struct xfs_message_header *msg;
+#if defined(HAVE_STRUCT_PROC_P_SIGMASK)
+ sigset_t oldsigmask;
+#endif /* HAVE_STRUCT_PROC_P_SIGMASK */
+
+ XFSDEB(XDEBMSG, ("xfs_message_rpc opcode = %d\n", message->opcode));
+
+ if (!(chan->status & CHANNEL_OPENED)) /* No receiver? */
+ return ENODEV;
+
+ if (size < sizeof(struct xfs_message_wakeup)) {
+ printf("XFS PANIC Error: Message to small to receive wakeup, opcode = %d\n", message->opcode);
+ return ENOMEM;
+ }
+ this_message = xfs_alloc(sizeof(struct xfs_link));
+ this_process = xfs_alloc(sizeof(struct xfs_link));
+ msg = xfs_alloc(size);
+ bcopy(message, msg, size);
+
+ msg->size = size;
+ msg->sequence_num = chan->nsequence++;
+ this_message->error_or_size = 0;
+ this_message->message = msg;
+ this_process->message = msg;
+ xfs_appendq(&chan->messageq, this_message);
+ xfs_appendq(&chan->sleepq, this_process);
+ xfs_select_wakeup(chan);
+ this_process->error_or_size = 0;
+
+ if (chan->status & CHANNEL_WAITING) {
+ chan->status &= ~CHANNEL_WAITING;
+ wakeup((caddr_t) chan);
+ }
+
+ /*
+ * Remove SIGIO from the sigmask so no IO will
+ * wake us up from tsleep()
+ */
+
+#ifdef HAVE_STRUCT_PROC_P_SIGMASK
+ oldsigmask = xfs_curproc()->p_sigmask;
+#ifdef __sigaddset
+ __sigaddset(&xfs_curproc()->p_sigmask, SIGIO);
+#else
+ xfs_curproc()->p_sigmask |= sigmask(SIGIO);
+#endif /* __sigaddset */
+#elif defined(HAVE_STRUCT_PROC_P_SIGWAITMASK)
+ oldsigmask = xfs_curproc()->p_sigwaitmask;
+ sigaddset(&xfs_curproc()->p_sigwaitmask, SIGIO);
+#endif
+ /*
+ * We have to check if we have a receiver here too because the
+ * daemon could have terminated before we sleep. This seems to
+ * happen sometimes when rebooting.
+ */
+ if (!(chan->status & CHANNEL_OPENED) ||
+ tsleep((caddr_t) this_process, (PZERO + 1) | PCATCH, "xfs", 0)) {
+ XFSDEB(XDEBMSG, ("caught signal\n"));
+ this_process->error_or_size = EINTR;
+ }
+
+#ifdef HAVE_STRUCT_PROC_P_SIGMASK
+ xfs_curproc()->p_sigmask = oldsigmask;
+#elif defined(HAVE_STRUCT_PROC_P_SIGWAITMASK)
+ xfs_curproc()->p_sigwaitmask = oldsigmask;
+#endif
+
+ /*
+ * Caught signal, got reply message or device was closed.
+ * Need to clean up both messageq and sleepq.
+ */
+ if (xfs_onq(this_message)) {
+ xfs_outq(this_message);
+ }
+ if (xfs_onq(this_process)) {
+ xfs_outq(this_process);
+ }
+ ret = this_process->error_or_size;
+
+ XFSDEB(XDEBMSG, ("xfs_message_rpc this_process->error_or_size = %d\n",
+ this_process->error_or_size));
+ XFSDEB(XDEBMSG, ("xfs_message_rpc opcode ((xfs_message_wakeup*)(this_process->message))->error = %d\n", ((struct xfs_message_wakeup *) (this_process->message))->error));
+
+ bcopy(msg, message, size);
+
+ xfs_free(this_message, sizeof(*this_message));
+ xfs_free(this_process, sizeof(*this_process));
+ xfs_free(msg, size);
+
+ return ret;
+}
+
+/*
+ * For each message type there is a message handler
+ * that implements its action, xfs_message_receive
+ * invokes the correct function.
+ */
+int
+xfs_message_receive(int fd,
+ struct xfs_message_header *message,
+ u_int size,
+ struct proc *p)
+{
+ XFSDEB(XDEBMSG, ("xfs_message_receive opcode = %d\n", message->opcode));
+
+ /* Dispatch and coerce message type */
+ switch (message->opcode) {
+ case XFS_MSG_WAKEUP:
+ return xfs_message_wakeup(fd,
+ (struct xfs_message_wakeup *) message,
+ message->size,
+ p);
+ case XFS_MSG_WAKEUP_DATA:
+ return xfs_message_wakeup_data(fd,
+ (struct xfs_message_wakeup_data *) message,
+ message->size,
+ p);
+ case XFS_MSG_INSTALLROOT:
+ return xfs_message_installroot(fd,
+ (struct xfs_message_installroot *) message,
+ message->size,
+ p);
+ case XFS_MSG_INSTALLNODE:
+ return xfs_message_installnode(fd,
+ (struct xfs_message_installnode *) message,
+ message->size,
+ p);
+ case XFS_MSG_INSTALLATTR:
+ return xfs_message_installattr(fd,
+ (struct xfs_message_installattr *) message,
+ message->size,
+ p);
+ case XFS_MSG_INSTALLDATA:
+ return xfs_message_installdata(fd,
+ (struct xfs_message_installdata *) message,
+ message->size,
+ p);
+ case XFS_MSG_INVALIDNODE:
+ return xfs_message_invalidnode(fd,
+ (struct xfs_message_invalidnode *) message,
+ message->size,
+ p);
+ case XFS_MSG_UPDATEFID:
+ return xfs_message_updatefid(fd,
+ (struct xfs_message_updatefid *)message,
+ message->size,
+ p);
+ default:
+ printf("XFS PANIC Warning xfs_dev: Unknown message opcode == %d\n",
+ message->opcode);
+ return EINVAL;
+ }
+}
+
+int
+xfs_message_wakeup(int fd,
+ struct xfs_message_wakeup *message,
+ u_int size,
+ struct proc *p)
+{
+ struct xfs_channel *chan = &xfs_channel[fd];
+ struct xfs_link *sleepq = &chan->sleepq;
+ struct xfs_link *t = chan->sleepq.next; /* Really first in q */
+
+ XFSDEB(XDEBMSG, ("xfs_message_wakeup error: %d\n", message->error));
+
+ for (; t != sleepq; t = t->next)
+ if (t->message->sequence_num == message->sleepers_sequence_num) {
+ if (t->message->size < size) {
+ printf("XFS PANIC Error: Could not wakeup requestor with opcode = %d properly, to small receive buffer.\n", t->message->opcode);
+ t->error_or_size = ENOMEM;
+ } else
+ bcopy(message, t->message, size);
+
+ wakeup((caddr_t) t);
+ break;
+ }
+
+ return 0;
+}
+
+int
+xfs_message_wakeup_data(int fd,
+ struct xfs_message_wakeup_data * message,
+ u_int size,
+ struct proc *p)
+{
+ struct xfs_channel *chan = &xfs_channel[fd];
+ struct xfs_link *sleepq = &chan->sleepq;
+ struct xfs_link *t = chan->sleepq.next; /* Really first in q */
+
+ XFSDEB(XDEBMSG, ("xfs_message_wakeup_data error: %d\n", message->error));
+
+ for (; t != sleepq; t = t->next)
+ if (t->message->sequence_num == message->sleepers_sequence_num) {
+ if (t->message->size < size) {
+ printf("XFS PANIC Error: Could not wakeup requestor with opcode = %d properly, to small receive buffer.\n", t->message->opcode);
+ t->error_or_size = ENOMEM;
+ } else
+ bcopy(message, t->message, size);
+ wakeup((caddr_t) t);
+ break;
+ }
+ return 0;
+}
+
+/*
+ *
+ */
+int
+xfs_uprintf_device(void)
+{
+#if 0
+ int i;
+
+ for (i = 0; i < NXFS; i++) {
+ uprintf("xfs_channel[%d] = {\n", i);
+ uprintf("messageq.next = %p ", xfs_channel[i].messageq.next);
+ uprintf("messageq.prev = %p ", xfs_channel[i].messageq.prev);
+ uprintf("sleepq.next = %p ", xfs_channel[i].sleepq.next);
+ uprintf("sleepq.prev = %p ", xfs_channel[i].sleepq.prev);
+ uprintf("nsequence = %d status = %d\n",
+ xfs_channel[i].nsequence,
+ xfs_channel[i].status);
+ uprintf("}\n");
+ }
+#endif
+ return 0;
+}
diff --git a/sys/xfs/xfs_dev.h b/sys/xfs/xfs_dev.h
index 4b95a68959c..095d004976d 100644
--- a/sys/xfs/xfs_dev.h
+++ b/sys/xfs/xfs_dev.h
@@ -1,4 +1,3 @@
-/* $OpenBSD: xfs_dev.h,v 1.2 1998/08/31 05:13:23 art Exp $ */
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
@@ -37,34 +36,128 @@
* SUCH DAMAGE.
*/
-/* $KTH: xfs_dev.h,v 1.4 1998/04/05 18:19:50 art Exp $ */
+/* $Id: xfs_dev.h,v 1.3 1999/04/30 01:59:00 art Exp $ */
-#ifndef _XFS_XFS_DEV_H_
-#define _XFS_XFS_DEV_H_
+#ifndef _xfs_dev_h
+#define _xfs_dev_h
-int xfs_devopen __P((dev_t dev, int flags, int devtype, struct proc * p));
+/*
+ * Queues of xfs_links hold outbound messages and processes sleeping
+ * for replies. The last field is used to return error to sleepers and
+ * to keep record of memory to be deallocated when messages have been
+ * delivered or dropped.
+ */
+
+struct xfs_link {
+ struct xfs_link *prev, *next;
+ struct xfs_message_header *message;
+ u_int error_or_size; /* error on sleepq and size on
+ * messageq */
+};
+
+struct xfs_channel {
+ struct xfs_link messageq; /* Messages not yet read */
+ struct xfs_link sleepq; /* Waiting for reply message */
+ u_int nsequence;
+#ifdef __osf__
+ sel_queue_t sel_q;
+#else
+ struct selinfo selinfo;
+#endif
+ struct xfs_message_header *message_buffer;
+ int status;
+#define CHANNEL_OPENED 0x1
+#define CHANNEL_WAITING 0x2
+};
+
+extern struct xfs_channel xfs_channel[NXFS];
+
+/*
+ * These are variant dependent
+ */
+
+int xfs_func_is_devopen(void*);
+void xfs_select_wakeup(struct xfs_channel *);
+
+int xfs_install_device(void);
+int xfs_uninstall_device(void);
-int xfs_install_device __P((void));
-int xfs_uninstall_device __P((void));
+int xfs_install_filesys(void);
+int xfs_may_uninstall_filesys(void);
+int xfs_uninstall_filesys(void);
-int xfs_install_filesys __P((void));
-int xfs_uninstall_filesys __P((void));
+int xfs_stat_filesys(void);
+int xfs_stat_device(void);
+
+/*
+ * And these should be generic
+ */
-int xfs_stat_filesys __P((void));
-int xfs_stat_device __P((void));
+void
+xfs_initq(struct xfs_link *q);
-int xfs_message_send __P((int fd, struct xfs_message_header *message,
- u_int size));
-int xfs_message_rpc __P((int fd, struct xfs_message_header *message,
- u_int size));
-int xfs_message_receive __P((int fd,struct xfs_message_header *message,
- u_int size,struct proc *p));
-int xfs_message_wakeup __P((int fd, struct xfs_message_wakeup *message,
- u_int size, struct proc *p));
-int xfs_message_wakeup_data __P((int fd,
- struct xfs_message_wakeup_data *message,
- u_int size, struct proc *p));
-#define USE_SELECT
+int
+xfs_emptyq(struct xfs_link *q);
+int
+xfs_onq(struct xfs_link *link);
+
+void
+xfs_appendq(struct xfs_link *q, struct xfs_link *p);
+
+void
+xfs_outq(struct xfs_link *p);
+
+int
+xfs_devopen_common(dev_t dev);
+
+#ifndef __osf__ /* XXX - we should do the same for osf */
+int xfs_devopen(dev_t dev, int flag, int devtype, struct proc *proc);
+int xfs_devclose(dev_t dev, int flag, int devtype, struct proc *proc);
+int xfs_devioctl(dev_t dev,
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+ u_long cmd,
+#else /* if defined(__FreeBSD__) */
+ int cmd,
#endif
+ caddr_t data, int flags, struct proc *p);
+int xfs_devselect(dev_t dev, int which, struct proc *p);
+#endif /* ! __osf__ */
+
+int
+xfs_devclose_common(dev_t dev, struct proc *p);
+
+int
+xfs_devread(dev_t dev, struct uio * uiop, int ioflag);
+
+int
+xfs_devwrite(dev_t dev, struct uio *uiop, int ioflag);
+
+int
+xfs_message_send(int fd, struct xfs_message_header * message, u_int size);
+
+int
+xfs_message_rpc(int fd, struct xfs_message_header * message, u_int size);
+
+int
+xfs_message_receive(int fd,
+ struct xfs_message_header *message,
+ u_int size,
+ struct proc *p);
+
+int
+xfs_message_wakeup(int fd,
+ struct xfs_message_wakeup *message,
+ u_int size,
+ struct proc *p);
+
+int
+xfs_message_wakeup_data(int fd,
+ struct xfs_message_wakeup_data * message,
+ u_int size,
+ struct proc *p);
+
+int
+xfs_uprintf_device(void);
+#endif /* _xfs_dev_h */
diff --git a/sys/xfs/xfs_fs.h b/sys/xfs/xfs_fs.h
index 007c32e706f..51f9bb4dbcd 100644
--- a/sys/xfs/xfs_fs.h
+++ b/sys/xfs/xfs_fs.h
@@ -1,4 +1,3 @@
-/* $OpenBSD: xfs_fs.h,v 1.2 1998/08/31 05:13:26 art Exp $ */
/*
* Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
@@ -37,30 +36,36 @@
* SUCH DAMAGE.
*/
-/* $KTH: xfs_fs.h,v 1.8 1998/04/04 01:17:26 art Exp $ */
+/* $Id: xfs_fs.h,v 1.3 1999/04/30 01:59:00 art Exp $ */
-#ifndef _XFS_XFS_H_
-#define _XFS_XFS_H_
+#ifndef _xfs_h
+#define _xfs_h
#include <sys/types.h>
+#include <xfs/xfs_common.h>
#include <xfs/xfs_node.h>
#include <xfs/xfs_attr.h>
-#include <xfs/nxfs.h>
+
+#define NXFS 2 /* maximal number of filesystems on a single device */
/*
* Filesystem struct.
*/
struct xfs {
- u_int status; /* Inited, opened or mounted */
+ u_int status; /* Inited, opened or mounted */
#define XFS_MOUNTED 0x1
- struct mount *mp;
- struct xfs_node *root;
- u_int nnodes;
- int fd;
+ struct mount *mp;
+ struct xfs_node *root;
+ u_int nnodes;
+ int fd;
};
+#ifdef __osf__
+#define VFS_TO_XFS(v) ((struct xfs *) ((v)->m_data))
+#else
#define VFS_TO_XFS(v) ((struct xfs *) ((v)->mnt_data))
+#endif
#define XFS_TO_VFS(x) ((x)->mp)
#define XFS_FROM_VNODE(vp) VFS_TO_XFS((vp)->v_mount)
@@ -70,20 +75,31 @@ extern struct xfs xfs[];
extern struct vnodeops xfs_vnodeops;
-struct xfs_node *xfs_node_find __P((struct xfs *, struct xfs_handle *));
-int new_xfs_node __P((struct xfs *, struct xfs_msg_node *, struct xfs_node **,
- struct proc *));
-void free_xfs_node __P((struct xfs_node *));
-int free_all_xfs_nodes __P((struct xfs *, int));
+struct xfs_node *xfs_node_find(struct xfs *, struct xfs_handle *);
+int new_xfs_node(struct xfs *, struct xfs_msg_node *, struct xfs_node **,
+ struct proc *);
+void free_xfs_node(struct xfs_node *);
+int free_all_xfs_nodes(struct xfs *, int, int);
-int xfs_dnlc_enter __P((struct vnode *, char *, struct vnode *));
-void xfs_dnlc_purge __P((struct mount *));
-int xfs_dnlc_lookup __P((struct vnode *, struct componentname *,
- struct vnode **));
+int xfs_dnlc_enter(struct vnode *, xfs_componentname *, struct vnode *);
+int xfs_dnlc_enter_name(struct vnode *, const char *, struct vnode *);
+void xfs_dnlc_purge_mp(struct mount *);
+void xfs_dnlc_purge(struct vnode *);
+int xfs_dnlc_lookup(struct vnode *, xfs_componentname *, struct vnode **);
+int xfs_dnlc_lookup_name(struct vnode *, const char *, struct vnode **);
-void vattr2xfs_attr __P((const struct vattr * va, struct xfs_attr *xa));
-void xfs_attr2vattr __P((const struct xfs_attr *xa, struct vattr * va));
+void
+xfs_cnp_init (xfs_componentname *ndp,
+ const char *name,
+ struct vnode *vp,
+ struct vnode *dvp,
+ struct proc *proc,
+ struct ucred *cred,
+ int nameiop);
-int xfs_has_pag __P((const struct xfs_node *xn, pag_t pag));
+void vattr2xfs_attr(const struct vattr *, struct xfs_attr *);
+void xfs_attr2vattr(const struct xfs_attr *, struct vattr *);
-#endif
+int xfs_has_pag(const struct xfs_node *, pag_t);
+
+#endif /* _xfs_h */
diff --git a/sys/xfs/xfs_global.h b/sys/xfs/xfs_global.h
new file mode 100644
index 00000000000..b23c1d20f08
--- /dev/null
+++ b/sys/xfs/xfs_global.h
@@ -0,0 +1,9 @@
+#ifndef __XFS_GLOBAL_H
+#define __XFS_GLOBAL_H
+
+#ifndef RCSID
+#define RCSID(msg) \
+static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
+#endif /* RCSID */
+
+#endif /* __XFS_GLOBAL_H */
diff --git a/sys/xfs/xfs_locl.h b/sys/xfs/xfs_locl.h
new file mode 100644
index 00000000000..c87c4c92b9c
--- /dev/null
+++ b/sys/xfs/xfs_locl.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/* $Id: xfs_locl.h,v 1.1 1999/04/30 01:59:00 art Exp $ */
+
+#if 1 /* XXX - ugly hack */
+#include <xfs/xfs_config.h>
+#endif
+
+#ifndef RCSID
+#define RCSID(x)
+#endif
+
+#ifdef __osf__
+
+#ifdef __GNUC__
+#define asm __foo_asm
+#endif
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/uio.h>
+#include <machine/cpu.h>
+#include <sys/conf.h>
+#include <sys/sysconfig.h>
+#include <sys/file.h>
+#include <sys/malloc.h>
+#include <sys/poll.h>
+#include <sys/ioctl.h>
+#include <sys/fcntl.h>
+#include <sys/vfs_proto.h>
+#include <io/common/devdriver.h>
+#include <vm/vm_page.h>
+#include <vm/vm_vppage.h>
+#include <vm/vm_ubc.h>
+
+typedef short int16_t;
+typedef int int32_t;
+typedef unsigned int u_int32_t;
+
+#define VT_AFS VT_ADDON
+#define MOUNT_XFS MOUNT_PC
+
+typedef struct nameidata xfs_componentname;
+
+/* XXX this is gross, but makes the code considerably more readable */
+#if 0
+#define componentname nameidata
+#endif
+
+#define cn_nameptr ni_ptr
+#define cn_namelen ni_namelen
+#define cn_hash ni_hash
+#define cn_cred ni_cred
+#define cn_nameiop ni_nameiop
+#define cn_flags ni_flags
+
+#define mnt_stat m_stat
+#define mnt_flag m_flag
+
+#define NDINIT(ndp, op, flags, segflg, namep, p) \
+ (ndp)->ni_nameiop = (op) | (flags); \
+ (ndp)->ni_segflg = segflg; \
+ (ndp)->ni_dirp = namep;
+
+#define LOCKLEAF 0
+
+#define FFLAGS(mode) ((mode) - FOPEN)
+
+/* 4.4BSD vput does VOP_UNLOCK + vrele, but it seems as if we only
+ should do a vrele here */
+#define vput(VP) vrele(VP)
+
+#define xfs_uio_to_proc(uiop) (u.u_procp)
+#define xfs_cnp_to_proc(cnp) (u.u_procp)
+#define xfs_proc_to_cred(p) ((p)->p_rcred)
+
+#define xfs_curproc() (u.u_procp)
+
+#else /* __osf__ */
+
+typedef struct componentname xfs_componentname;
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/filedesc.h>
+#include <sys/kernel.h>
+#ifdef HAVE_SYS_MODULE_H
+#include <sys/module.h>
+#endif
+#include <sys/systm.h>
+#include <sys/fcntl.h>
+#ifdef HAVE_SYS_SYSPROTO_H
+#include <sys/sysproto.h>
+#endif
+#include <sys/conf.h>
+#include <sys/mount.h>
+#include <sys/exec.h>
+#ifdef HAVE_SYS_SYSENT_H
+#include <sys/sysent.h>
+#endif
+#include <sys/lkm.h>
+#include <sys/errno.h>
+#include <sys/file.h>
+#include <sys/namei.h>
+#include <sys/dirent.h>
+#include <sys/ucred.h>
+#include <sys/select.h>
+#include <sys/uio.h>
+#ifdef HAVE_SYS_POLL_H
+#include <sys/poll.h>
+#endif
+#include <sys/syscall.h>
+#include <sys/queue.h>
+#include <sys/malloc.h>
+#ifdef HAVE_MISCFS_GENFS_GENFS_H
+#include <miscfs/genfs/genfs.h>
+#endif
+#ifdef HAVE_VM_VM_H
+#include <vm/vm.h>
+#endif
+#ifdef HAVE_VM_VM_EXTERN_H
+#include <vm/vm_extern.h>
+#endif
+#ifdef HAVE_VM_VM_ZONE_H
+#include <vm/vm_zone.h>
+#endif
+
+#define xfs_uio_to_proc(uiop) ((uiop)->uio_procp)
+#define xfs_cnp_to_proc(cnp) ((cnp)->cn_proc)
+#define xfs_proc_to_cred(p) ((p)->p_ucred)
+
+#define xfs_curproc() (curproc)
+
+#endif /* __osf__ */
+
+/*
+ * The VOP table
+ *
+ * What VOPs do we have today ?
+ */
+
+#include "xfs/xfs_vopdefs.h"
diff --git a/sys/xfs/xfs_message.c b/sys/xfs/xfs_message.c
index 2a3086611d9..beb951376b3 100644
--- a/sys/xfs/xfs_message.c
+++ b/sys/xfs/xfs_message.c
@@ -1,4 +1,3 @@
-/* $OpenBSD: xfs_message.c,v 1.3 1998/09/06 01:48:58 art Exp $ */
/*
* Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
@@ -37,181 +36,234 @@
* SUCH DAMAGE.
*/
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/namei.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/vnode.h>
-
-#include <xfs/xfs_common.h>
+#include <xfs/xfs_locl.h>
#include <xfs/xfs_deb.h>
#include <xfs/xfs_fs.h>
#include <xfs/xfs_message.h>
#include <xfs/xfs_msg_locl.h>
+#include <xfs/xfs_syscalls.h>
+#include <xfs/xfs_vfsops.h>
+#include <xfs/xfs_vnodeops.h>
-RCSID("$KTH: xfs_message.c,v 1.16 1998/07/19 00:19:54 art Exp $");
+RCSID("$Id: xfs_message.c,v 1.4 1999/04/30 01:59:00 art Exp $");
int
xfs_message_installroot(int fd,
- struct xfs_message_installroot *message,
+ struct xfs_message_installroot * message,
u_int size,
struct proc *p)
{
- int error = 0;
+ int error = 0;
- XFSDEB(XDEBMSG, ("xfs_message_installroot\n"));
+ XFSDEB(XDEBMSG, ("xfs_message_installroot\n"));
- if (xfs[fd].root != NULL) {
- printf("XFS WARNING! xfs_message_installroot: again!\n");
- error = EBUSY;
- } else {
- error = new_xfs_node(&xfs[fd], &message->node, &xfs[fd].root,
- p);
- if (error)
- return error;
- xfs[fd].root->vn->v_flag |= VROOT;
- }
-
- return error;
+ if (xfs[fd].root != NULL) {
+ printf("XFS PANIC WARNING! xfs_message_installroot: called again!\n");
+ error = EBUSY;
+ } else {
+ error = new_xfs_node(&xfs[fd], &message->node, &xfs[fd].root, p);
+ if (error)
+ return error;
+ xfs[fd].root->vn->v_flag |= VROOT;
+ }
+ return error;
}
int
xfs_message_installnode(int fd,
- struct xfs_message_installnode *message,
+ struct xfs_message_installnode * message,
u_int size,
struct proc *p)
{
- int error = 0;
- struct xfs_node *n, *dp;
-
- XFSDEB(XDEBMSG, ("xfs_message_installnode\n"));
-
- dp = xfs_node_find(&xfs[fd], &message->parent_handle);
- if (dp) {
- error = new_xfs_node(&xfs[fd], &message->node, &n, p);
- if (error)
- return error;
- cache_purge (XNODE_TO_VNODE(dp));
- xfs_dnlc_enter(XNODE_TO_VNODE(dp), message->name,
- XNODE_TO_VNODE(n));
- vrele(XNODE_TO_VNODE(n));
- } else {
- printf("XFS WARNING! xfs_message_installnode: no parent\n");
- error = ENOENT;
+ int error = 0;
+ struct xfs_node *n, *dp;
+
+ XFSDEB(XDEBMSG, ("xfs_message_installnode\n"));
+
+ dp = xfs_node_find(&xfs[fd], &message->parent_handle);
+ if (dp) {
+ struct vnode *t_vnode = XNODE_TO_VNODE(dp);
+
+ xfs_do_vget (t_vnode, LK_INTERLOCK|LK_SHARED, p);
+
+ error = new_xfs_node(&xfs[fd], &message->node, &n, p);
+ if (error) {
+ vrele (t_vnode);
+ return error;
}
- XFSDEB(XDEBMSG, ("return: xfs_message_installnode: %d\n", error));
- return error;
+ xfs_dnlc_enter_name(t_vnode,
+ message->name,
+ XNODE_TO_VNODE(n));
+ vrele(XNODE_TO_VNODE(n));
+ vput (t_vnode);
+ } else {
+ printf("XFS PANIC WARNING! xfs_message_installnode: no parent\n");
+ error = ENOENT;
+ }
+ XFSDEB(XDEBMSG, ("return: xfs_message_installnode: %d\n", error));
+
+ return error;
}
int
xfs_message_installattr(int fd,
- struct xfs_message_installattr *message,
+ struct xfs_message_installattr * message,
u_int size,
struct proc *p)
{
- int error = 0;
- struct xfs_node *t;
-
- t = xfs_node_find(&xfs[fd], &message->node.handle);
- if (t != 0) {
- t->tokens = message->node.tokens;
- xfs_attr2vattr(&message->node.attr, &t->attr);
- bcopy(message->node.id, t->id, sizeof(t->id));
- bcopy(message->node.rights, t->rights, sizeof(t->rights));
- t->anonrights = message->node.anonrights;
- } else {
- printf("XFS WARNING! xfs_message_installattr: no node!\n");
- error = ENOENT;
- }
+ int error = 0;
+ struct xfs_node *t;
+
+ t = xfs_node_find(&xfs[fd], &message->node.handle);
+ if (t != 0) {
+ t->tokens = message->node.tokens;
+ xfs_attr2vattr(&message->node.attr, &t->attr);
+#ifdef HAVE_KERNEL_VNODE_PAGER_SETSIZE
+ vnode_pager_setsize(XNODE_TO_VNODE(t), t->attr.va_size);
+#endif
+ bcopy(message->node.id, t->id, sizeof(t->id));
+ bcopy(message->node.rights, t->rights, sizeof(t->rights));
+ t->anonrights = message->node.anonrights;
+ } else {
+ printf("XFS PANIC WARNING! xfs_message_installattr: no node!\n");
+ error = ENOENT;
+ }
- return error;
+ return error;
}
int
xfs_message_installdata(int fd,
- struct xfs_message_installdata *message,
+ struct xfs_message_installdata * message,
u_int size,
struct proc *p)
{
- struct xfs_node *t;
- int error = 0;
-
- XFSDEB(XDEBMSG, ("xfs_message_installdata\n"));
-
- t = xfs_node_find(&xfs[fd], &message->node.handle);
- if (t != NULL) {
- struct nameidata nd;
- char tmp[CACHEHANDLESIZE + 1];
- struct vnode *vp;
-
- bcopy((char *) &message->cache_handle.data, tmp, sizeof(tmp));
- tmp[CACHEHANDLESIZE] = '\0';
-
- XFSDEB(XDEBMSG, ("cache_handle = '%s'\n", tmp));
-
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, tmp, p);
- error = namei(&nd);
- vp = nd.ni_vp;
- if (error == 0) {
- if (DATA_FROM_XNODE(t))
- vrele(DATA_FROM_XNODE(t));
- VOP_UNLOCK(vp, 0, p);
- DATA_FROM_XNODE(t) = vp;
- XFSDEB(XDEBMSG,
- ("xfs_message_installdata: t= %p tokens= %x\n",
- t, message->node.tokens));
-
- t->tokens = message->node.tokens;
- xfs_attr2vattr(&message->node.attr, &t->attr);
- if (XNODE_TO_VNODE(t)->v_type == VDIR)
- cache_purge (XNODE_TO_VNODE(t));
-
- bcopy(message->node.id, t->id, sizeof(t->id));
- bcopy(message->node.rights, t->rights,
- sizeof(t->rights));
- t->anonrights = message->node.anonrights;
- } else {
- printf("XFS WARNING! xfs_message_installdata fail!\n");
- printf("Reason: lookup failed on cache file '%s', "
- "error = %d\n", tmp, error);
- }
+ struct xfs_node *t;
+ int error = 0;
+
+ XFSDEB(XDEBMSG, ("xfs_message_installdata\n"));
+
+ t = xfs_node_find(&xfs[fd], &message->node.handle);
+
+ if (t != NULL) {
+ struct xfs_fh_args *fh_args = (struct xfs_fh_args *)&message->cache_handle;
+ struct vnode *vp;
+ struct vnode *t_vnode = XNODE_TO_VNODE(t);
+
+ XFSDEB(XDEBMSG, ("cache_name = '%s'\n", message->cache_name));
+ XFSDEB(XDEBMSG, ("fileno = %ld, gen = %ld\n",
+ SCARG(fh_args, fileid),
+ SCARG(fh_args, gen)));
+
+ xfs_do_vget (t_vnode, LK_INTERLOCK|LK_SHARED, p);
+
+ error = xfs_fhlookup (p,
+ SCARG(fh_args,fsid),
+ SCARG(fh_args,fileid),
+ SCARG(fh_args,gen),
+ &vp);
+
+ if (error != 0) {
+#ifdef __osf__
+ struct nameidata *ndp = &u.u_nd;
+#else
+ struct nameidata nd;
+ struct nameidata *ndp = &nd;
+#endif
+
+ XFSDEB(XDEBMSG,
+ ("xfs_message_installdata: fhlookup failed: %d, "
+ "opening by name\n", error));
+
+ NDINIT(ndp, LOOKUP, FOLLOW, UIO_SYSSPACE,
+ message->cache_name, p);
+ error = namei(ndp);
+ vp = ndp->ni_vp;
+ }
+
+ if (error == 0) {
+ xfs_vfs_unlock(vp, p);
+ if (DATA_FROM_XNODE(t))
+ vrele(DATA_FROM_XNODE(t));
+ DATA_FROM_XNODE(t) = vp;
+
+ XFSDEB(XDEBMSG, ("xfs_message_installdata: t = %p;"
+ " tokens = %x\n",
+ t, message->node.tokens));
+
+ t->tokens = message->node.tokens;
+ xfs_attr2vattr(&message->node.attr, &t->attr);
+#ifdef HAVE_KERNEL_VNODE_PAGER_SETSIZE
+ vnode_pager_setsize(XNODE_TO_VNODE(t), t->attr.va_size);
+#endif
+ if (XNODE_TO_VNODE(t)->v_type == VDIR
+ && (message->flag & XFS_INVALID_DNLC))
+ cache_purge (XNODE_TO_VNODE(t));
+ bcopy(message->node.id, t->id, sizeof(t->id));
+ bcopy(message->node.rights, t->rights, sizeof(t->rights));
+ t->anonrights = message->node.anonrights;
} else {
- printf("XFS WARNING! xfs_message_installdata failed\n");
- printf("Reason: No node to install the data into!\n");
- error = ENOENT;
+ printf("XFS PANIC WARNING! xfs_message_installdata failed!\n");
+ printf("Reason: lookup failed on cache file '%s', error = %d\n",
+ message->cache_name, error);
}
+ vput (t_vnode);
+ } else {
+ printf("XFS PANIC WARNING! xfs_message_installdata failed\n");
+ printf("Reason: No node to install the data into!\n");
+ error = ENOENT;
+ }
- return error;
+ return error;
}
int
xfs_message_invalidnode(int fd,
- struct xfs_message_invalidnode *message,
+ struct xfs_message_invalidnode * message,
u_int size,
struct proc *p)
{
- int error = 0;
- struct xfs_node *t;
-
- XFSDEB(XDEBMSG, ("xfs_message_invalidnode\n"));
-
- t = xfs_node_find(&xfs[fd], &message->handle);
- if (t != 0) {
- /* XXX Really need to put back dirty data first. */
- if (DATA_FROM_XNODE(t)) {
- vrele(DATA_FROM_XNODE(t));
- DATA_FROM_XNODE(t) = (struct vnode *) 0;
- }
- XFS_TOKEN_CLEAR(t, ~0,
- XFS_OPEN_MASK | XFS_ATTR_MASK |
- XFS_DATA_MASK | XFS_LOCK_MASK);
- cache_purge(XNODE_TO_VNODE(t));
- } else {
- printf("XFS WARNING! xfs_message_invalidnode: no node!\n");
- error = ENOENT;
+ int error = 0;
+ struct xfs_node *t;
+
+ XFSDEB(XDEBMSG, ("xfs_message_invalidnode\n"));
+
+ t = xfs_node_find(&xfs[fd], &message->handle);
+ if (t != 0) {
+ /* XXX Really need to put back dirty data first. */
+ if (DATA_FROM_XNODE(t)) {
+ vrele(DATA_FROM_XNODE(t));
+ DATA_FROM_XNODE(t) = (struct vnode *) 0;
}
+ XFS_TOKEN_CLEAR(t, ~0,
+ XFS_OPEN_MASK | XFS_ATTR_MASK |
+ XFS_DATA_MASK | XFS_LOCK_MASK);
+ cache_purge(XNODE_TO_VNODE(t));
+ } else {
+ printf("XFS PANIC WARNING! xfs_message_invalidnode: no node!\n");
+ error = ENOENT;
+ }
+
+ return error;
+}
+
+int
+xfs_message_updatefid(int fd,
+ struct xfs_message_updatefid * message,
+ u_int size,
+ struct proc *p)
+{
+ int error = 0;
+ struct xfs_node *t;
- return error;
+ XFSDEB(XDEBMSG, ("xfs_message_updatefid\n"));
+ t = xfs_node_find (&xfs[fd], &message->old_handle);
+ if (t != NULL) {
+ t->handle = message->new_handle;
+ } else {
+ printf ("XFS PANIC WARNING! xfs_message_updatefid: no node!\n");
+ error = ENOENT;
+ }
+ return error;
}
diff --git a/sys/xfs/xfs_message.h b/sys/xfs/xfs_message.h
index 1e30b1f217c..d3741a1d3bd 100644
--- a/sys/xfs/xfs_message.h
+++ b/sys/xfs/xfs_message.h
@@ -1,6 +1,5 @@
-/* $OpenBSD: xfs_message.h,v 1.1 1998/08/31 05:13:27 art Exp $ */
/*
- * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -37,16 +36,22 @@
* SUCH DAMAGE.
*/
-/* $KTH: xfs_message.h,v 1.21 1998/06/27 11:05:24 assar Exp $ */
+/* $Id: xfs_message.h,v 1.2 1999/04/30 01:59:00 art Exp $ */
-#ifndef _SYS_XFS_MESSAGE_H_
-#define _SYS_XFS_MESSAGE_H_
+#ifndef _xmsg_h
+#define _xmsg_h
+#if !defined(__LINUX__) && !defined(HAVE_GLIBC)
#include <sys/types.h>
#include <sys/param.h>
+#else
+#include <linux/types.h>
+#include <linux/param.h>
+#endif
#include <xfs/xfs_attr.h>
+/* Temporary hack? */
#define MAX_XMSG_SIZE (1024*64)
typedef u_int32_t pag_t;
@@ -54,29 +59,36 @@ typedef u_int32_t pag_t;
/*
* The xfs_cred, if pag == 0, use uid
*/
-struct xfs_cred {
- __kernel_uid_t uid;
- pag_t pag;
-};
+typedef struct xfs_cred {
+ __kernel_uid_t uid;
+ pag_t pag;
+} xfs_cred;
+
+typedef unsigned long xfs_locktype_t;
+typedef unsigned long xfs_lockid_t;
-typedef struct xfs_cred xfs_cred;
-#define MAXHANDLE (4*4)
-#define MAXRIGHTS 8
+#define MAXHANDLE (4*4)
+#define MAXRIGHTS 8
+
+#define XFS_ANONYMOUSID 32766
-#define XFS_ANONYMOUSID 32766
typedef struct xfs_handle {
- u_int a, b, c, d;
+ u_int a, b, c, d;
} xfs_handle;
+
#define xfs_handle_eq(p, q) \
((p)->a == (q)->a && (p)->b == (q)->b && (p)->c == (q)->c && (p)->d == (q)->d)
+/*
+ * This should be the maximum size of any `file handle'
+ */
-#define CACHEHANDLESIZE 4
-struct xfs_cache_handle {
- u_char data[CACHEHANDLESIZE];
-};
-typedef struct xfs_cache_handle xfs_cache_handle;
+#define CACHEHANDLESIZE 80
+
+typedef struct xfs_cache_handle {
+ u_char data[CACHEHANDLESIZE];
+} xfs_cache_handle;
/*
* Tokens that apply to nodes, open modes and attributes. Shared
@@ -99,11 +111,11 @@ typedef struct xfs_cache_handle xfs_cache_handle;
#define XFS_DATA_R 0x0040 /* Data valid */
#define XFS_DATA_W 0x0080 /* Data valid and modifiable */
#define XFS_LOCK_MASK 0x0300
-#define XFS_LOCK_R 0x0100 /* Data Shared locks? */
-#define XFS_LOCK_W 0x0200 /* Data Exclusive locks? */
+#define XFS_LOCK_R 0x0100 /* Data Shared locks */
+#define XFS_LOCK_W 0x0200 /* Data Exclusive locks */
-#define XFS_ATTR_VALID XFS_ATTR_R
-#define XFS_DATA_VALID XFS_DATA_W
+#define XFS_ATTR_VALID XFS_ATTR_R
+#define XFS_DATA_VALID XFS_DATA_W
/* xfs_node.flags */
#define XFS_DATA_DIRTY 0x0001
@@ -120,21 +132,21 @@ typedef struct xfs_cache_handle xfs_cache_handle;
#define XFS_RIGHT_X 0x04 /* may execute? */
struct xfs_msg_node {
- xfs_handle handle;
- u_int tokens;
- struct xfs_attr attr;
- pag_t id[MAXRIGHTS];
- u_char rights[MAXRIGHTS];
- u_char anonrights;
+ xfs_handle handle;
+ u_int tokens;
+ struct xfs_attr attr;
+ pag_t id[MAXRIGHTS];
+ u_char rights[MAXRIGHTS];
+ u_char anonrights;
};
/*
* Messages passed through the xfs_dev.
*/
struct xfs_message_header {
- u_int size;
- u_int opcode;
- u_int sequence_num; /* Private */
+ u_int size;
+ u_int opcode;
+ u_int sequence_num; /* Private */
};
/*
@@ -148,6 +160,12 @@ enum { XFS_READ = 1, XFS_WRITE = 2, XFS_NONBLOCK = 4, XFS_APPEND = 8};
enum { XFS_NOREFS = 1, XFS_DELETE = 2 };
/*
+ * Flags for installdata
+ */
+
+enum { XFS_INVALID_DNLC = 1 };
+
+/*
* Defined message types and their opcodes.
*/
#define XFS_MSG_VERSION 0
@@ -188,195 +206,218 @@ enum { XFS_NOREFS = 1, XFS_DELETE = 2 };
#define XFS_MSG_PIOCTL 22
#define XFS_MSG_WAKEUP_DATA 23
-#define XFS_MSG_COUNT 24
+#define XFS_MSG_UPDATEFID 24
+
+#define XFS_MSG_ADVLOCK 25
+
+#define XFS_MSG_COUNT 26
/* XFS_MESSAGE_WAKEUP */
struct xfs_message_wakeup {
- struct xfs_message_header header;
- int sleepers_sequence_num; /* Where to send wakeup */
- int error; /* Return value */
+ struct xfs_message_header header;
+ int sleepers_sequence_num; /* Where to send wakeup */
+ int error; /* Return value */
};
/* XFS_MESSAGE_GETROOT */
struct xfs_message_getroot {
- struct xfs_message_header header;
- struct xfs_cred cred;
+ struct xfs_message_header header;
+ struct xfs_cred cred;
};
/* XFS_MESSAGE_INSTALLROOT */
struct xfs_message_installroot {
- struct xfs_message_header header;
- struct xfs_msg_node node;
+ struct xfs_message_header header;
+ struct xfs_msg_node node;
};
/* XFS_MESSAGE_GETNODE */
struct xfs_message_getnode {
- struct xfs_message_header header;
- struct xfs_cred cred;
- xfs_handle parent_handle;
- char name[256]; /* XXX */
+ struct xfs_message_header header;
+ struct xfs_cred cred;
+ xfs_handle parent_handle;
+ char name[256]; /* XXX */
};
/* XFS_MESSAGE_INSTALLNODE */
struct xfs_message_installnode {
- struct xfs_message_header header;
- xfs_handle parent_handle;
- char name[256]; /* XXX */
- struct xfs_msg_node node;
+ struct xfs_message_header header;
+ xfs_handle parent_handle;
+ char name[256]; /* XXX */
+ struct xfs_msg_node node;
};
/* XFS_MESSAGE_GETATTR */
struct xfs_message_getattr {
- struct xfs_message_header header;
- struct xfs_cred cred;
- xfs_handle handle;
+ struct xfs_message_header header;
+ struct xfs_cred cred;
+ xfs_handle handle;
};
/* XFS_MESSAGE_INSTALLATTR */
struct xfs_message_installattr {
- struct xfs_message_header header;
- struct xfs_msg_node node;
+ struct xfs_message_header header;
+ struct xfs_msg_node node;
};
/* XFS_MESSAGE_GETDATA */
struct xfs_message_getdata {
- struct xfs_message_header header;
- struct xfs_cred cred;
- xfs_handle handle;
- u_int tokens;
+ struct xfs_message_header header;
+ struct xfs_cred cred;
+ xfs_handle handle;
+ u_int tokens;
};
/* XFS_MESSAGE_INSTALLDATA */
struct xfs_message_installdata {
- struct xfs_message_header header;
- struct xfs_msg_node node;
- struct xfs_cache_handle cache_handle;
+ struct xfs_message_header header;
+ struct xfs_msg_node node;
+ char cache_name[256]; /* XXX */
+ struct xfs_cache_handle cache_handle;
+ u_int flag;
};
/* XFS_MSG_INACTIVENODE */
struct xfs_message_inactivenode {
- struct xfs_message_header header;
- xfs_handle handle;
- u_int flag;
+ struct xfs_message_header header;
+ xfs_handle handle;
+ u_int flag;
};
/* XFS_MSG_INVALIDNODE */
struct xfs_message_invalidnode {
- struct xfs_message_header header;
- xfs_handle handle;
+ struct xfs_message_header header;
+ xfs_handle handle;
};
/* XFS_MSG_OPEN */
struct xfs_message_open {
- struct xfs_message_header header;
- struct xfs_cred cred;
- xfs_handle handle;
- u_int tokens;
+ struct xfs_message_header header;
+ struct xfs_cred cred;
+ xfs_handle handle;
+ u_int tokens;
};
/* XFS_MSG_PUTDATA */
struct xfs_message_putdata {
- struct xfs_message_header header;
- xfs_handle handle;
- struct xfs_attr attr;
- struct xfs_cred cred;
- u_int flag;
+ struct xfs_message_header header;
+ xfs_handle handle;
+ struct xfs_attr attr; /* XXX ??? */
+ struct xfs_cred cred;
+ u_int flag;
};
/* XFS_MSG_PUTATTR */
struct xfs_message_putattr {
- struct xfs_message_header header;
- xfs_handle handle;
- struct xfs_attr attr;
- struct xfs_cred cred;
+ struct xfs_message_header header;
+ xfs_handle handle;
+ struct xfs_attr attr;
+ struct xfs_cred cred;
};
/* XFS_MSG_CREATE */
struct xfs_message_create {
- struct xfs_message_header header;
- xfs_handle parent_handle;
- char name[256]; /* XXX */
- struct xfs_attr attr;
-#if 0 /* XXX ??? */
- enum vcexcl exclusive;
-#endif
- int mode;
- struct xfs_cred cred;
+ struct xfs_message_header header;
+ xfs_handle parent_handle;
+ char name[256]; /* XXX */
+ struct xfs_attr attr;
+ int mode;
+ struct xfs_cred cred;
};
/* XFS_MSG_MKDIR */
struct xfs_message_mkdir {
- struct xfs_message_header header;
- xfs_handle parent_handle;
- char name[256]; /* XXX */
- struct xfs_attr attr;
- struct xfs_cred cred;
+ struct xfs_message_header header;
+ xfs_handle parent_handle;
+ char name[256]; /* XXX */
+ struct xfs_attr attr;
+ struct xfs_cred cred;
};
/* XFS_MSG_LINK */
struct xfs_message_link {
- struct xfs_message_header header;
- xfs_handle parent_handle;
- char name[256]; /* XXX */
- xfs_handle from_handle;
- struct xfs_cred cred;
+ struct xfs_message_header header;
+ xfs_handle parent_handle;
+ char name[256]; /* XXX */
+ xfs_handle from_handle;
+ struct xfs_cred cred;
};
/* XFS_MSG_SYMLINK */
struct xfs_message_symlink {
- struct xfs_message_header header;
- xfs_handle parent_handle;
- char name[256]; /* XXX */
- char contents[2048]; /* XXX */
- struct xfs_attr attr;
- struct xfs_cred cred;
+ struct xfs_message_header header;
+ xfs_handle parent_handle;
+ char name[256]; /* XXX */
+ char contents[2048]; /* XXX */
+ struct xfs_attr attr;
+ struct xfs_cred cred;
};
/* XFS_MSG_REMOVE */
struct xfs_message_remove {
- struct xfs_message_header header;
- xfs_handle parent_handle;
- char name[256]; /* XXX */
- struct xfs_cred cred;
+ struct xfs_message_header header;
+ xfs_handle parent_handle;
+ char name[256]; /* XXX */
+ struct xfs_cred cred;
};
/* XFS_MSG_RMDIR */
struct xfs_message_rmdir {
- struct xfs_message_header header;
- xfs_handle parent_handle;
- char name[256]; /* XXX */
- struct xfs_cred cred;
+ struct xfs_message_header header;
+ xfs_handle parent_handle;
+ char name[256]; /* XXX */
+ struct xfs_cred cred;
};
/* XFS_MSG_RENAME */
struct xfs_message_rename {
- struct xfs_message_header header;
- xfs_handle old_parent_handle;
- char old_name[256]; /* XXX */
- xfs_handle new_parent_handle;
- char new_name[256]; /* XXX */
- struct xfs_cred cred;
+ struct xfs_message_header header;
+ xfs_handle old_parent_handle;
+ char old_name[256]; /* XXX */
+ xfs_handle new_parent_handle;
+ char new_name[256]; /* XXX */
+ struct xfs_cred cred;
};
/* XFS_MSG_PIOCTL */
struct xfs_message_pioctl {
- struct xfs_message_header header;
- int opcode ;
- xfs_cred cred;
- int insize;
- int outsize;
- char msg[2048]; /* XXX */
- xfs_handle handle;
+ struct xfs_message_header header;
+ int opcode ;
+ xfs_cred cred;
+ int insize;
+ int outsize;
+ char msg[2048] ; /* XXX */
+ xfs_handle handle;
};
/* XFS_MESSAGE_WAKEUP_DATA */
struct xfs_message_wakeup_data {
- struct xfs_message_header header;
- int sleepers_sequence_num; /* Where to send wakeup */
- int error; /* Return value */
- int len;
- char msg[2048]; /* XXX */
+ struct xfs_message_header header;
+ int sleepers_sequence_num; /* Where to send wakeup */
+ int error; /* Return value */
+ int len;
+ char msg[2048] ; /* XXX */
+};
+
+/* XFS_MESSAGE_UPDATEFID */
+struct xfs_message_updatefid {
+ struct xfs_message_header header;
+ xfs_handle old_handle;
+ xfs_handle new_handle;
+};
+
+/* XFS_MESSAGE_ADVLOCK */
+struct xfs_message_advlock {
+ struct xfs_message_header header;
+ xfs_handle handle;
+ struct xfs_cred cred;
+ xfs_locktype_t locktype;
+#define XFS_WR_LOCK 1 /* Write lock */
+#define XFS_RD_LOCK 2 /* Read lock */
+#define XFS_UN_LOCK 3 /* Unlock */
+#define XFS_BR_LOCK 4 /* Break lock (inform that we don't want the lock) */
+ xfs_lockid_t lockid;
};
#endif /* _xmsg_h */
diff --git a/sys/xfs/xfs_msg_locl.h b/sys/xfs/xfs_msg_locl.h
index 18fe0613a93..b552e8c148f 100644
--- a/sys/xfs/xfs_msg_locl.h
+++ b/sys/xfs/xfs_msg_locl.h
@@ -1,4 +1,3 @@
-/* $OpenBSD: xfs_msg_locl.h,v 1.2 1998/08/31 05:13:27 art Exp $ */
/*
* Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
@@ -37,25 +36,45 @@
* SUCH DAMAGE.
*/
-/* $KTH: xfs_msg_locl.h,v 1.1 1998/03/26 02:25:53 assar Exp $ */
-
-#ifndef _XFS_XFS_MSG_LOCL_H_
-#define _XFS_XFS_MSG_LOCL_H_
-
-int xfs_message_installroot __P((int fd,
- struct xfs_message_installroot *message,
- u_int size, struct proc *p));
-int xfs_message_installnode __P((int fd,
- struct xfs_message_installnode *message,
- u_int size,struct proc *p));
-int xfs_message_installattr __P((int fd,
- struct xfs_message_installattr *message,
- u_int size,struct proc *p));
-int xfs_message_installdata __P((int fd,
- struct xfs_message_installdata *message,
- u_int size, struct proc *p));
-int xfs_message_invalidnode __P((int fd,
- struct xfs_message_invalidnode *message,
- u_int size, struct proc *p));
-
-#endif
+/* $Id: xfs_msg_locl.h,v 1.3 1999/04/30 01:59:00 art Exp $ */
+
+#ifndef _xfs_msg_locl_h
+#define _xfs_msg_locl_h
+
+int
+xfs_message_installroot(int fd,
+ struct xfs_message_installroot * message,
+ u_int size,
+ struct proc *p);
+
+int
+xfs_message_installnode(int fd,
+ struct xfs_message_installnode * message,
+ u_int size,
+ struct proc *p);
+
+int
+xfs_message_installattr(int fd,
+ struct xfs_message_installattr * message,
+ u_int size,
+ struct proc *p);
+
+int
+xfs_message_installdata(int fd,
+ struct xfs_message_installdata * message,
+ u_int size,
+ struct proc *p);
+
+int
+xfs_message_invalidnode(int fd,
+ struct xfs_message_invalidnode * message,
+ u_int size,
+ struct proc *p);
+
+int
+xfs_message_updatefid(int fd,
+ struct xfs_message_updatefid * message,
+ u_int size,
+ struct proc *p);
+
+#endif /* _xfs_msg_locl_h */
diff --git a/sys/xfs/xfs_node-bsd.c b/sys/xfs/xfs_node-bsd.c
new file mode 100644
index 00000000000..71d1b8faae1
--- /dev/null
+++ b/sys/xfs/xfs_node-bsd.c
@@ -0,0 +1,590 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include <xfs/xfs_locl.h>
+#include <xfs/xfs_common.h>
+#include <xfs/xfs_fs.h>
+#include <xfs/xfs_deb.h>
+
+RCSID("$Id: xfs_node-bsd.c,v 1.1 1999/04/30 01:59:00 art Exp $");
+
+extern vop_t **xfs_vnodeop_p;
+
+/*
+ * Allocate a new vnode with handle `handle' in `mp' and return it in
+ * `vpp'. Return 0 or error.
+ */
+
+int
+xfs_getnewvnode(struct mount *mp, struct vnode **vpp,
+ struct xfs_handle *handle)
+{
+ struct xfs_node *result;
+ int error;
+
+ error = getnewvnode(VT_AFS, mp, xfs_vnodeop_p, vpp);
+ if (error)
+ return error;
+
+ result = xfs_alloc(sizeof(*result));
+ bzero(result, sizeof(*result));
+
+ (*vpp)->v_data = result;
+ result->vn = *vpp;
+
+ result->handle = *handle;
+ result->flags = 0;
+ result->tokens = 0;
+ result->vnlocks = 0;
+
+ result->anonrights = 0;
+
+ return 0;
+}
+
+/*
+ * Create a new xfs_node and make a vget
+ *
+ * Also prevents creation of duplicates. This happens
+ * whenever there are more than one name to a file,
+ * "." and ".." are common cases. */
+
+int
+new_xfs_node(struct xfs *xfsp,
+ struct xfs_msg_node *node,
+ struct xfs_node **xpp,
+ struct proc *p)
+{
+ int do_vget = 0;
+ struct xfs_node *result;
+
+ XFSDEB(XDEBNODE, ("new_xfs_node %d.%d.%d.%d\n",
+ node->handle.a,
+ node->handle.b,
+ node->handle.c,
+ node->handle.d));
+ again:
+ /* Does not allow duplicates */
+ result = xfs_node_find(xfsp, &node->handle);
+
+ if (result == 0) {
+ int error;
+ struct vnode *v;
+
+ error = xfs_getnewvnode(XFS_TO_VFS(xfsp), &v, &node->handle);
+ if (error)
+ return error;
+
+ result = VNODE_TO_XNODE(v);
+ result->anonrights = node->anonrights;
+
+ xfsp->nnodes++;
+ } else {
+ /* Node is already cached */
+#ifdef HAVE_LK_INTERLOCK
+ simple_lock(&(XNODE_TO_VNODE(result)->v_interlock));
+#endif
+ do_vget = 1;
+ }
+
+ /* Init other fields */
+ xfs_attr2vattr(&node->attr, &result->attr);
+ result->vn->v_type = result->attr.va_type;
+ XFS_TOKEN_SET(result, XFS_ATTR_R, XFS_ATTR_MASK);
+ bcopy(node->id, result->id, sizeof(result->id));
+ bcopy(node->rights, result->rights, sizeof(result->rights));
+
+ /*
+ * We need to postpone this until here because (on FreeBSD) vget
+ * tries to install a pager on the vnode and for that it wants to
+ * retrieve the size with getattr.
+ */
+
+ if (do_vget) {
+ if (xfs_do_vget(XNODE_TO_VNODE(result), LK_INTERLOCK, p))
+ goto again;
+ }
+
+ *xpp = result;
+ XFSDEB(XDEBNODE, ("return: new_xfs_node\n"));
+ return 0;
+}
+
+void
+free_xfs_node(struct xfs_node *node)
+{
+ struct xfs *xfsp = XFS_FROM_XNODE(node);
+
+ XFSDEB(XDEBNODE, ("free_xfs_node starting: node = %p\n", node));
+
+ /* XXX Really need to put back dirty data first. */
+
+ if (DATA_FROM_XNODE(node)) {
+ vrele(DATA_FROM_XNODE(node));
+ DATA_FROM_XNODE(node) = NULL;
+ }
+ xfsp->nnodes--;
+ XNODE_TO_VNODE(node)->v_data = NULL;
+ xfs_free(node, sizeof(*node));
+
+ XFSDEB(XDEBNODE, ("free_xfs_node done\n"));
+}
+
+int
+free_all_xfs_nodes(struct xfs *xfsp, int flags, int unmountp)
+{
+ int error = 0;
+ struct mount *mp = XFS_TO_VFS(xfsp);
+
+ if (mp == NULL) {
+ XFSDEB(XDEBNODE, ("free_all_xfs_nodes already freed\n"));
+ return 0;
+ }
+
+ XFSDEB(XDEBNODE, ("free_all_xfs_nodes starting\n"));
+
+ xfs_dnlc_purge_mp(mp);
+
+ if (xfsp->root) {
+ XFSDEB(XDEBNODE, ("free_all_xfs_nodes now removing root\n"));
+
+ vgone(XNODE_TO_VNODE(xfsp->root));
+ xfsp->root = 0;
+ }
+
+ XFSDEB(XDEBNODE, ("free_all_xfs_nodes root removed\n"));
+ XFSDEB(XDEBNODE, ("free_all_xfs_nodes now killing all remaining nodes\n"));
+
+#ifdef HAVE_STRUCT_MOUNT_MNT_SYNCER
+ if (!unmountp) {
+ XFSDEB(XDEBNODE, ("free_all_xfs_nodes not flushing syncer vnode\n"));
+ error = vflush(mp, mp->mnt_syncer, flags);
+ } else
+#endif
+ {
+ error = vflush(mp, NULL, flags);
+ }
+
+ if (error) {
+ XFSDEB(XDEBNODE, ("xfree_all_xfs_nodes: vflush() error == %d\n",
+ error));
+ return error;
+ }
+
+ XFSDEB(XDEBNODE, ("free_all_xfs_nodes done\n"));
+ return error;
+}
+
+struct xfs_node *
+xfs_node_find(struct xfs *xfsp, xfs_handle *handlep)
+{
+ struct vnode *t;
+ struct xfs_node *xn = NULL;
+
+ XFSDEB(XDEBNODE, ("xfs_node_find: xfsp = %p handlep = %p\n",
+ xfsp, handlep));
+
+ for(t = XFS_TO_VFS(xfsp)->mnt_vnodelist.lh_first;
+ t != NULL;
+ t = t->v_mntvnodes.le_next) {
+ xn = VNODE_TO_XNODE(t);
+ if (xn && xfs_handle_eq(&xn->handle, handlep))
+ break;
+ }
+
+ if (t != NULL)
+ return xn;
+ else
+ return NULL;
+}
+
+void
+vattr2xfs_attr(const struct vattr *va, struct xfs_attr *xa)
+{
+ bzero(xa, sizeof(*xa));
+ if (va->va_mode != (mode_t)VNOVAL)
+ XA_SET_MODE(xa, va->va_mode);
+ if (va->va_nlink != VNOVAL)
+ XA_SET_NLINK(xa, va->va_nlink);
+ if (va->va_size != VNOVAL)
+ XA_SET_SIZE(xa, va->va_size);
+ if (va->va_uid != VNOVAL)
+ XA_SET_UID(xa, va->va_uid);
+ if (va->va_gid != VNOVAL)
+ XA_SET_GID(xa, va->va_gid);
+ if (va->va_atime.tv_sec != VNOVAL)
+ XA_SET_ATIME(xa, va->va_atime.tv_sec);
+ if (va->va_mtime.tv_sec != VNOVAL)
+ XA_SET_MTIME(xa, va->va_mtime.tv_sec);
+ if (va->va_ctime.tv_sec != VNOVAL)
+ XA_SET_CTIME(xa, va->va_ctime.tv_sec);
+ if (va->va_fileid != VNOVAL)
+ XA_SET_FILEID(xa, va->va_fileid);
+ switch (va->va_type) {
+ case VNON:
+ xa->xa_type = XFS_FILE_NON;
+ break;
+ case VREG:
+ xa->xa_type = XFS_FILE_REG;
+ break;
+ case VDIR:
+ xa->xa_type = XFS_FILE_DIR;
+ break;
+ case VBLK:
+ xa->xa_type = XFS_FILE_BLK;
+ break;
+ case VCHR:
+ xa->xa_type = XFS_FILE_CHR;
+ break;
+ case VLNK:
+ xa->xa_type = XFS_FILE_LNK;
+ break;
+ case VSOCK:
+ xa->xa_type = XFS_FILE_SOCK;
+ break;
+ case VFIFO:
+ xa->xa_type = XFS_FILE_FIFO;
+ break;
+ case VBAD:
+ xa->xa_type = XFS_FILE_BAD;
+ break;
+ default:
+ panic("xfs_attr2attr: bad value");
+ }
+}
+
+#define SET_TIMEVAL(X, S, N) do { (X)->tv_sec = (S); (X)->tv_nsec = (N); } while(0)
+
+void
+xfs_attr2vattr(const struct xfs_attr *xa, struct vattr *va)
+{
+ VATTR_NULL(va);
+ if (XA_VALID_MODE(xa))
+ va->va_mode = xa->xa_mode;
+ if (XA_VALID_NLINK(xa))
+ va->va_nlink = xa->xa_nlink;
+ if (XA_VALID_SIZE(xa))
+ va->va_size = xa->xa_size;
+ if (XA_VALID_UID(xa))
+ va->va_uid = xa->xa_uid;
+ if (XA_VALID_GID(xa))
+ va->va_gid = xa->xa_gid;
+ if (XA_VALID_ATIME(xa)) {
+ SET_TIMEVAL(&va->va_atime, xa->xa_atime, 0);
+ }
+ if (XA_VALID_MTIME(xa)) {
+ SET_TIMEVAL(&va->va_mtime, xa->xa_mtime, 0);
+ }
+ if (XA_VALID_CTIME(xa)) {
+ SET_TIMEVAL(&va->va_ctime, xa->xa_ctime, 0);
+ }
+ if (XA_VALID_FILEID(xa)) {
+ va->va_fileid = xa->xa_fileid;
+ }
+ if (XA_VALID_TYPE(xa)) {
+ switch (xa->xa_type) {
+ case XFS_FILE_NON:
+ va->va_type = VNON;
+ break;
+ case XFS_FILE_REG:
+ va->va_type = VREG;
+ break;
+ case XFS_FILE_DIR:
+ va->va_type = VDIR;
+ break;
+ case XFS_FILE_BLK:
+ va->va_type = VBLK;
+ break;
+ case XFS_FILE_CHR:
+ va->va_type = VCHR;
+ break;
+ case XFS_FILE_LNK:
+ va->va_type = VLNK;
+ break;
+ case XFS_FILE_SOCK:
+ va->va_type = VSOCK;
+ break;
+ case XFS_FILE_FIFO:
+ va->va_type = VFIFO;
+ break;
+ case XFS_FILE_BAD:
+ va->va_type = VBAD;
+ break;
+ default:
+ panic("xfs_attr2vattr: bad value");
+ }
+ }
+ va->va_flags = 0;
+ va->va_blocksize = 8192;
+ va->va_bytes = va->va_size;
+}
+
+/*
+ * A single entry DNLC for systems for handling long names that don't
+ * get put into the system DNLC.
+ */
+
+struct long_entry {
+ struct vnode *dvp, *vp;
+ char name[MAXNAMLEN + 1];
+ size_t len;
+ u_long dvpid, vpid;
+};
+
+static struct long_entry tbl;
+
+/*
+ * Nuke the `tbl'
+ */
+
+static void
+tbl_clear (void)
+{
+ tbl.dvp = tbl.vp = NULL;
+ tbl.name[0] = '\0';
+ tbl.len = 0;
+ tbl.dvpid = tbl.vpid = 0;
+}
+
+/*
+ * Set the entry in the `tbl'
+ */
+
+static void
+tbl_enter (size_t len, const char *name, struct vnode *dvp, struct vnode *vp)
+{
+ tbl.len = len;
+ bcopy(name, tbl.name, len);
+ tbl.dvp = dvp;
+ tbl.vp = vp;
+ tbl.dvpid = dvp->v_id;
+ tbl.vpid = vp->v_id;
+}
+
+/*
+ * Lookup in tbl
+ */
+
+static int
+tbl_lookup (size_t len, const char *name, struct vnode *dvp, struct vnode **res)
+{
+ if (tbl.dvp == dvp
+ && tbl.len == len
+ && strncmp(tbl.name, name, len) == 0
+ && tbl.dvpid == tbl.dvp->v_id
+ && tbl.vpid == tbl.vp->v_id) {
+ *res = tbl.vp;
+ return -1;
+ } else
+ return 0;
+}
+
+/*
+ * Store a componentname in the DNLC
+ */
+
+int
+xfs_dnlc_enter(struct vnode *dvp,
+ xfs_componentname *cnp,
+ struct vnode *vp)
+{
+ XFSDEB(XDEBDNLC, ("xfs_dnlc_enter_cnp(%p, %p, %p)\n", dvp, cnp, vp));
+ XFSDEB(XDEBDNLC, ("xfs_dnlc_enter: v_id = %ld\n", dvp->v_id));
+
+ XFSDEB(XDEBDNLC, ("xfs_dnlc_enter: calling cache_enter:"
+ "dvp = %p, vp = %p, cnp = (%s, %ld, %lu), "
+ "nameiop = %lu, flags = %lx\n",
+ dvp, vp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_hash,
+ cnp->cn_nameiop, cnp->cn_flags));
+
+#ifdef NCHNAMLEN
+ if (cnp->cn_namelen <= NCHNAMLEN)
+#endif
+ {
+ /*
+ * This is to make sure there's no negative entry already in the dnlc
+ */
+ u_long save_nameiop;
+ struct vnode *dummy;
+
+ save_nameiop = cnp->cn_nameiop;
+ cnp->cn_nameiop = CREATE;
+
+ if (cache_lookup(dvp, &dummy, cnp) != 0) {
+ printf ("XFS PANIC WARNING! xfs_dnlc_enter: %s already in cache\n",
+ cnp->cn_nameptr);
+ }
+
+ cnp->cn_nameiop = save_nameiop;
+ cache_enter(dvp, vp, cnp);
+ }
+
+ if (vp != NULL)
+ tbl_enter (cnp->cn_namelen, cnp->cn_nameptr, dvp, vp);
+
+ return 0;
+}
+
+
+void
+xfs_cnp_init (struct componentname *cn,
+ const char *name, struct vnode *vp, struct vnode *dvp,
+ struct proc *proc, struct ucred *cred,
+ int nameiop)
+{
+ char *p ;
+
+ bzero(cn, sizeof(*cn));
+ cn->cn_nameptr = (char *)name;
+ cn->cn_namelen = strlen(name);
+ cn->cn_flags = 0;
+ cn->cn_hash = 0;
+ for (p = cn->cn_nameptr; *p; ++p)
+ cn->cn_hash += *p;
+ cn->cn_nameiop = nameiop;
+ cn->cn_proc = proc;
+ cn->cn_cred = cred;
+}
+
+
+/*
+ * Store (dvp, name, vp) in the DNLC
+ */
+
+int
+xfs_dnlc_enter_name(struct vnode *dvp,
+ const char *name,
+ struct vnode *vp)
+{
+ struct componentname cn;
+ const char *p;
+
+ XFSDEB(XDEBDNLC, ("xfs_dnlc_enter_name(%p, \"%s\", %p)\n", dvp, name, vp));
+
+ cn.cn_nameiop = LOOKUP;
+ cn.cn_flags = 0;
+ cn.cn_namelen = strlen(name);
+ cn.cn_nameptr = (char *)name;
+ cn.cn_hash = 0;
+ for (p = cn.cn_nameptr; *p; ++p)
+ cn.cn_hash += *p;
+
+ return xfs_dnlc_enter (dvp, &cn, vp);
+}
+
+/*
+ * Lookup (dvp, cnp) in the DNLC and return the result in `res'.
+ * Return -1 if succesful, 0 if not and ENOENT if we're sure it doesn't exist.
+ */
+
+int
+xfs_dnlc_lookup(struct vnode *dvp,
+ xfs_componentname *cnp,
+ struct vnode **res)
+{
+ int error;
+ u_long saved_flags;
+
+ XFSDEB(XDEBDNLC, ("xfs_dnlc_lookup(%p, \"%s\")\n", dvp, cnp->cn_nameptr));
+
+ XFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: v_id = %ld\n", dvp->v_id));
+
+ XFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: calling cache_lookup:"
+ "dvp = %p, cnp = (%s, %ld, %lu), flags = %lx\n",
+ dvp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_hash,
+ cnp->cn_flags));
+
+ saved_flags = cnp->cn_flags;
+ cnp->cn_flags |= MAKEENTRY;
+
+ error = cache_lookup(dvp, res, cnp);
+
+ cnp->cn_flags = saved_flags;
+
+ XFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: cache_lookup returned. "
+ "error = %d, *res = %p\n", error, *res));
+
+ if (error == -1 || error == ENOENT)
+ return error;
+
+ return tbl_lookup (cnp->cn_namelen, cnp->cn_nameptr, dvp, res);
+}
+
+/*
+ * Remove one entry from the DNLC
+ */
+
+void
+xfs_dnlc_purge (struct vnode *vp)
+{
+ XFSDEB(XDEBDNLC, ("xfs_dnlc_purge\n"));
+
+ if (tbl.dvp == vp || tbl.vp == vp)
+ tbl_clear ();
+
+ cache_purge(vp);
+}
+
+/*
+ * Remove all entries belong to `mp' from the DNLC
+ */
+
+void
+xfs_dnlc_purge_mp(struct mount *mp)
+{
+ XFSDEB(XDEBDNLC, ("xfs_dnlc_purge_mp()\n"));
+
+ tbl_clear ();
+ cache_purgevfs(mp);
+}
+
+/*
+ * Returns 1 if pag has any rights set in the node
+ */
+
+int
+xfs_has_pag(const struct xfs_node *xn, pag_t pag)
+{
+ int i;
+
+ for (i = 0; i < MAXRIGHTS; i++)
+ if (xn->id[i] == pag)
+ return 1;
+
+ return 0;
+}
diff --git a/sys/xfs/xfs_node.h b/sys/xfs/xfs_node.h
index 6e64c14b657..a77ab61d993 100644
--- a/sys/xfs/xfs_node.h
+++ b/sys/xfs/xfs_node.h
@@ -1,4 +1,3 @@
-/* $OpenBSD: xfs_node.h,v 1.3 1998/09/06 01:48:58 art Exp $ */
/*
* Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
@@ -37,36 +36,90 @@
* SUCH DAMAGE.
*/
-/* $KTH: xfs_node.h,v 1.3 1998/07/13 20:36:37 art Exp $ */
+/* $Id: xfs_node.h,v 1.4 1999/04/30 01:59:01 art Exp $ */
-#ifndef _XFS_XFS_NODE_H_
-#define _XFS_XFS_NODE_H_
+#ifndef _xfs_xnode_h
+#define _xfs_xnode_h
-#if 0
#include <sys/types.h>
#include <sys/time.h>
+#if defined(_KERNEL) || !defined(__OpenBSD__)
#include <sys/vnode.h>
#endif
+#ifdef __NetBSD__
+#include <sys/lockf.h>
+#endif /* __NetBSD__ */
#include <xfs/xfs_attr.h>
#include <xfs/xfs_message.h>
struct xfs_node {
- struct vnode *vn;
- struct vnode *data;
- struct vattr attr;
- u_int flags;
- u_int tokens;
- xfs_handle handle;
- pag_t id[MAXRIGHTS];
- u_char rights[MAXRIGHTS];
- u_char anonrights;
+ struct vnode *vn;
+ struct vnode *data;
+ struct vattr attr;
+ u_int flags;
+ u_int tokens;
+ xfs_handle handle;
+ pag_t id[MAXRIGHTS];
+ u_char rights[MAXRIGHTS];
+ u_char anonrights;
+ int vnlocks;
+#ifdef __NetBSD__
+ struct lockf *i_lockf;
+#endif
};
+int xfs_getnewvnode(struct mount *mp, struct vnode **vpp,
+ struct xfs_handle *handle);
+
+
#define DATA_FROM_VNODE(vp) DATA_FROM_XNODE(VNODE_TO_XNODE(vp))
+
#define DATA_FROM_XNODE(xp) ((xp)->data)
#define XNODE_TO_VNODE(xp) ((xp)->vn)
#define VNODE_TO_XNODE(vp) ((struct xfs_node *) (vp)->v_data)
+#if defined(HAVE_THREE_ARGUMENT_VGET)
+#define xfs_do_vget(vp, lockflag, proc) vget((vp), (lockflag), (proc))
+#elif !defined(__osf__)
+#define xfs_do_vget(vp, lockflag, proc) vget((vp), (lockflag))
+#else
+#define xfs_do_vget(vp, lockflag, proc) vget((vp))
+#endif
+
+#ifndef HAVE_VOP_T
+typedef int vop_t (void *);
+#endif
+
+#ifdef LK_INTERLOCK
+#define HAVE_LK_INTERLOCK
+#else
+#define LK_INTERLOCK 0
+#endif
+
+#ifdef LK_RETRY
+#define HAVE_LK_RETRY
+#else
+#define LK_RETRY 0
#endif
+
+/*
+ * This is compat code for older vfs that have a
+ * vget that only take a integer (really boolean) argument
+ * that the the returned vnode will be returned locked
+ */
+
+#ifdef LK_EXCLUSIVE
+#define HAVE_LK_EXCLUSIVE 1
+#else
+#define LK_EXCLUSIVE 1
+#endif
+
+#ifdef LK_SHARED
+#define HAVE_LK_SHARED 1
+#else
+#define LK_SHARED 1
+#endif
+
+#endif /* _xfs_xnode_h */
diff --git a/sys/xfs/xfs_pioctl.h b/sys/xfs/xfs_pioctl.h
index 76ab12cf8a0..ee2d499df0b 100644
--- a/sys/xfs/xfs_pioctl.h
+++ b/sys/xfs/xfs_pioctl.h
@@ -1,6 +1,6 @@
-/* $OpenBSD: xfs_pioctl.h,v 1.2 1998/09/17 20:47:15 art Exp $ */
+/* $OpenBSD: xfs_pioctl.h,v 1.3 1999/04/30 01:59:01 art Exp $ */
/*
- * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -18,7 +18,7 @@
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
- * Högskolan and its contributors.
+ * Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -37,8 +37,8 @@
* SUCH DAMAGE.
*/
-#ifndef _SYS_PIOCTL_H_
-#define _SYS_PIOCTL_H_
+#ifndef _XFS_XFS_PIOCTL_H_
+#define _XFS_XFS_PIOCTL_H_
/*
*/
@@ -111,9 +111,28 @@
#define VIOC_TWIDDLE _VICEIOCTL(45)
#define VIOC_SETSPREFS _VICEIOCTL(46)
#define VIOC_STORBEHIND _VICEIOCTL(47)
-#define VIOC_GETRXKCRYPT _VICEIOCTL(48)
-#define VIOC_SETRXKCRYPT _VICEIOCTL(49)
-#define VIOC_FPRIOSTATUS _VICEIOCTL(50)
+#define VIOC_GCPAGS _VICEIOCTL(48)
+#define VIOC_GETRXKCRYPT _VICEIOCTL(49)
+#define VIOC_SETRXKCRYPT _VICEIOCTL(50)
+#define VIOC_FPRIOSTATUS _VICEIOCTL(51)
+
+#define VIOC_FHGET _VICEIOCTL(52)
+#define VIOC_FHOPEN _VICEIOCTL(53)
+
+#define VIOC_XFSDEBUG _VICEIOCTL(54)
+#define VIOC_ARLADEBUG _VICEIOCTL(55)
+
+#define VIOC_AVIATOR _VICEIOCTL(56)
+
+#define VIOC_XFSDEBUG_PRINT _VICEIOCTL(57)
+
+/*
+ * GETCELLSTATUS flags
+ */
+
+#define CELLSTATUS_PRIMARY 0x01 /* this is the `primary' cell */
+#define CELLSTATUS_SETUID 0x02 /* setuid honored for this cell */
+#define CELLSTATUS_OBSOLETE_VL 0x04 /* uses obsolete VL servers */
/*
* VIOCCONNECTMODE arguments
@@ -123,6 +142,7 @@
#define CONNMODE_CONN 1
#define CONNMODE_FETCH 2
#define CONNMODE_DISCONN 3
+#define CONNMODE_PARCONNECTED 4
/*
* The struct for VIOC_FPRIOSTATUS
@@ -146,6 +166,16 @@ struct vioc_fprio {
int32_t Unique;
};
+/*
+ * Flags for VIOCCKSERV
+ */
+
+#define CKSERV_DONTPING 1
+#define CKSERV_FSONLY 2
+
+#define CKSERV_MAXSERVERS 16 /* limitation of VIOCCKSERV number of
+ returned servers */
+
struct ViceIoctl {
caddr_t in, out;
short in_size;
diff --git a/sys/xfs/xfs_syscalls-common.c b/sys/xfs/xfs_syscalls-common.c
new file mode 100644
index 00000000000..6dc34eb611e
--- /dev/null
+++ b/sys/xfs/xfs_syscalls-common.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include <xfs/xfs_locl.h>
+
+RCSID("$Id: xfs_syscalls-common.c,v 1.1 1999/04/30 01:59:01 art Exp $");
+
+/*
+ * XFS system calls.
+ */
+
+#include <xfs/xfs_syscalls.h>
+#include <xfs/xfs_message.h>
+#include <xfs/xfs_fs.h>
+#include <xfs/xfs_dev.h>
+#include <xfs/xfs_node.h>
+#include <xfs/xfs_vfsops.h>
+#include <xfs/xfs_deb.h>
+
+/* Misc syscalls */
+#ifdef HAVE_SYS_IOCCOM_H
+#include <sys/ioccom.h>
+#elif defined(HAVE_SYS_IOCTL_H)
+#include <sys/ioctl.h>
+#endif
+#include <xfs/xfs_pioctl.h>
+
+/*
+ * the syscall entry point
+ */
+
+int
+sys_xfspioctl(struct proc *proc, void *varg, register_t *return_value)
+{
+ struct sys_pioctl_args *arg = (struct sys_pioctl_args *) varg;
+ int error = EINVAL;
+
+ switch (SCARG(arg, operation)) {
+ case AFSCALL_PIOCTL:
+ error = xfs_pioctl_call(proc, varg, return_value);
+ break;
+ case AFSCALL_SETPAG:
+ error = xfs_setpag_call(&xfs_proc_to_cred(proc));
+ break;
+ default:
+ XFSDEB(XDEBSYS, ("Unimplemeted xfspioctl: %d\n",
+ SCARG(arg, operation)));
+ error = EINVAL;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * Def pag:
+ * 33536 <= g0 <= 34560
+ * 32512 <= g1 <= 48896
+ */
+
+#define XFS_PAG1_LLIM 33536
+#define XFS_PAG1_ULIM 34560
+#define XFS_PAG2_LLIM 32512
+#define XFS_PAG2_ULIM 48896
+
+static gid_t pag_part_one = XFS_PAG1_LLIM;
+static gid_t pag_part_two = XFS_PAG2_LLIM;
+
+/*
+ * Is `cred' member of a PAG?
+ */
+
+static int
+xfs_is_pag(struct ucred *cred)
+{
+ /* The first group is the gid of the user ? */
+
+ if (cred->cr_ngroups >= 3 &&
+ cred->cr_groups[1] >= XFS_PAG1_LLIM &&
+ cred->cr_groups[1] <= XFS_PAG1_ULIM &&
+ cred->cr_groups[2] >= XFS_PAG2_LLIM &&
+ cred->cr_groups[2] <= XFS_PAG2_ULIM)
+ return 1;
+ else
+ return 0;
+}
+
+/*
+ * Return the pag used by `cred'
+ */
+
+pag_t
+xfs_get_pag(struct ucred *cred)
+{
+ if (xfs_is_pag(cred)) {
+
+ return (((cred->cr_groups[1] << 16) & 0xFFFF0000) |
+ ((cred->cr_groups[2] & 0x0000FFFF)));
+
+ } else
+ return cred->cr_uid; /* XXX */
+}
+
+/*
+ * Acquire a new pag in `ret_cred'
+ */
+
+int
+xfs_setpag_call(struct ucred **ret_cred)
+{
+ struct ucred *cred = *ret_cred;
+ int i;
+
+ if (!xfs_is_pag(cred)) {
+
+ /* Check if it fits */
+ if (cred->cr_ngroups + 2 >= NGROUPS)
+ return E2BIG; /* XXX Hmmm, better error ? */
+
+ cred = crcopy (cred);
+
+ /* Copy the groups */
+ for (i = cred->cr_ngroups - 1; i > 0; i--) {
+ cred->cr_groups[i + 2] = cred->cr_groups[i];
+ }
+ cred->cr_ngroups += 2;
+
+ } else
+ cred = crcopy(cred);
+
+ cred->cr_groups[1] = pag_part_one;
+ cred->cr_groups[2] = pag_part_two++;
+
+ if (pag_part_two > XFS_PAG2_ULIM) {
+ pag_part_one++;
+ pag_part_two = XFS_PAG2_LLIM;
+ }
+ *ret_cred = cred;
+ return 0;
+}
+
+/*
+ * Return the vnode corresponding to `pathptr'
+ */
+
+static int
+lookup_node (const char *pathptr,
+ int follow_links_p,
+ struct vnode **res,
+ struct proc *proc)
+{
+ int error;
+ char path[MAXPATHLEN];
+#ifdef __osf__
+ struct nameidata *ndp = &u.u_nd;
+#else
+ struct nameidata nd, *ndp = &nd;
+#endif
+ struct vnode *vp;
+ size_t done;
+
+ XFSDEB(XDEBSYS, ("xfs_syscall: looking up: %p\n", pathptr));
+
+ error = copyinstr(pathptr, path, MAXPATHLEN, &done);
+
+ XFSDEB(XDEBSYS, ("xfs_syscall: looking up: %s len: %lu error: %d\n",
+ path, (unsigned long)done, error));
+
+ if (error)
+ return error;
+
+ NDINIT(ndp, LOOKUP,
+ follow_links_p ? FOLLOW : 0,
+ UIO_SYSSPACE, path, proc);
+
+ error = namei(ndp);
+
+ if (error != 0) {
+ XFSDEB(XDEBSYS, ("xfs_syscall: error during namei: %d\n", error));
+ return EINVAL;
+ }
+
+ vp = ndp->ni_vp;
+
+ *res = vp;
+ return 0;
+}
+
+/*
+ * return file handle of `vp' in vice_ioctl->out
+ */
+
+static int
+fhget_call (struct proc *p,
+ struct ViceIoctl *vice_ioctl,
+ struct vnode *vp)
+{
+ int error;
+ struct mount *mnt;
+ struct vattr vattr;
+ size_t len;
+ struct xfs_fh_args fh_args;
+
+ XFSDEB(XDEBSYS, ("fhget_call\n"));
+
+ if (vp == NULL)
+ return EBADF;
+
+ error = suser (xfs_proc_to_cred(p), NULL);
+ if (error)
+ return error;
+
+#ifdef __osf__
+ VOP_GETATTR(vp, &vattr, p->p_rcred, error);
+#else
+ error = VOP_GETATTR(vp, &vattr, p->p_ucred, p);
+#endif
+ if (error)
+ goto out;
+
+ mnt = vp->v_mount;
+
+ SCARG(&fh_args, fsid) = mnt->mnt_stat.f_fsid;
+ SCARG(&fh_args, fileid) = vattr.va_fileid;
+ SCARG(&fh_args, gen) = vattr.va_gen;
+
+ len = sizeof(fh_args);
+
+ if (vice_ioctl->out_size < len) {
+ error = EINVAL;
+ goto out;
+ }
+
+ error = copyout (&fh_args, vice_ioctl->out, len);
+ if (error) {
+ XFSDEB(XDEBSYS, ("fhget_call: copyout failed: %d\n", error));
+ }
+
+out:
+ vrele (vp);
+ return error;
+}
+
+/*
+ * open the file specified in `vice_ioctl->in'
+ */
+
+static int
+fhopen_call (struct proc *p,
+ struct ViceIoctl *vice_ioctl,
+ struct vnode *vp,
+ int flags,
+ register_t *retval)
+{
+ int error;
+ struct xfs_fh_args fh_args;
+
+ XFSDEB(XDEBSYS, ("fhopen_call: flags = %d\n", flags));
+
+ if (vp != NULL) {
+ vrele (vp);
+ return EINVAL;
+ }
+
+ if (vice_ioctl->in_size < sizeof(fh_args))
+ return EINVAL;
+
+ error = copyin (vice_ioctl->in,
+ &fh_args,
+ sizeof(fh_args));
+ if (error)
+ return error;
+
+ return xfs_fhopen (p,
+ SCARG(&fh_args, fsid),
+ SCARG(&fh_args, fileid),
+ SCARG(&fh_args, gen),
+ flags,
+ retval);
+}
+
+/*
+ * Send the pioctl to arlad
+ */
+
+static int
+remote_pioctl (struct proc *p,
+ struct sys_pioctl_args *arg,
+ struct ViceIoctl *vice_ioctl,
+ struct vnode *vp)
+{
+ int error;
+ struct xfs_message_pioctl msg;
+ struct xfs_message_wakeup_data *msg2;
+
+ if (vp != NULL) {
+ struct xfs_node *xn;
+
+ if (vp->v_tag != VT_AFS) {
+ XFSDEB(XDEBSYS, ("xfs_syscall: file is not in afs\n"));
+ vrele(vp);
+ return EINVAL;
+ }
+
+ xn = VNODE_TO_XNODE(vp);
+
+ msg.handle = xn->handle;
+ vrele(vp);
+ }
+
+ if (vice_ioctl->in_size > 2048) {
+ printf("xfs_pioctl_call: got a humongous in packet: opcode: %d",
+ SCARG(arg, a_opcode));
+ return EINVAL;
+ }
+ if (vice_ioctl->in_size != 0) {
+ error = copyin(vice_ioctl->in,
+ &msg.msg,
+ vice_ioctl->in_size);
+
+ if (error)
+ return error;
+ }
+
+ msg.header.opcode = XFS_MSG_PIOCTL;
+ msg.opcode = SCARG(arg, a_opcode);
+
+ msg.insize = vice_ioctl->in_size;
+ msg.outsize = vice_ioctl->out_size;
+#ifdef __osf__
+ msg.cred.uid = p->p_ruid;
+ msg.cred.pag = xfs_get_pag(p->p_rcred);
+#else
+ msg.cred.uid = p->p_cred->p_ruid;
+ msg.cred.pag = xfs_get_pag(p->p_ucred);
+#endif
+
+ error = xfs_message_rpc(0, &msg.header, sizeof(msg)); /* XXX */
+ msg2 = (struct xfs_message_wakeup_data *) &msg;
+
+ if (error == 0)
+ error = msg2->error;
+ else
+ error = EINVAL; /* return EINVAL to not confuse applications */
+
+ if (error == 0 && msg2->header.opcode == XFS_MSG_WAKEUP_DATA)
+ error = copyout(msg2->msg, vice_ioctl->out,
+ min(msg2->len, vice_ioctl->out_size));
+ return error;
+}
+
+static int
+xfs_debug (struct proc *p,
+ struct ViceIoctl *vice_ioctl)
+{
+ int32_t flags;
+ int error;
+
+ if (vice_ioctl->in_size != 0) {
+ if (vice_ioctl->in_size < sizeof(int32_t))
+ return EINVAL;
+
+ error = suser (xfs_proc_to_cred(p), NULL);
+ if (error)
+ return error;
+
+ error = copyin (vice_ioctl->in,
+ &flags,
+ sizeof(flags));
+ if (error)
+ return error;
+
+ xfsdeb = flags;
+ }
+
+ if (vice_ioctl->out_size != 0) {
+ if (vice_ioctl->out_size < sizeof(int32_t))
+ return EINVAL;
+
+ error = copyout (&xfsdeb,
+ vice_ioctl->out,
+ sizeof(int32_t));
+ if (error)
+ return error;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Handle `pioctl'
+ */
+
+int
+xfs_pioctl_call(struct proc *proc,
+ struct sys_pioctl_args *arg,
+ register_t *return_value)
+{
+ int error;
+ struct ViceIoctl vice_ioctl;
+ char *pathptr;
+ struct vnode *vp = NULL;
+
+ XFSDEB(XDEBSYS, ("xfs_syscall(%d, %p, %d, %p, %d)\n",
+ SCARG(arg, operation),
+ SCARG(arg, a_pathP),
+ SCARG(arg, a_opcode),
+ SCARG(arg, a_paramsP),
+ SCARG(arg, a_followSymlinks)));
+
+ /* Copy in the data structure for us */
+
+ error = copyin(SCARG(arg, a_paramsP),
+ &vice_ioctl,
+ sizeof(vice_ioctl));
+
+ if (error)
+ return error;
+
+ pathptr = SCARG(arg, a_pathP);
+
+ if (pathptr != NULL) {
+ error = lookup_node (pathptr, SCARG(arg, a_followSymlinks), &vp,
+ proc);
+ if(error)
+ return error;
+ }
+
+ switch (SCARG(arg, a_opcode)) {
+ case VIOC_FHGET :
+ return fhget_call (proc, &vice_ioctl, vp);
+ case VIOC_FHOPEN :
+ return fhopen_call (proc, &vice_ioctl, vp,
+ SCARG(arg, a_followSymlinks), return_value);
+ case VIOC_XFSDEBUG:
+ return xfs_debug (proc, &vice_ioctl);
+ default :
+ XFSDEB(XDEBSYS, ("a_opcode = %x\n", SCARG(arg, a_opcode)));
+ return remote_pioctl (proc, arg, &vice_ioctl, vp);
+ }
+}
diff --git a/sys/xfs/xfs_syscalls-dummy.c b/sys/xfs/xfs_syscalls-dummy.c
new file mode 100644
index 00000000000..656a34a3471
--- /dev/null
+++ b/sys/xfs/xfs_syscalls-dummy.c
@@ -0,0 +1,11 @@
+/*
+ * This code released into public domain by Artur Grabowski <art@openbsd.org>
+ */
+#include <xfs/xfs_locl.h>
+#include <sys/syscallargs.h>
+
+int
+sys_xfspioctl(struct proc *proc, void *varg, register_t *retval)
+{
+ return ENOSYS;
+}
diff --git a/sys/xfs/xfs_syscalls.h b/sys/xfs/xfs_syscalls.h
index 4a8d1bfaadf..2ebdaa17674 100644
--- a/sys/xfs/xfs_syscalls.h
+++ b/sys/xfs/xfs_syscalls.h
@@ -1,6 +1,5 @@
-/* $OpenBSD: xfs_syscalls.h,v 1.2 1998/08/31 05:13:29 art Exp $ */
/*
- * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -37,14 +36,58 @@
* SUCH DAMAGE.
*/
-/* $KTH: xfs_syscalls.h,v 1.2 1998/01/21 01:03:57 mho Exp $ */
+/* $Id: xfs_syscalls.h,v 1.3 1999/04/30 01:59:01 art Exp $ */
-#ifndef _XFS_XFS_SYSCALLS_H_
-#define _XFS_XFS_SYSCALLS_H_
+#ifndef __xfs_syscalls
+#define __xfs_syscalls
-int xfs_install_syscalls __P((void));
-int xfs_uninstall_syscalls __P((void));
-int xfs_stat_syscalls __P((void));
-pag_t xfs_get_pag __P((struct ucred *));
+#include <xfs/xfs_common.h>
+#include <xfs/xfs_message.h>
+#ifdef HAVE_SYS_SYSCALLARGS_H
+#include <sys/syscallargs.h>
+#endif
+
+/*
+ * XXX
+ */
+
+#ifndef SCARG
+#define SCARG(a, b) ((a)->b.datum)
+#define syscallarg(x) union { x datum; register_t pad; }
+#endif
+
+#ifndef syscallarg
+#define syscallarg(x) x
+#endif
+#ifndef HAVE_REGISTER_T
+typedef int register_t;
#endif
+
+struct sys_pioctl_args {
+ syscallarg(int) operation;
+ syscallarg(char *) a_pathP;
+ syscallarg(int) a_opcode;
+ syscallarg(struct ViceIoctl *) a_paramsP;
+ syscallarg(int) a_followSymlinks;
+};
+
+struct xfs_fh_args {
+ syscallarg(fsid_t) fsid;
+ syscallarg(long) fileid;
+ syscallarg(long) gen;
+};
+
+int xfs_install_syscalls(void);
+int xfs_uninstall_syscalls(void);
+int xfs_stat_syscalls(void);
+pag_t xfs_get_pag(struct ucred *);
+
+int xfs_setpag_call(struct ucred **ret_cred);
+int xfs_pioctl_call(struct proc *proc,
+ struct sys_pioctl_args *args,
+ register_t *return_value);
+
+int sys_xfspioctl(struct proc *proc, void *varg, register_t *retval);
+
+#endif /* __xfs_syscalls */
diff --git a/sys/xfs/xfs_vfsops-bsd.c b/sys/xfs/xfs_vfsops-bsd.c
new file mode 100644
index 00000000000..723cb1aa1d8
--- /dev/null
+++ b/sys/xfs/xfs_vfsops-bsd.c
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include <xfs/xfs_locl.h>
+
+RCSID("$Id: xfs_vfsops-bsd.c,v 1.1 1999/04/30 01:59:01 art Exp $");
+
+/*
+ * XFS vfs operations.
+ */
+
+#include <xfs/xfs_common.h>
+#include <xfs/xfs_message.h>
+#include <xfs/xfs_fs.h>
+#include <xfs/xfs_dev.h>
+#include <xfs/xfs_deb.h>
+#include <xfs/xfs_vfsops.h>
+#include <xfs/xfs_vfsops-bsd.h>
+#include <xfs/xfs_vnodeops.h>
+
+int
+xfs_mount(struct mount *mp,
+ const char *user_path,
+ caddr_t user_data,
+ struct nameidata *ndp,
+ struct proc *p)
+{
+ return xfs_mount_common(mp, user_path, user_data, ndp, p);
+}
+
+int
+xfs_start(struct mount * mp, int flags, struct proc * p)
+{
+ XFSDEB(XDEBVFOPS, ("xfs_start mp = %p, flags = %d, proc = %p\n",
+ mp, flags, p));
+ return 0;
+}
+
+
+int
+xfs_unmount(struct mount * mp, int mntflags, struct proc *p)
+{
+ XFSDEB(XDEBVFOPS, ("xfs_umount: mp = %p, mntflags = %d, proc = %p\n",
+ mp, mntflags, p));
+ return xfs_unmount_common(mp, mntflags);
+}
+
+int
+xfs_root(struct mount *mp, struct vnode **vpp)
+{
+ XFSDEB(XDEBVFOPS, ("xfs_root mp = %p\n", mp));
+ return xfs_root_common(mp, vpp, curproc, curproc->p_ucred);
+}
+
+int
+xfs_quotactl(struct mount *mp, int cmd, uid_t uid, caddr_t arg, struct proc *p)
+{
+ XFSDEB(XDEBVFOPS, ("xfs_quotactl: mp = %p, cmd = %d, uid = %u, "
+ "arg = %p, proc = %p\n",
+ mp, cmd, uid, arg, p));
+ return EOPNOTSUPP;
+}
+
+int
+xfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
+{
+ XFSDEB(XDEBVFOPS, ("xfs_statfs: mp = %p, sbp = %p, proc = %p\n",
+ mp, sbp, p));
+ bcopy(&mp->mnt_stat, sbp, sizeof(*sbp));
+ return 0;
+}
+
+int
+xfs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
+{
+ XFSDEB(XDEBVFOPS, ("xfs_sync: mp = %p, waitfor = %d, "
+ "cred = %p, proc = %p\n",
+ mp, waitfor, cred, p));
+ return 0;
+}
+
+int
+xfs_vget(struct mount * mp,
+ ino_t ino,
+ struct vnode ** vpp)
+{
+ XFSDEB(XDEBVFOPS, ("xfs_vget\n"));
+ return EOPNOTSUPP;
+}
+
+int
+xfs_fhtovp(struct mount * mp,
+ struct fid * fhp,
+ struct mbuf * nam,
+ struct vnode ** vpp,
+ int *exflagsp,
+ struct ucred ** credanonp)
+{
+#ifdef ARLA_KNFS
+ static struct ucred fhtovpcred;
+ struct netcred *np = NULL;
+ struct xfs_node *xn;
+ struct vnode *vp;
+ xfs_handle handle;
+ int error;
+
+ XFSDEB(XDEBVFOPS, ("xfs_fhtovp\n"));
+
+ if (fhp->fid_len != 16) {
+ printf("xfs_fhtovp: *PANIC* got a invalid length of a fid\n");
+ return EINVAL;
+ }
+
+ /* XXX: Should see if we is exported to this client */
+#if 0
+ np = vfs_export_lookup(mp, &ump->um_export, nam);
+ if (np == NULL)
+ return EACCES;
+#endif
+
+ memcpy(&handle, fhp->fid_data, sizeof(handle));
+ XFSDEB(XDEBVFOPS, ("xfs_fhtovp: fid: %d.%d.%d.%d\n",
+ handle.a, handle.d, handle.c, handle.d));
+
+ XFSDEB(XDEBVFOPS, ("xfs_fhtovp: xfs_vnode_find\n"));
+ xn = xfs_node_find(&xfs[0], &handle); /* XXX: 0 */
+
+ if (xn == NULL) {
+ struct xfs_message_getattr msg;
+
+ error = xfs_getnewvnode(xfs[0].mp, &vp, &handle);
+ if (error)
+ return error;
+
+ xfs_do_vget(vp, 0, current);
+
+ } else {
+ /* XXX access ? */
+ vp = XNODE_TO_VNODE(xn);
+
+ /* XXX wrong ? (we tell arla below) */
+ if (vp->v_usecount <= 0)
+ xfs_do_vget(vp, 0, current);
+ else
+ VREF(vp);
+ error = 0;
+ }
+
+ if (error == 0) {
+ fhtovpcred.cr_uid = 0;
+ fhtovpcred.cr_gid = 0;
+ fhtovpcred.cr_ngroups = 0;
+
+ *vpp = vp;
+#ifdef MNT_EXPUBLIC
+ *exflagsp = MNT_EXPUBLIC;
+#else
+ *exflagsp = 0;
+#endif
+ *credanonp = &fhtovpcred;
+
+ XFSDEB(XDEBVFOPS, ("xfs_fhtovp done\n"));
+
+ /*
+ * XXX tell arla about this node is hold by nfsd.
+ * There need to be code in xfs_write too.
+ */
+ } else
+ XFSDEB(XDEBVFOPS, ("xfs_fhtovp failed (%d);", error));
+
+ return error;
+#else
+ return EOPNOTSUPP;
+#endif
+}
+
+int
+xfs_vptofh(struct vnode * vp,
+ struct fid * fhp)
+{
+#ifdef ARLA_KNFS
+ struct xfs_node *xn;
+ XFSDEB(XDEBVFOPS, ("xfs_vptofh\n"));
+
+ if (MAXFIDSZ < 16)
+ return EOPNOTSUPP;
+
+ xn = VNODE_TO_XNODE(vp);
+
+ if (xn == NULL)
+ return EINVAL;
+
+ fhp->fid_len = 16;
+ memcpy(fhp->fid_data, &xn->handle, 16);
+
+ return 0;
+#else
+ XFSDEB(XDEBVFOPS, ("xfs_vptofh\n"));
+ return EOPNOTSUPP;
+#endif
+}
+
+/*
+ * xfs complete dead vnodes implementation.
+ *
+ * this is because the dead_vnodeops_p is _not_ filesystem, but rather
+ * a part of the vfs-layer.
+ */
+
+int
+xfs_dead_lookup(struct vop_lookup_args * ap)
+ /* struct vop_lookup_args {
+ struct vnodeop_desc *a_desc;
+ struct vnode *a_dvp;
+ struct vnode **a_vpp;
+ struct componentname *a_cnp;
+}; */
+{
+ *ap->a_vpp = NULL;
+ return ENOTDIR;
+}
+
+/*
+ * Given `fsid', `fileid', and `gen', return in `vpp' a locked and
+ * ref'ed vnode from that file system with that id and generation.
+ * All is done in the context of `proc'. Returns 0 if succesful, and
+ * error otherwise.
+ */
+
+int
+xfs_fhlookup (struct proc *proc,
+ fsid_t fsid,
+ long fileid,
+ long gen,
+ struct vnode **vpp)
+{
+ int error;
+ struct mount *mp;
+ struct ucred *cred = proc->p_ucred;
+ struct vattr vattr;
+
+ XFSDEB(XDEBVFOPS, ("xfs_fhlookup: fileid = %ld\n",
+ fileid));
+
+ error = suser (cred, NULL);
+ if (error)
+ return EPERM;
+
+#ifdef HAVE_KERNEL_VFS_GETVFS
+ mp = vfs_getvfs (&fsid);
+#else
+ mp = getvfs (&fsid);
+#endif
+ if (mp == NULL)
+ return ENXIO;
+
+ error = VFS_VGET(mp, fileid, vpp);
+
+ if (error)
+ return error;
+
+ error = VOP_GETATTR(*vpp, &vattr, cred, proc);
+ if (error) {
+ vput(*vpp);
+ return error;
+ }
+
+ if (vattr.va_gen != gen) {
+ vput(*vpp);
+ return ENOENT;
+ }
+
+#ifdef HAVE_KERNEL_VFS_OBJECT_CREATE
+ if ((*vpp)->v_type == VREG && (*vpp)->v_object == NULL)
+#if HAVE_FOUR_ARGUMENT_VFS_OBJECT_CREATE
+ vfs_object_create (*vpp, proc, proc->p_ucred, TRUE);
+#else
+ vfs_object_create (*vpp, proc, proc->p_ucred);
+#endif
+#endif
+ return 0;
+}
+
+/*
+ * Perform an open operation on the vnode identified by (fsid, fileid,
+ * gen) (see xfs_fhlookup) with flags `user_flags'. Returns 0 or
+ * error. If succsesful, the file descriptor is returned in `retval'.
+ */
+
+int
+xfs_fhopen (struct proc *proc,
+ fsid_t fsid,
+ long fileid,
+ long gen,
+ int user_flags,
+ register_t *retval)
+{
+ int error;
+ struct vnode *vp;
+ struct ucred *cred = proc->p_ucred;
+ int flags = FFLAGS(user_flags);
+ int index;
+ struct file *fp;
+ extern struct fileops vnops;
+
+ XFSDEB(XDEBVFOPS, ("xfs_fhopen: fileid = %ld, flags = %d\n",
+ fileid, user_flags));
+
+ error = xfs_fhlookup (proc, fsid, fileid, gen, &vp);
+ if (error)
+ return error;
+
+ error = VOP_OPEN(vp, flags, cred, proc);
+ if (error)
+ goto out;
+
+ error = falloc(proc, &fp, &index);
+ if (error)
+ goto out;
+
+ if (flags & FWRITE)
+ vp->v_writecount++;
+
+#if __FreeBSD_version >= 300000
+ if (vp->v_type == VREG) {
+#if HAVE_FOUR_ARGUMENT_VFS_OBJECT_CREATE
+ error = vfs_object_create(vp, proc, proc->p_cred->pc_ucred, 1);
+#else
+ error = vfs_object_create(vp, proc, proc->p_cred->pc_ucred);
+#endif
+ if (error)
+ goto out;
+ }
+#endif
+
+ fp->f_flag = flags & FMASK;
+ fp->f_type = DTYPE_VNODE;
+ fp->f_ops = &vnops;
+ fp->f_data = (caddr_t)vp;
+ xfs_vfs_unlock(vp, proc);
+ *retval = index;
+ return 0;
+out:
+ vput(vp);
+ return error;
+}
diff --git a/sys/xfs/xfs_vfsops-bsd.h b/sys/xfs/xfs_vfsops-bsd.h
new file mode 100644
index 00000000000..5cb767f8eb0
--- /dev/null
+++ b/sys/xfs/xfs_vfsops-bsd.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/* $Id: xfs_vfsops-bsd.h,v 1.1 1999/04/30 01:59:01 art Exp $ */
+
+#ifndef _xfs_vfsops_bsd_h
+#define _xfs_vfsops_bsd_h
+
+int
+xfs_mount(struct mount * mp,
+ const char *user_path,
+ caddr_t user_data,
+ struct nameidata * ndp,
+ struct proc * p);
+
+int
+xfs_start(struct mount * mp, int flags, struct proc * p);
+
+int
+xfs_unmount(struct mount * mp, int mntflags, struct proc *p);
+
+int
+xfs_root(struct mount *mp, struct vnode **vpp);
+
+int
+xfs_quotactl(struct mount *mp, int cmd, uid_t uid, caddr_t arg, struct proc *p);
+
+int
+xfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p);
+
+int
+xfs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p);
+
+int
+xfs_vget(struct mount * mp,
+ ino_t ino,
+ struct vnode ** vpp);
+
+int
+xfs_fhtovp(struct mount * mp,
+ struct fid * fhp,
+ struct mbuf * nam,
+ struct vnode ** vpp,
+ int *exflagsp,
+ struct ucred ** credanonp);
+
+int
+xfs_vptofh(struct vnode * vp,
+ struct fid * fhp);
+
+int
+xfs_dead_lookup(struct vop_lookup_args * ap);
+
+#endif /* _xfs_vfsops_bsd_h */
diff --git a/sys/xfs/xfs_vfsops-common.c b/sys/xfs/xfs_vfsops-common.c
new file mode 100644
index 00000000000..8f1210cbc9c
--- /dev/null
+++ b/sys/xfs/xfs_vfsops-common.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include <xfs/xfs_locl.h>
+
+RCSID("$Id: xfs_vfsops-common.c,v 1.1 1999/04/30 01:59:01 art Exp $");
+
+/*
+ * XFS vfs operations.
+ */
+
+#include <xfs/xfs_common.h>
+#include <xfs/xfs_message.h>
+#include <xfs/xfs_fs.h>
+#include <xfs/xfs_dev.h>
+#include <xfs/xfs_deb.h>
+#include <xfs/xfs_syscalls.h>
+#include <xfs/xfs_vfsops.h>
+
+struct xfs xfs[NXFS];
+
+int
+xfs_mount_common(struct mount *mp,
+ const char *user_path,
+ caddr_t user_data,
+ struct nameidata *ndp,
+ struct proc *p)
+{
+ struct vnode *devvp;
+ dev_t dev;
+ int error;
+ struct vattr vat;
+ char path[MAXPATHLEN];
+ char data[MAXPATHLEN];
+ size_t len;
+
+ error = copyinstr(user_path, path, MAXPATHLEN, &len);
+ if (error)
+ return error;
+
+ error = copyinstr(user_data, data, MAXPATHLEN, &len);
+ if (error)
+ return error;
+
+ XFSDEB(XDEBVFOPS, ("xfs_mount: "
+ "struct mount mp = %p path = '%s' data = '%s'\n",
+ mp, path, data));
+
+#ifdef ARLA_KNFS
+ XFSDEB(XDEBVFOPS, ("xfs_mount: mount flags = %x\n", mp->mnt_flag));
+
+ /*
+ * mountd(8) flushes all export entries when it starts
+ * right now we ignore it (but should not)
+ */
+
+ if (mp->mnt_flag & MNT_UPDATE ||
+ mp->mnt_flag & MNT_DELEXPORT) {
+
+ XFSDEB(XDEBVFOPS,
+ ("xfs_mount: ignoreing MNT_UPDATE or MNT_DELEXPORT\n"));
+ return 0;
+ }
+#endif
+
+ NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, data, p);
+ error = namei(ndp);
+ if (error) {
+ XFSDEB(XDEBVFOPS, ("namei failed, errno = %d\n", error));
+ return error;
+ }
+
+ devvp = ndp->ni_vp;
+
+ if (devvp->v_type != VCHR) {
+ vput(devvp);
+ XFSDEB(XDEBVFOPS, ("not VCHR (%d)\n", devvp->v_type));
+ return ENXIO;
+ }
+#ifdef __osf__
+ VOP_GETATTR(devvp, &vat, ndp->ni_cred, error);
+#else
+ error = VOP_GETATTR(devvp, &vat, p->p_ucred, p);
+#endif
+ vput(devvp);
+ if (error) {
+ XFSDEB(XDEBVFOPS, ("VOP_GETATTR failed, error = %d\n", error));
+ return error;
+ }
+ dev = vat.va_rdev;
+ XFSDEB(XDEBVFOPS, ("dev = %d.%d\n", major(dev), minor(dev)));
+
+ /* Check that this device really is an xfs_dev */
+ if (major(dev) < 0 || major(dev) > nchrdev) {
+ XFSDEB(XDEBVFOPS, ("major out of range (0 < %d < %d)\n",
+ major(dev), nchrdev));
+ return ENXIO;
+ }
+ if (minor(dev) < 0 || NXFS < minor(dev)) {
+ XFSDEB(XDEBVFOPS, ("minor out of range (0 < %d < %d)\n",
+ minor(dev), NXFS));
+ return ENXIO;
+ }
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+ if(!xfs_func_is_devopen(cdevsw[major(dev)].d_open))
+ return ENXIO;
+#elif defined(__FreeBSD__)
+ if (cdevsw[major(dev)] == NULL
+ || !xfs_func_is_devopen(cdevsw[major(dev)]->d_open))
+ return ENXIO;
+#endif
+
+ if (xfs[minor(dev)].status & XFS_MOUNTED)
+ return EBUSY;
+
+ xfs[minor(dev)].status = XFS_MOUNTED;
+ xfs[minor(dev)].mp = mp;
+ xfs[minor(dev)].root = 0;
+ xfs[minor(dev)].nnodes = 0;
+ xfs[minor(dev)].fd = minor(dev);
+
+ VFS_TO_XFS(mp) = &xfs[minor(dev)];
+#if defined(HAVE_KERNEL_VFS_GETNEWFSID)
+#if defined(HAVE_TWO_ARGUMENT_VFS_GETNEWFSID)
+ vfs_getnewfsid(mp, MOUNT_AFS);
+#else
+ vfs_getnewfsid(mp);
+#endif
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ getnewfsid(mp, makefstype(MOUNT_AFS));
+#elif defined(__FreeBSD__)
+ getnewfsid(mp, MOUNT_AFS);
+ mp->mnt_stat.f_type = MOUNT_AFS;
+#endif
+
+ mp->mnt_stat.f_bsize = DEV_BSIZE;
+#ifndef __osf__
+ mp->mnt_stat.f_iosize = DEV_BSIZE;
+ mp->mnt_stat.f_owner = 0;
+#endif
+ mp->mnt_stat.f_blocks = 4711 * 4711;
+ mp->mnt_stat.f_bfree = 4711 * 4711;
+ mp->mnt_stat.f_bavail = 4711 * 4711;
+ mp->mnt_stat.f_files = 4711;
+ mp->mnt_stat.f_ffree = 4711;
+ mp->mnt_stat.f_flags = mp->mnt_flag;
+
+#ifdef __osf__
+ mp->mnt_stat.f_fsid.val[0] = dev;
+ mp->mnt_stat.f_fsid.val[1] = MOUNT_XFS;
+
+ MALLOC(mp->m_stat.f_mntonname, char *, strlen(path) + 1,
+ M_PATHNAME, M_WAITOK);
+ strcpy(mp->m_stat.f_mntonname, path);
+
+ MALLOC(mp->m_stat.f_mntfromname, char *, sizeof("arla"),
+ M_PATHNAME, M_WAITOK);
+ strcpy(mp->m_stat.f_mntfromname, "arla");
+#else /* __osf__ */
+ strncpy(mp->mnt_stat.f_mntonname,
+ path,
+ sizeof(mp->mnt_stat.f_mntonname));
+
+ strncpy(mp->mnt_stat.f_mntfromname,
+ "arla",
+ sizeof(mp->mnt_stat.f_mntfromname));
+
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+ strncpy(mp->mnt_stat.f_fstypename,
+ "xfs",
+ sizeof(mp->mnt_stat.f_fstypename));
+#endif
+#endif /* __osf__ */
+
+ return 0;
+}
+
+int
+xfs_unmount_common(struct mount *mp, int mntflags)
+{
+ struct xfs *xfsp = VFS_TO_XFS(mp);
+ int flags = 0;
+ int error;
+
+ if (mntflags & MNT_FORCE) {
+#ifdef HAVE_KERNEL_DOFORCE
+ extern int doforce;
+ if (!doforce)
+ return EINVAL;
+#endif
+ flags |= FORCECLOSE;
+ }
+
+ error = free_all_xfs_nodes(xfsp, flags, 1);
+ if (error)
+ return error;
+
+ xfsp->status = 0;
+ XFS_TO_VFS(xfsp) = NULL;
+ return 0;
+}
+
+int
+xfs_root_common(struct mount *mp, struct vnode **vpp,
+ struct proc *proc, struct ucred *cred)
+{
+ struct xfs *xfsp = VFS_TO_XFS(mp);
+ struct xfs_message_getroot msg;
+ int error;
+
+ do {
+ if (xfsp->root != NULL) {
+ *vpp = XNODE_TO_VNODE(xfsp->root);
+ xfs_do_vget(*vpp, LK_INTERLOCK|LK_EXCLUSIVE, proc);
+ return 0;
+ }
+ msg.header.opcode = XFS_MSG_GETROOT;
+ msg.cred.uid = cred->cr_uid;
+ msg.cred.pag = xfs_get_pag(cred);
+ error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+ if (error == 0)
+ error = ((struct xfs_message_wakeup *) & msg)->error;
+ } while (error == 0);
+ /*
+ * Failed to get message through, need to pretend that all went well
+ * and return a fake dead vnode to be able to unmount.
+ */
+
+ if ((error = make_dead_vnode(mp, vpp)))
+ return error;
+
+ (*vpp)->v_flag |= VROOT;
+ return 0;
+}
diff --git a/sys/xfs/xfs_vfsops-openbsd.c b/sys/xfs/xfs_vfsops-openbsd.c
new file mode 100644
index 00000000000..c4c8f770bbe
--- /dev/null
+++ b/sys/xfs/xfs_vfsops-openbsd.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include <xfs/xfs_locl.h>
+
+RCSID("$Id: xfs_vfsops-openbsd.c,v 1.1 1999/04/30 01:59:01 art Exp $");
+
+#include <xfs/xfs_common.h>
+#include <xfs/xfs_message.h>
+#include <xfs/xfs_fs.h>
+#include <xfs/xfs_dev.h>
+#include <xfs/xfs_deb.h>
+#include <xfs/xfs_vfsops.h>
+#include <xfs/xfs_vfsops-bsd.h>
+#include <xfs/xfs_vnodeops.h>
+
+static vop_t **xfs_dead_vnodeop_p;
+
+int
+make_dead_vnode(struct mount *mp, struct vnode **vpp)
+{
+ XFSDEB(XDEBNODE, ("make_dead_vnode mp = %p\n", mp));
+
+ return getnewvnode(VT_NON, mp, xfs_dead_vnodeop_p, vpp);
+}
+
+static struct vnodeopv_entry_desc xfs_dead_vnodeop_entries[] = {
+ {&vop_default_desc, (vop_t *) xfs_eopnotsupp},
+ {&vop_lookup_desc, (vop_t *) xfs_dead_lookup},
+ {&vop_reclaim_desc, (vop_t *) xfs_returnzero},
+ {NULL, NULL}};
+
+static struct vnodeopv_desc xfs_dead_vnodeop_opv_desc =
+{&xfs_dead_vnodeop_p, xfs_dead_vnodeop_entries};
+
+extern struct vnodeopv_desc xfs_vnodeop_opv_desc;
+
+static int
+xfs_init(struct vfsconf *vfs)
+{
+ XFSDEB(XDEBVFOPS, ("xfs_init\n"));
+ vfs_opv_init_explicit(&xfs_vnodeop_opv_desc);
+ vfs_opv_init_default(&xfs_vnodeop_opv_desc);
+ vfs_opv_init_explicit(&xfs_dead_vnodeop_opv_desc);
+ vfs_opv_init_default(&xfs_dead_vnodeop_opv_desc);
+ return 0;
+}
+
+struct vfsops xfs_vfsops = {
+ xfs_mount,
+ xfs_start,
+ xfs_unmount,
+ xfs_root,
+ xfs_quotactl,
+ xfs_statfs,
+ xfs_sync,
+ xfs_vget,
+ xfs_fhtovp,
+ xfs_vptofh,
+ xfs_init,
+ NULL,
+};
+
+static struct vfsconf xfs_vfc = {
+ &xfs_vfsops,
+ "xfs",
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL
+};
+
+#ifndef HAVE_KERNEL_VFS_REGISTER
+
+static int
+vfs_register (struct vfsconf *vfs)
+{
+ struct vfsconf *vfsp;
+ struct vfsconf **vfspp;
+
+ /* Check if filesystem already known */
+ for (vfspp = &vfsconf, vfsp = vfsconf;
+ vfsp;
+ vfspp = &vfsp->vfc_next, vfsp = vfsp->vfc_next)
+ if (strcmp(vfsp->vfc_name, vfs->vfc_name) == 0)
+ return (EEXIST);
+
+ maxvfsconf++;
+
+ /* Add to the end of the list */
+ *vfspp = vfs;
+
+ vfs->vfc_next = NULL;
+
+ /* Call vfs_init() */
+ XFSDEB(XDEBVFOPS, ("calling vfs_init\n"));
+ (*(vfs->vfc_vfsops->vfs_init)) (vfs);
+
+ /* done! */
+
+ return 0;
+}
+
+static int
+vfs_unregister (struct vfsconf *vfs)
+{
+ struct vfsconf *vfsp;
+ struct vfsconf **vfspp;
+
+ /* Find our vfsconf struct */
+ for (vfspp = &vfsconf, vfsp = vfsconf;
+ vfsp;
+ vfspp = &vfsp->vfc_next, vfsp = vfsp->vfc_next)
+ if (strcmp(vfsp->vfc_name, vfs->vfc_name) == 0)
+ break;
+
+ if (!vfsp) /* Not found */
+ return (ENOENT);
+
+ if (vfsp->vfc_refcount) /* In use */
+ return (EBUSY);
+
+ /* Remove from list and free */
+ *vfspp = vfsp->vfc_next;
+
+ maxvfsconf--;
+
+ return 0;
+}
+
+#endif
+
+int
+xfs_install_filesys(void)
+{
+ return vfs_register (&xfs_vfc);
+}
+
+int
+xfs_uninstall_filesys(void)
+{
+ return vfs_unregister (&xfs_vfc);
+}
+
+int
+xfs_stat_filesys (void)
+{
+ return 0;
+}
diff --git a/sys/xfs/xfs_vfsops.h b/sys/xfs/xfs_vfsops.h
new file mode 100644
index 00000000000..55a5ff1c175
--- /dev/null
+++ b/sys/xfs/xfs_vfsops.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/* $Id: xfs_vfsops.h,v 1.1 1999/04/30 01:59:01 art Exp $ */
+
+#ifndef _xfs_vfsops_h
+#define _xfs_vfsops_h
+
+int
+xfs_mount_common(struct mount *mp,
+ const char *user_path,
+ caddr_t user_data,
+ struct nameidata *ndp,
+ struct proc *p);
+
+int
+xfs_unmount_common(struct mount *mp, int mntflags);
+
+int
+xfs_root_common(struct mount *mp,
+ struct vnode **vpp,
+ struct proc *proc,
+ struct ucred *cred);
+
+int
+xfs_fhlookup (struct proc *proc,
+ fsid_t fsid,
+ long fileid,
+ long gen,
+ struct vnode **vpp);
+
+int
+xfs_fhopen (struct proc *proc,
+ fsid_t fsid,
+ long fileid,
+ long gen,
+ int flags,
+ register_t *retval);
+
+int make_dead_vnode(struct mount *mp, struct vnode **vpp);
+
+#endif /* _xfs_vfsops_h */
diff --git a/sys/xfs/xfs_vnodeops-bsd.c b/sys/xfs/xfs_vnodeops-bsd.c
new file mode 100644
index 00000000000..01b1f096a81
--- /dev/null
+++ b/sys/xfs/xfs_vnodeops-bsd.c
@@ -0,0 +1,1030 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/*
+ * XFS operations.
+ */
+
+#include <xfs/xfs_locl.h>
+#include <xfs/xfs_message.h>
+#include <xfs/xfs_common.h>
+#include <xfs/xfs_fs.h>
+#include <xfs/xfs_dev.h>
+#include <xfs/xfs_deb.h>
+#include <xfs/xfs_syscalls.h>
+#include <xfs/xfs_vnodeops.h>
+#include <vm/vm.h>
+#include <vm/vnode_pager.h>
+
+RCSID("$Id: xfs_vnodeops-bsd.c,v 1.1 1999/04/30 01:59:01 art Exp $");
+
+/*
+ * vnode functions
+ */
+
+#ifdef HAVE_VOP_OPEN
+static int
+xfs_open(struct vop_open_args * ap)
+ /*
+ struct vop_open {
+ struct vnode *vp;
+ int mode;
+ struct ucred *cred;
+ struct proc *p;
+ }; */
+{
+ XFSDEB(XDEBVNOPS, ("xfs_open\n"));
+
+ if (ap->a_mode & FWRITE)
+ return xfs_open_valid(ap->a_vp, ap->a_cred, XFS_OPEN_NW);
+ else
+ return xfs_open_valid(ap->a_vp, ap->a_cred, XFS_OPEN_NR);
+}
+#endif /* HAVE_VOP_OPEN */
+
+#ifdef HAVE_VOP_FSYNC
+static int
+xfs_fsync(struct vop_fsync_args * ap)
+ /*
+ vop_fsync {
+ struct vnode *vp;
+ struct ucred *cred;
+ int waitfor;
+ struct proc *p;
+}; */
+{
+#ifdef HAVE_STRUCT_VOP_FSYNC_ARGS_A_FLAGS
+ return xfs_fsync_common(ap->a_vp, ap->a_cred, ap->a_flags, ap->a_p);
+#else
+ return xfs_fsync_common(ap->a_vp, ap->a_cred, ap->a_waitfor, ap->a_p);
+#endif
+}
+#endif /* HAVE_VOP_FSYNC */
+
+#ifdef HAVE_VOP_CLOSE
+static int
+xfs_close(struct vop_close_args * ap)
+ /* vop_close {
+ IN struct vnode *vp;
+ IN int fflag;
+ IN struct ucred *cred;
+ IN struct proc *p;
+ }; */
+{
+ return xfs_close_common(ap->a_vp, ap->a_fflag, ap->a_p, ap->a_cred);
+}
+#endif /* HAVE_VOP_CLOSE */
+
+#ifdef HAVE_VOP_READ
+static int
+xfs_read(struct vop_read_args * ap)
+ /* vop_read {
+ IN struct vnode *vp;
+ INOUT struct uio *uio;
+ IN int ioflag;
+ IN struct ucred *cred;
+ }; */
+{
+ return xfs_read_common(ap->a_vp, ap->a_uio, ap->a_ioflag, ap->a_cred);
+}
+#endif /* HAVE_VOP_READ */
+
+#ifdef HAVE_VOP_WRITE
+static int
+xfs_write(struct vop_write_args * ap)
+ /* vop_write {
+ IN struct vnode *vp;
+ INOUT struct uio *uio;
+ IN int ioflag;
+ IN struct ucred *cred;
+ }; */
+{
+ return xfs_write_common(ap->a_vp, ap->a_uio, ap->a_ioflag, ap->a_cred);
+}
+#endif /* HAVE_VOP_WRITE */
+
+#ifdef HAVE_VOP_IOCTL
+static int
+xfs_ioctl(struct vop_ioctl_args * ap)
+ /* struct vnode *vp,
+ int com,
+ caddr_t data,
+ int flag,
+ struct ucred *cred) */
+{
+ XFSDEB(XDEBVNOPS, ("xfs_ioctl\n"));
+
+ return EOPNOTSUPP;
+}
+#endif /* HAVE_VOP_IOCTL */
+
+#ifdef HAVE_VOP_SELECT
+static int
+xfs_select(struct vop_select_args * ap)
+ /* struct vnode *vp,
+ int which,
+ struct ucred *cred ) */
+{
+ XFSDEB(XDEBVNOPS, ("xfs_select\n"));
+
+ return EOPNOTSUPP;
+}
+#endif /* HAVE_VOP_SELECT */
+
+#ifdef HAVE_VOP_SEEK
+static int
+xfs_seek(struct vop_seek_args * ap)
+ /*
+struct vop_seek_args {
+ struct vnodeop_desc *a_desc;
+ struct vnode *a_vp;
+ off_t a_oldoff;
+ off_t a_newoff;
+ struct ucred *a_cred;
+};
+*/
+{
+ XFSDEB(XDEBVNOPS, ("xfs_seek\n"));
+ return 0;
+}
+#endif /* HAVE_VOP_SEEK */
+
+#ifdef HAVE_VOP_POLL
+static int
+xfs_poll(struct vop_poll_args * ap)
+ /* vop_poll {
+ IN struct vnode *vp;
+ IN int events;
+ IN struct proc *p;
+ }; */
+{
+ XFSDEB(XDEBVNOPS, ("xfs_poll\n"));
+ return EOPNOTSUPP;
+}
+#endif /* HAVE_VOP_POLL */
+
+#ifdef HAVE_VOP_GETATTR
+static int
+xfs_getattr(struct vop_getattr_args * ap)
+ /* struct vnode *vp,
+ struct vattr *vap,
+ struct ucred *cred) */
+{
+ return xfs_getattr_common(ap->a_vp, ap->a_vap, ap->a_cred);
+}
+#endif /* HAVE_VOP_GETATTR */
+
+#ifdef HAVE_VOP_SETATTR
+static int
+xfs_setattr(struct vop_setattr_args * ap)
+ /*
+struct vnode *vp,
+ struct vattr *vap,
+ struct ucred *cred)
+ */
+{
+ return xfs_setattr_common(ap->a_vp, ap->a_vap, ap->a_cred);
+}
+#endif /* HAVE_VOP_SETATTR */
+
+#ifdef HAVE_VOP_ACCESS
+static int
+xfs_access(struct vop_access_args * ap)
+ /*
+struct vnode *vp,
+ int mode,
+ struct ucred *cred)
+ */
+{
+ return xfs_access_common(ap->a_vp, ap->a_mode, ap->a_cred);
+}
+#endif /* HAVE_VOP_ACCESS */
+
+#ifdef HAVE_VOP_LOOKUP
+static int
+xfs_lookup(struct vop_lookup_args * ap)
+ /* struct vop_lookup_args {
+ struct vnodeop_desc *a_desc;
+ struct vnode *a_dvp;
+ struct vnode **a_vpp;
+ struct componentname *a_cnp;
+}; */
+{
+ struct componentname *cnp = ap->a_cnp;
+ int error;
+
+ XFSDEB(XDEBVNOPS, ("xfs_lookup: (%s, %ld), nameiop = %lu, flags = %lu\n",
+ cnp->cn_nameptr,
+ cnp->cn_namelen,
+ cnp->cn_nameiop,
+ cnp->cn_flags));
+
+ error = xfs_lookup_common(ap->a_dvp, cnp, ap->a_vpp);
+
+ if (error == ENOENT
+ && (cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME)
+ && (cnp->cn_flags & ISLASTCN)) {
+ error = EJUSTRETURN;
+ }
+
+ if (cnp->cn_nameiop != LOOKUP && cnp->cn_flags & ISLASTCN)
+ cnp->cn_flags |= SAVENAME;
+
+ XFSDEB(XDEBVNOPS, ("xfs_lookup: error = %d\n", error));
+
+ return error;
+}
+#endif /* HAVE_VOP_LOOKUP */
+
+#ifdef HAVE_VOP_CACHEDLOOKUP
+static int
+xfs_cachedlookup(struct vop_cachedlookup_args * ap)
+ /* struct vop_cachedlookup_args {
+ struct vnodeop_desc *a_desc;
+ struct vnode *a_dvp;
+ struct vnode **a_vpp;
+ struct componentname *a_cnp;
+}; */
+{
+ return xfs_lookup(ap);
+}
+#endif /* HAVE_VOP_CACHEDLOOKUP */
+
+#ifdef HAVE_VOP_CREATE
+static int
+xfs_create(struct vop_create_args * ap)
+{
+ struct vnode *dvp = ap->a_dvp;
+ struct componentname *cnp = ap->a_cnp;
+ const char *name = cnp->cn_nameptr;
+ struct ucred *cred = cnp->cn_cred;
+ int error;
+
+ error = xfs_create_common(dvp,
+ name,
+ ap->a_vap,
+ cred);
+
+ if (error == 0)
+ error = xfs_lookup_name(dvp, name, xfs_cnp_to_proc(cnp),
+ cred, ap->a_vpp);
+
+ if (error != 0 || (ap->a_cnp->cn_flags & SAVESTART) == 0)
+#ifdef HAVE_KERNEL_ZFREEI
+ zfreei(namei_zone, ap->a_cnp->cn_pnbuf);
+#else
+ free (ap->a_cnp->cn_pnbuf, M_NAMEI);
+#endif
+
+ XFSDEB(XDEBVNOPS, ("xfs_create: error = %d\n", error));
+
+ return error;
+}
+#endif /* HAVE_VOP_CREATE */
+
+#ifdef HAVE_VOP_REMOVE
+static int
+xfs_remove(struct vop_remove_args * ap)
+ /* struct vnode *dvp,
+ struct vnode *vp,
+ struct componentname *cnp */
+{
+ struct componentname *cnp = ap->a_cnp;
+ int error = xfs_remove_common(ap->a_dvp, ap->a_vp, cnp->cn_nameptr,
+ cnp->cn_cred);
+
+ if (error != 0 || (cnp->cn_flags & SAVESTART) == 0)
+#ifdef HAVE_KERNEL_ZFREEI
+ zfreei(namei_zone, cnp->cn_pnbuf);
+#else
+ free (cnp->cn_pnbuf, M_NAMEI);
+#endif
+
+ return error;
+}
+#endif /* HAVE_VOP_REMOVE */
+
+#ifdef HAVE_VOP_RENAME
+static int
+xfs_rename(struct vop_rename_args * ap)
+ /* vop_rename {
+ IN WILLRELE struct vnode *fdvp;
+ IN WILLRELE struct vnode *fvp;
+ IN struct componentname *fcnp;
+ IN WILLRELE struct vnode *tdvp;
+ IN WILLRELE struct vnode *tvp;
+ IN struct componentname *tcnp;
+ }; */
+{
+ struct vnode *tdvp = ap->a_tdvp;
+ struct vnode *tvp = ap->a_tvp;
+ struct vnode *fdvp = ap->a_fdvp;
+ struct vnode *fvp = ap->a_fvp;
+
+ int error = xfs_rename_common(fdvp,
+ fvp,
+ ap->a_fcnp->cn_nameptr,
+ tdvp,
+ tvp,
+ ap->a_tcnp->cn_nameptr,
+ ap->a_tcnp->cn_cred);
+ if(tdvp == tvp)
+ vrele(tdvp);
+ else
+ vput(tdvp);
+ if(tvp)
+ vput(tvp);
+ vrele(fdvp);
+ vrele(fvp);
+ return error;
+}
+#endif /* HAVE_VOP_RENAME */
+
+#ifdef HAVE_VOP_MKDIR
+static int
+xfs_mkdir(struct vop_mkdir_args * ap)
+ /* struct vnode *dvp,
+ char *nm,
+ struct vattr *va,
+ struct vnode **vpp,
+ struct ucred *cred) */
+{
+ struct vnode *dvp = ap->a_dvp;
+ struct componentname *cnp = ap->a_cnp;
+ const char *name = cnp->cn_nameptr;
+ struct ucred *cred = cnp->cn_cred;
+ int error;
+
+ error = xfs_mkdir_common(dvp,
+ name,
+ ap->a_vap,
+ cred);
+
+ if (error == 0)
+ error = xfs_lookup_name(dvp, name, xfs_cnp_to_proc(cnp),
+ cred, ap->a_vpp);
+
+ if (error != 0 || (ap->a_cnp->cn_flags & SAVESTART) == 0) {
+#ifdef HAVE_KERNEL_ZFREEI
+ zfreei(namei_zone, ap->a_cnp->cn_pnbuf);
+#else
+ free (ap->a_cnp->cn_pnbuf, M_NAMEI);
+#endif
+ }
+
+#if defined(__OpenBSD__)
+ vput(ap->a_dvp);
+#endif
+
+ XFSDEB(XDEBVNOPS, ("xfs_create: error = %d\n", error));
+
+ return error;
+}
+#endif /* HAVE_VOP_MKDIR */
+
+#ifdef HAVE_VOP_RMDIR
+static int
+xfs_rmdir(struct vop_rmdir_args * ap)
+ /* struct vnode *dvp,
+ struct vnode *vp,
+ struct componentname *cnp */
+{
+ struct componentname *cnp = ap->a_cnp;
+ int error = xfs_rmdir_common(ap->a_dvp, ap->a_vp,
+ cnp->cn_nameptr, cnp->cn_cred);
+
+ if (error != 0 || (cnp->cn_flags & SAVESTART) == 0)
+#ifdef HAVE_KERNEL_ZFREEI
+ zfreei(namei_zone, cnp->cn_pnbuf);
+#else
+ free (cnp->cn_pnbuf, M_NAMEI);
+#endif
+
+ return error;
+}
+#endif /* HAVE_VOP_RMDIR */
+
+#ifdef HAVE_VOP_READDIR
+static int
+xfs_readdir(struct vop_readdir_args * ap)
+ /* struct vnode *vp,
+ struct uio *uiop,
+ struct ucred *cred) */
+{
+ int error;
+ off_t off;
+
+ off = ap->a_uio->uio_offset;
+
+ error = xfs_readdir_common(ap->a_vp, ap->a_uio, ap->a_cred,
+ ap->a_eofflag);
+
+ if (!error && ap->a_ncookies != NULL) {
+ struct uio *uio = ap->a_uio;
+ struct dirent* dp;
+ int ncookies;
+#if defined(__FreeBSD__) || defined (__OpenBSD__)
+ u_long *cookies;
+ struct dirent* dpStart;
+ struct dirent* dpEnd;
+ u_long *cookiep;
+#else
+ off_t *cookies;
+ cookies = ap->a_cookies;
+ ncookies = ap->a_ncookies;
+#endif
+ if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
+ panic("xfs_readdir: mail arla-drinkers and tell them to bake burned cookies");
+ dp = (struct dirent *)
+ (uio->uio_iov->iov_base - (uio->uio_offset - off));
+#if defined(__FreeBSD__) || defined (__OpenBSD__)
+ dpEnd = (struct dirent *) uio->uio_iov->iov_base;
+ for (dpStart = dp, ncookies = 0;
+ dp < dpEnd;
+ dp = (struct dirent *)((caddr_t) dp + dp->d_reclen))
+ ncookies++;
+ MALLOC(cookies, u_long *, ncookies * sizeof(u_long),
+ M_TEMP, M_WAITOK);
+ for (dp = dpStart, cookiep = cookies;
+ dp < dpEnd;
+ dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) {
+ off += dp->d_reclen;
+ *cookiep++ = (u_int) off;
+ }
+ *ap->a_cookies = cookies;
+ *ap->a_ncookies = ncookies;
+#else /* __NetBSD__ */
+ while (ncookies-- && off < uio->uio_offset) {
+ if (dp->d_reclen == 0)
+ break;
+ off += dp->d_reclen;
+ *(cookies++) = off;
+ dp = (struct dirent *)((caddr_t)dp + dp->d_reclen);
+ }
+#endif
+ }
+ return error;
+}
+#endif /* HAVE_VOP_READDIR */
+
+#ifdef HAVE_VOP_LINK
+static int
+xfs_link(struct vop_link_args * ap)
+ /*
+ WILLRELE struct vnode *tdvp;
+ struct vnode *vp;
+ struct componentname *cnp;
+ */
+{
+ struct componentname *cnp = ap->a_cnp;
+ int error = xfs_link_common(
+#if defined (__OpenBSD__) || defined(__NetBSD__)
+ ap->a_dvp,
+#elif defined(__FreeBSD__)
+ ap->a_tdvp,
+#endif
+ ap->a_vp,
+ cnp->cn_nameptr,
+ cnp->cn_cred);
+
+ if (error != 0 || (cnp->cn_flags & SAVESTART) == 0)
+#ifdef HAVE_KERNEL_ZFREEI
+ zfreei(namei_zone, cnp->cn_pnbuf);
+#else
+ free (cnp->cn_pnbuf, M_NAMEI);
+#endif
+
+ return error;
+}
+#endif /* HAVE_VOP_LINK */
+
+#ifdef HAVE_VOP_SYMLINK
+static int
+xfs_symlink(struct vop_symlink_args * ap)
+ /*
+ IN WILLRELE struct vnode *dvp;
+ OUT WILLRELE struct vnode **vpp;
+ IN struct componentname *cnp;
+ IN struct vattr *vap;
+ IN char *target;
+ */
+{
+ struct componentname *cnp = ap->a_cnp;
+ int error = xfs_symlink_common(ap->a_dvp,
+ ap->a_vpp,
+ cnp->cn_nameptr,
+ xfs_cnp_to_proc(cnp),
+ cnp->cn_cred,
+ ap->a_vap,
+ ap->a_target);
+
+ if (error != 0 || (cnp->cn_flags & SAVESTART) == 0) {
+#ifdef HAVE_KERNEL_ZFREEI
+ zfreei(namei_zone, cnp->cn_pnbuf);
+#else
+ free (cnp->cn_pnbuf, M_NAMEI);
+#endif
+ }
+ return error;
+}
+#endif /* HAVE_VOP_SYMLINK */
+
+
+#ifdef HAVE_VOP_READLINK
+static int
+xfs_readlink(struct vop_readlink_args * ap)
+ /* struct vnode *vp,
+ struct uio *uiop,
+ struct ucred *cred) */
+{
+ return xfs_readlink_common(ap->a_vp, ap->a_uio, ap->a_cred);
+}
+#endif /* HAVE_VOP_READLINK */
+
+#ifdef HAVE_VOP_INACTIVE
+static int
+xfs_inactive(struct vop_inactive_args * ap)
+ /*struct vnode *vp,
+ struct ucred *cred)*/
+{
+#if 0
+ /*
+ * This break freebsd 2.2.x
+ */
+
+ return xfs_inactive_common(ap->a_vp, xfs_curproc());
+#else
+ return 0;
+#endif
+}
+#endif /* HAVE_VOP_INACTICE */
+
+#ifdef HAVE_VOP_RECLAIM
+static int
+xfs_reclaim(struct vop_reclaim_args * ap)
+ /*struct vop_reclaim_args {
+ struct vnodeop_desc *a_desc;
+ struct vnode *a_vp;
+};*/
+{
+ return xfs_reclaim_common(ap->a_vp);
+}
+#endif /* HAVE_VOP_RECLAIM */
+
+/*
+ * The lock, unlock, islocked vnode operations.
+ *
+ * This should be done with the generic locking function for the
+ * appropriate dialect of BSD (vop_nolock, genfs_nolock, ...). But,
+ * most of these functions are commented out and don't work enough to
+ * allow xfs_islocked to figure if the vnode is locked or not, which
+ * other parts of the kernel depend on.
+ *
+ * We try do locking the folling way:
+ * If we have LK_INTERLOCK & co:
+ * Do no locking with (we should use lockmgr)
+ * else
+ * When VXLOCK is set loop
+ */
+
+#ifdef HAVE_VOP_LOCK
+static int
+xfs_lock(struct vop_lock_args * ap)
+{
+ struct vnode *vp = ap->a_vp;
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+
+ XFSDEB(XDEBVNOPS, ("xfs_lock: %p, %d\n", vp, xn->vnlocks));
+
+#if defined(HAVE_LK_INTERLOCK) && !defined(HAVE_ONE_ARGUMENT_VOP_LOCK)
+ {
+ int flags = ap->a_flags;
+
+ if (flags & LK_INTERLOCK)
+ simple_unlock(&vp->v_interlock);
+
+ if (!(flags & LK_TYPE_MASK))
+ return 0;
+ }
+#else
+ while (vp->v_flag & VXLOCK) {
+ vp->v_flag |= VXWANT;
+ (void) tsleep((caddr_t)vp, PINOD, "xfs_vnlock", 0);
+ }
+ if (vp->v_tag == VT_NON)
+ return (ENOENT);
+#endif
+ ++xn->vnlocks;
+ return 0;
+}
+#endif /* HAVE_VOP_LOCK */
+
+#ifdef HAVE_VOP_UNLOCK
+static int
+xfs_unlock(struct vop_unlock_args * ap)
+{
+ struct vnode *vp = ap->a_vp;
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+ XFSDEB(XDEBVNOPS, ("xfs_unlock: %p, %d\n", vp, xn->vnlocks));
+
+#if defined(HAVE_LK_INTERLOCK) && !defined(HAVE_ONE_ARGUMENT_VOP_LOCK)
+ {
+ int flags = ap->a_flags;
+
+ if (flags & LK_INTERLOCK)
+ simple_unlock(&vp->v_interlock);
+ if (!(flags & LK_TYPE_MASK))
+ return 0;
+ }
+#endif
+ --xn->vnlocks;
+ if (xn->vnlocks < 0) {
+ printf ("PANIC: xfs_unlock: unlocking unlocked\n");
+ xn->vnlocks = 0;
+ }
+ return 0;
+}
+#endif /* HAVE_VOP_UNLOCK */
+
+#ifdef HAVE_VOP_ISLOCKED
+static int
+xfs_islocked (struct vop_islocked_args *ap)
+{
+ struct vnode *vp = ap->a_vp;
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+
+ XFSDEB(XDEBVNOPS, ("xfs_islocked: %p, %d\n", vp, xn->vnlocks));
+
+ return xn->vnlocks;
+}
+#endif /* HAVE_VOP_ISLOCKED */
+
+#ifdef HAVE_VOP_ABORTOP
+static int
+xfs_abortop (struct vop_abortop_args *ap)
+ /* struct vnode *dvp;
+ struct componentname *cnp; */
+{
+ struct componentname *cnp = ap->a_cnp;
+
+ if ((cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
+#ifdef HAVE_KERNEL_ZFREEI
+ zfreei(namei_zone, cnp->cn_pnbuf);
+#else
+ FREE(cnp->cn_pnbuf, M_NAMEI);
+#endif
+ return 0;
+}
+#endif /* HAVE_VOP_ABORTOP */
+
+#ifdef HAVE_VOP_MMAP
+static int
+xfs_mmap(struct vop_mmap_args *ap)
+ /*
+ IN struct vnode *vp;
+ IN int fflags;
+ IN struct ucred *cred;
+ IN struct proc *p;
+ */
+{
+ XFSDEB(XDEBVNOPS, ("xfs_mmap\n"));
+ return EOPNOTSUPP;
+}
+#endif /* HAVE_VOP_MMAP */
+
+#ifdef HAVE_VOP_BMAP
+static int
+xfs_bmap(struct vop_bmap_args *ap)
+ /* IN struct vnode *vp;
+ IN daddr_t bn;
+ OUT struct vnode **vpp;
+ IN daddr_t *bnp;
+ OUT int *runp;
+ OUT int *runb;
+ */
+{
+ XFSDEB(XDEBVNOPS, ("xfs_bmap\n"));
+ return EOPNOTSUPP;
+}
+#endif /* HAVE_VOP_BMAP */
+
+#ifdef HAVE_VOP_GETPAGES
+static int
+xfs_getpages (struct vop_getpages_args *ap)
+ /*
+ IN struct vnode *vp;
+ IN vm_page_t *m;
+ IN int count;
+ IN int reqpage;
+ IN vm_ooffset_t offset;
+ */
+{
+ int error;
+
+ XFSDEB(XDEBVNOPS, ("xfs_getpages\n"));
+
+#if HAVE_KERNEL_VNODE_PAGER_GENERIC_GETPAGES
+ error = vnode_pager_generic_getpages (ap->a_vp, ap->a_m,
+ ap->a_count, ap->a_reqpage);
+#else
+ error = EOPNOTSUPP;
+#endif
+ XFSDEB(XDEBVNOPS, ("xfs_getpages = %d\n", error));
+ return error;
+}
+#endif /* HAVE_VOP_GETPAGES */
+
+#ifdef HAVE_VOP_PUTPAGES
+static int
+xfs_putpages (struct vop_putpages_args *ap)
+ /*
+ IN struct vnode *vp;
+ IN vm_page_t *m;
+ IN int count;
+ IN int sync;
+ IN int *rtvals;
+ IN vm_ooffset_t offset;
+ */
+{
+ XFSDEB(XDEBVNOPS, ("xfs_putpages\n"));
+
+#if HAVE_KERNEL_VNODE_PAGER_GENERIC_PUTPAGES
+ return vnode_pager_generic_putpages (ap->a_vp, ap->a_m, ap->a_count,
+ ap->a_sync, ap->a_rtvals);
+#else
+ return EOPNOTSUPP;
+#endif
+}
+#endif /* HAVE_VOP_PUTPAGES */
+
+#ifdef HAVE_VOP_CMP
+static int
+xfs_cmp(struct vnode * vp1, struct vnode * vp2)
+{
+ XFSDEB(XDEBVNOPS, ("xfs_cmp\n"));
+ return EOPNOTSUPP;
+}
+#endif /* HAVE_VOP_CMP */
+
+#ifdef HAVE_VOP_REALVP
+static int
+xfs_realvp(struct vnode * vp,
+ struct vnode ** vpp)
+{
+ XFSDEB(XDEBVNOPS, ("xfs_realvp\n"));
+ return EOPNOTSUPP;
+}
+#endif /* HAVE_VOP_REALVP */
+
+#ifdef HAVE_VOP_CNTL
+static int
+xfs_cntl(struct vnode * vp,
+ int cmd,
+ caddr_t idata,
+ caddr_t odata,
+ int iflag,
+ int oflag)
+{
+ XFSDEB(XDEBVNOPS, ("xfs_cntl\n"));
+ return EOPNOTSUPP;
+}
+#endif /* HAVE_VOP_CNTL */
+
+#ifdef HAVE_VOP_PRINT
+static int
+xfs_print (struct vnode *vp)
+{
+ xfs_printnode_common (vp);
+ return 0;
+}
+#endif
+
+#if 0
+#ifdef HAVE_VOP_ADVLOCK
+static int
+xfs_advlock(void *v)
+{
+ struct vop_advlock_args /* {
+ struct vnode *a_vp;
+ caddr_t a_id;
+ int a_op;
+ struct flock *a_fl;
+ int a_flags;
+ } */ *ap = v;
+
+ struct xfs_node *xn = VNODE_TO_XNODE(ap->a_vp);
+ int ret;
+ xfs_locktype_t locktype;
+
+/* if (XFS_TOKEN_GOT(xn, */
+
+#if 0
+ if (ap->a_fl.l_start != 0 ||
+ ap->a_fl.l_end != 0)
+ printf ("WARN: someone is trying byte-range locking\n");
+
+ switch (ap->a_op) {
+ case F_SETLCK:
+ locktype = XFS_READLOCK;
+ break;
+
+ ret = xfs_advlock_common (xn, );
+
+ return ret;
+#else
+ return 0;
+#endif
+}
+#endif /* HAVE_VOP_ADVOCK */
+#endif
+
+#ifdef HAVE_VOP_REVOKE
+static int
+xfs_revoke(void *v)
+{
+#if defined(HAVE_KERNEL_GENFS_REVOKE)
+ return genfs_revoke (v);
+#elif defined(HAVE_KERNEL_VOP_REVOKE)
+ return vop_revoke (v);
+#else
+ return EOPNOTSUPP;
+#endif
+}
+#endif /* HAVE_VOP_REVOKE */
+
+vop_t **xfs_vnodeop_p;
+
+int
+xfs_eopnotsupp (void *v)
+{
+ XFSDEB(XDEBVNOPS, ("xfs_eopnotsupp\n"));
+ return EOPNOTSUPP;
+}
+
+int
+xfs_returnzero (void *v)
+{
+ XFSDEB(XDEBVNOPS, ("xfs_returnzero\n"));
+ return 0;
+}
+
+static struct vnodeopv_entry_desc xfs_vnodeop_entries[] = {
+ {&vop_default_desc, (vop_t *) xfs_eopnotsupp},
+#ifdef HAVE_VOP_LOOKUP
+#ifdef HAVE_KERNEL_VFS_CACHE_LOOKUP
+ {&vop_lookup_desc, (vop_t *) vfs_cache_lookup },
+#else
+ {&vop_lookup_desc, (vop_t *) xfs_lookup },
+#endif
+#endif
+#ifdef HAVE_VOP_CACHEDLOOKUP
+ {&vop_cachedlookup_desc, (vop_t *) xfs_cachedlookup },
+#endif
+#ifdef HAVE_VOP_OPEN
+ {&vop_open_desc, (vop_t *) xfs_open },
+#endif
+#ifdef HAVE_VOP_FSYNC
+ {&vop_fsync_desc, (vop_t *) xfs_fsync },
+#endif
+#ifdef HAVE_VOP_CLOSE
+ {&vop_close_desc, (vop_t *) xfs_close },
+#endif
+#ifdef HAVE_VOP_READ
+ {&vop_read_desc, (vop_t *) xfs_read },
+#endif
+#ifdef HAVE_VOP_WRITE
+ {&vop_write_desc, (vop_t *) xfs_write },
+#endif
+#ifdef HAVE_VOP_MMAP
+ {&vop_mmap_desc, (vop_t *) xfs_mmap },
+#endif
+#ifdef HAVE_VOP_BMAP
+ {&vop_bmap_desc, (vop_t *) xfs_bmap },
+#endif
+#ifdef HAVE_VOP_IOCTL
+ {&vop_ioctl_desc, (vop_t *) xfs_ioctl },
+#endif
+#ifdef HAVE_VOP_SELECT
+ {&vop_select_desc, (vop_t *) xfs_select },
+#endif
+#ifdef HAVE_VOP_SEEK
+ {&vop_seek_desc, (vop_t *) xfs_seek },
+#endif
+#ifdef HAVE_VOP_POLL
+ {&vop_poll_desc, (vop_t *) xfs_poll },
+#endif
+#ifdef HAVE_VOP_GETATTR
+ {&vop_getattr_desc, (vop_t *) xfs_getattr },
+#endif
+#ifdef HAVE_VOP_SETATTR
+ {&vop_setattr_desc, (vop_t *) xfs_setattr },
+#endif
+#ifdef HAVE_VOP_ACCESS
+ {&vop_access_desc, (vop_t *) xfs_access },
+#endif
+#ifdef HAVE_VOP_CREATE
+ {&vop_create_desc, (vop_t *) xfs_create },
+#endif
+#ifdef HAVE_VOP_REMOVE
+ {&vop_remove_desc, (vop_t *) xfs_remove },
+#endif
+#ifdef HAVE_VOP_LINK
+ {&vop_link_desc, (vop_t *) xfs_link },
+#endif
+#ifdef HAVE_VOP_RENAME
+ {&vop_rename_desc, (vop_t *) xfs_rename },
+#endif
+#ifdef HAVE_VOP_MKDIR
+ {&vop_mkdir_desc, (vop_t *) xfs_mkdir },
+#endif
+#ifdef HAVE_VOP_RMDIR
+ {&vop_rmdir_desc, (vop_t *) xfs_rmdir },
+#endif
+#ifdef HAVE_VOP_READDIR
+ {&vop_readdir_desc, (vop_t *) xfs_readdir },
+#endif
+#ifdef HAVE_VOP_SYMLINK
+ {&vop_symlink_desc, (vop_t *) xfs_symlink },
+#endif
+#ifdef HAVE_VOP_READLINK
+ {&vop_readlink_desc, (vop_t *) xfs_readlink },
+#endif
+#ifdef HAVE_VOP_INACTIVE
+ {&vop_inactive_desc, (vop_t *) xfs_inactive },
+#endif
+#ifdef HAVE_VOP_RECLAIM
+ {&vop_reclaim_desc, (vop_t *) xfs_reclaim },
+#endif
+#ifdef HAVE_VOP_LOCK
+ {&vop_lock_desc, (vop_t *) xfs_lock },
+#endif
+#ifdef HAVE_VOP_UNLOCK
+ {&vop_unlock_desc, (vop_t *) xfs_unlock },
+#endif
+#ifdef HAVE_VOP_ISLOCKED
+ {&vop_islocked_desc, (vop_t *) xfs_islocked },
+#endif
+#ifdef HAVE_VOP_ABORTOP
+ {&vop_abortop_desc, (vop_t *) xfs_abortop },
+#endif
+#ifdef HAVE_VOP_GETPAGES
+ {&vop_getpages_desc, (vop_t *) xfs_getpages },
+#endif
+#ifdef HAVE_VOP_PUTPAGES
+ {&vop_putpages_desc, (vop_t *) xfs_putpages },
+#endif
+#ifdef HAVE_VOP_REVOKE
+ {&vop_revoke_desc, (vop_t *) xfs_revoke },
+#endif
+#ifdef HAVE_VOP_PRINT
+ {&vop_print_desc, (vop_t *) xfs_print},
+#endif
+#if 0
+#ifdef HAVE_VOP_ADVLOCK
+ {&vop_advlock_desc, (vop_t *) xfs_advlock },
+#endif
+#endif
+ {(struct vnodeop_desc *) NULL, (int (*) (void *)) NULL}
+};
+
+struct vnodeopv_desc xfs_vnodeop_opv_desc =
+{&xfs_vnodeop_p, xfs_vnodeop_entries};
+
+#ifdef VNODEOP_SET
+VNODEOP_SET(xfs_vnodeop_opv_desc);
+#endif
diff --git a/sys/xfs/xfs_vnodeops-common.c b/sys/xfs/xfs_vnodeops-common.c
new file mode 100644
index 00000000000..fee9b17acc8
--- /dev/null
+++ b/sys/xfs/xfs_vnodeops-common.c
@@ -0,0 +1,948 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/*
+ * XFS operations.
+ */
+
+#include <xfs/xfs_locl.h>
+#include <xfs/xfs_message.h>
+#include <xfs/xfs_common.h>
+#include <xfs/xfs_fs.h>
+#include <xfs/xfs_dev.h>
+#include <xfs/xfs_deb.h>
+#include <xfs/xfs_syscalls.h>
+#include <xfs/xfs_vnodeops.h>
+
+RCSID("$Id: xfs_vnodeops-common.c,v 1.1 1999/04/30 01:59:01 art Exp $");
+
+int
+xfs_open_valid(struct vnode * vp, struct ucred * cred, u_int tok)
+{
+ struct xfs *xfsp = XFS_FROM_VNODE(vp);
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+ int error = 0;
+
+ XFSDEB(XDEBVFOPS, ("xfs_open_valid\n"));
+
+ do {
+ if (!XFS_TOKEN_GOT(xn, tok)) {
+ struct xfs_message_open msg;
+
+ msg.header.opcode = XFS_MSG_OPEN;
+ msg.cred.uid = cred->cr_uid;
+ msg.cred.pag = xfs_get_pag(cred);
+ msg.handle = xn->handle;
+ msg.tokens = tok;
+ error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+ if (error == 0)
+ error = ((struct xfs_message_wakeup *) & msg)->error;
+ } else {
+ goto done;
+ }
+ } while (error == 0);
+
+done:
+ XFSDEB(XDEBVFOPS, ("xfs_open_valid: error = %d\n", error));
+
+ return error;
+}
+
+int
+xfs_attr_valid(struct vnode * vp, struct ucred * cred, u_int tok)
+{
+ struct xfs *xfsp = XFS_FROM_VNODE(vp);
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+ int error = 0;
+ pag_t pag = xfs_get_pag(cred);
+
+ do {
+ if (!XFS_TOKEN_GOT(xn, tok)) {
+ struct xfs_message_getattr msg;
+
+ msg.header.opcode = XFS_MSG_GETATTR;
+ msg.cred.uid = cred->cr_uid;
+ msg.cred.pag = pag;
+ msg.handle = xn->handle;
+ error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+ if (error == 0)
+ error = ((struct xfs_message_wakeup *) & msg)->error;
+ } else {
+ goto done;
+ }
+ } while (error == 0);
+
+done:
+ return error;
+}
+
+int
+xfs_fetch_rights(struct vnode * vp, struct ucred * cred)
+{
+ struct xfs *xfsp = XFS_FROM_VNODE(vp);
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+ int error = 0;
+
+ pag_t pag = xfs_get_pag(cred);
+
+ do {
+ if (!xfs_has_pag(xn, pag)) {
+ struct xfs_message_getattr msg;
+
+ msg.header.opcode = XFS_MSG_GETATTR;
+ msg.cred.uid = cred->cr_uid;
+ msg.cred.pag = pag;
+ msg.handle = xn->handle;
+ error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+ if (error == 0)
+ error = ((struct xfs_message_wakeup *) & msg)->error;
+ } else {
+ goto done;
+ }
+ } while (error == 0);
+
+done:
+
+ return error;
+}
+
+int
+xfs_data_valid(struct vnode * vp, struct ucred * cred, u_int tok)
+{
+ struct xfs *xfsp = XFS_FROM_VNODE(vp);
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+ int error = 0;
+
+ do {
+ if (!XFS_TOKEN_GOT(xn, tok)) {
+ struct xfs_message_getdata msg;
+
+ msg.header.opcode = XFS_MSG_GETDATA;
+ msg.cred.uid = cred->cr_uid;
+ msg.cred.pag = xfs_get_pag(cred);
+ msg.handle = xn->handle;
+ msg.tokens = tok;
+ error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+ if (error == 0)
+ error = ((struct xfs_message_wakeup *) & msg)->error;
+ } else {
+ goto done;
+ }
+ } while (error == 0);
+
+done:
+ return error;
+}
+
+static int
+do_fsync(struct xfs * xfsp,
+ struct xfs_node * xn,
+ struct ucred * cred,
+ u_int flag)
+{
+ int error;
+ struct xfs_message_putdata msg;
+
+ msg.header.opcode = XFS_MSG_PUTDATA;
+ if (cred != NOCRED) {
+ msg.cred.uid = cred->cr_uid;
+ msg.cred.pag = xfs_get_pag(cred);
+ } else {
+ msg.cred.uid = 0;
+ msg.cred.pag = XFS_ANONYMOUSID;
+ }
+ msg.handle = xn->handle;
+ vattr2xfs_attr(&xn->attr, &msg.attr);
+ msg.flag = flag;
+
+ error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+ if (error == 0)
+ error = ((struct xfs_message_wakeup *) & msg)->error;
+
+ if (error == 0)
+ xn->flags &= ~XFS_DATA_DIRTY;
+
+ return error;
+}
+
+int
+xfs_fsync_common(struct vnode *vp, struct ucred *cred,
+ int waitfor, struct proc *proc)
+{
+ struct xfs *xfsp = XFS_FROM_VNODE(vp);
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+ int error = 0;
+
+ XFSDEB(XDEBVNOPS, ("xfs_fsync: %p\n", vp));
+
+ /*
+ * It seems that fsync is sometimes called after reclaiming a node.
+ * In that case we just look happy.
+ */
+
+ if (xn == NULL) {
+ printf("XFS PANIC WARNING! xfs_fsync called after reclaiming!\n");
+ return 0;
+ }
+
+ if (xn->flags & XFS_DATA_DIRTY)
+ error = do_fsync(xfsp, xn, cred, XFS_WRITE);
+
+ return error;
+}
+
+int
+xfs_close_common(struct vnode *vp, int fflag,
+ struct proc *proc, struct ucred *cred)
+{
+ struct xfs *xfsp = XFS_FROM_VNODE(vp);
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+ int error = 0;
+
+ XFSDEB(XDEBVNOPS, ("xfs_close cred = %p\n", cred));
+
+ if (fflag & FWRITE && xn->flags & XFS_DATA_DIRTY)
+ error = do_fsync(xfsp, xn, cred, XFS_WRITE);
+
+ return error;
+}
+
+int
+xfs_read_common(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
+{
+ int error = 0;
+
+ XFSDEB(XDEBVNOPS, ("xfs_read\n"));
+
+ error = xfs_data_valid(vp, cred, XFS_DATA_R);
+
+ if (error == 0) {
+ struct vnode *t = DATA_FROM_VNODE(vp);
+
+ xfs_vfs_readlock(t, xfs_uio_to_proc(uio));
+#ifdef __osf__
+ VOP_READ(t, uio, ioflag, cred, error);
+#else /* __osf__ */
+ error = VOP_READ(t, uio, ioflag, cred);
+#endif /* __osf__ */
+ xfs_vfs_unlock(t, xfs_uio_to_proc(uio));
+ }
+ return error;
+}
+
+int
+xfs_write_common(struct vnode *vp, struct uio *uiop, int ioflag, struct ucred *cred)
+{
+ int error = 0;
+
+ XFSDEB(XDEBVNOPS, ("xfs_write\n"));
+
+ error = xfs_data_valid(vp, cred, XFS_DATA_W);
+
+ if (error == 0) {
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+ struct vnode *t = DATA_FROM_XNODE(xn);
+ struct vattr sub_attr;
+ int error2 = 0;
+
+ xfs_vfs_writelock(t, xfs_uio_to_proc(uiop));
+#ifdef __osf__
+ VOP_WRITE(t, uiop, ioflag, cred, error);
+ VNODE_TO_XNODE(vp)->flags |= XFS_DATA_DIRTY;
+ VOP_GETATTR(t, &sub_attr, cred, error2);
+#else /* __osf__ */
+ error = VOP_WRITE(t, uiop, ioflag, cred);
+ VNODE_TO_XNODE(vp)->flags |= XFS_DATA_DIRTY;
+ error2 = VOP_GETATTR(t, &sub_attr, cred, uiop->uio_procp);
+#endif /* __osf__ */
+
+ if (error2 == 0) {
+ xn->attr.va_size = sub_attr.va_size;
+ xn->attr.va_mtime = sub_attr.va_mtime;
+#ifdef HAVE_KERNEL_VNODE_PAGER_SETSIZE
+ vnode_pager_setsize(vp, sub_attr.va_size);
+#endif
+ }
+ xfs_vfs_unlock(t, xfs_uio_to_proc(uiop));
+ }
+
+ return error;
+}
+
+int
+xfs_getattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred)
+{
+ int error = 0;
+
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+
+ XFSDEB(XDEBVNOPS, ("xfs_getattr\n"));
+
+ error = xfs_attr_valid(vp, cred, XFS_ATTR_R);
+ if (error == 0)
+ *vap = xn->attr;
+ return error;
+}
+
+int
+xfs_setattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred)
+{
+ struct xfs *xfsp = XFS_FROM_VNODE(vp);
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+ int error = 0;
+
+ XFSDEB(XDEBVNOPS, ("xfs_setattr\n"));
+
+#define CHECK_XFSATTR(A, cast) (vap->A == cast VNOVAL || vap->A == xn->attr.A)
+ if (CHECK_XFSATTR(va_mode,(mode_t)) &&
+ CHECK_XFSATTR(va_nlink,) &&
+ CHECK_XFSATTR(va_size,) &&
+ CHECK_XFSATTR(va_uid,) &&
+ CHECK_XFSATTR(va_gid,) &&
+ CHECK_XFSATTR(va_mtime.tv_sec,) &&
+ CHECK_XFSATTR(va_fileid,) &&
+ CHECK_XFSATTR(va_type,))
+ return 0; /* Nothing to do */
+#undef CHECK_XFSATTR
+
+ if (XFS_TOKEN_GOT(xn, XFS_ATTR_W)) {
+ /* Update attributes and mark them dirty. */
+ VNODE_TO_XNODE(vp)->flags |= XFS_ATTR_DIRTY;
+ error = EINVAL; /* XXX not yet implemented */
+ goto done;
+ } else {
+ struct xfs_message_putattr msg;
+
+ msg.header.opcode = XFS_MSG_PUTATTR;
+ if (cred != NOCRED) {
+ msg.cred.uid = cred->cr_uid;
+ msg.cred.pag = xfs_get_pag(cred);
+ } else {
+ msg.cred.uid = 0;
+ msg.cred.pag = XFS_ANONYMOUSID;
+ }
+ msg.handle = xn->handle;
+ vattr2xfs_attr(vap, &msg.attr);
+
+ XFS_TOKEN_CLEAR(xn, XFS_ATTR_VALID, XFS_ATTR_MASK);
+ error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+ if (error == 0)
+ error = ((struct xfs_message_wakeup *) & msg)->error;
+ }
+
+done:
+ return error;
+}
+
+static int
+check_rights (u_char rights, int mode)
+{
+ int error = 0;
+
+ if (mode & VREAD)
+ if ((rights & XFS_RIGHT_R) == 0)
+ error = EACCES;
+ if (mode & VWRITE)
+ if ((rights & XFS_RIGHT_W) == 0)
+ error = EACCES;
+ if (mode & VEXEC)
+ if ((rights & XFS_RIGHT_X) == 0)
+ error = EACCES;
+ return error;
+}
+
+int
+xfs_access_common(struct vnode *vp, int mode, struct ucred *cred)
+{
+ int error = 0;
+ pag_t pag = xfs_get_pag(cred);
+
+ XFSDEB(XDEBVNOPS, ("xfs_access mode = 0%o\n", mode));
+
+ error = xfs_attr_valid(vp, cred, XFS_ATTR_R);
+ if (error == 0) {
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+ int i;
+
+ error = check_rights (xn->anonrights, mode);
+
+ if (error == 0)
+ goto done;
+
+ XFSDEB(XDEBVNOPS, ("xfs_access anonaccess failed\n"));
+
+ xfs_fetch_rights(vp, cred); /* ignore error */
+
+ error = EACCES; /* default to EACCES if pag isn't in xn->id */
+
+ for (i = 0; i < MAXRIGHTS; i++)
+ if (xn->id[i] == pag) {
+ error = check_rights (xn->rights[i], mode);
+ break;
+ }
+ }
+
+done:
+ XFSDEB(XDEBVNOPS, ("xfs_access(0%o) = %d\n", mode, error));
+
+ return error;
+}
+
+int
+xfs_lookup_common(struct vnode *dvp,
+ xfs_componentname *cnp,
+ struct vnode **vpp)
+{
+ struct xfs_message_getnode msg;
+ struct xfs *xfsp = XFS_FROM_VNODE(dvp);
+ struct xfs_node *d = VNODE_TO_XNODE(dvp);
+ int error = 0;
+ struct proc *proc = xfs_cnp_to_proc(cnp);
+ struct ucred *cred = xfs_proc_to_cred(proc);
+
+ *vpp = NULL;
+
+ if (dvp->v_type != VDIR)
+ return ENOTDIR;
+
+ again:
+
+ do {
+#ifdef __osf__
+ VOP_ACCESS(dvp, VEXEC, cred, error);
+#else
+ error = VOP_ACCESS(dvp, VEXEC, cred, xfs_cnp_to_proc(cnp));
+#endif
+ if (error != 0)
+ goto done;
+
+ error = xfs_dnlc_lookup(dvp, cnp, vpp);
+ if (error == 0) {
+
+ /*
+ * Doesn't quite work.
+ */
+
+#if 0
+ if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME)
+ && (cnp->cn_flags & ISLASTCN)) {
+ error = EJUSTRETURN;
+ goto done;
+ }
+#endif
+
+ msg.header.opcode = XFS_MSG_GETNODE;
+ if (cnp->cn_cred != NOCRED) {
+ msg.cred.uid = cnp->cn_cred->cr_uid;
+ msg.cred.pag = xfs_get_pag(cnp->cn_cred);
+ } else {
+ msg.cred.uid = 0;
+ msg.cred.pag = XFS_ANONYMOUSID;
+ }
+ msg.parent_handle = d->handle;
+
+ bcopy(cnp->cn_nameptr, msg.name, cnp->cn_namelen);
+ msg.name[cnp->cn_namelen] = '\0';
+
+ error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+
+ if (error == 0)
+ error = ((struct xfs_message_wakeup *) & msg)->error;
+ if(error == ENOENT && cnp->cn_nameiop != CREATE) {
+ XFSDEB(XDEBVNOPS, ("xfs_lookup: neg cache %p (%s, %ld)\n",
+ dvp,
+ cnp->cn_nameptr, cnp->cn_namelen));
+ xfs_dnlc_enter (dvp, cnp, NULL);
+ }
+ } else if (error == -1) {
+ if (xfs_do_vget(*vpp, LK_EXCLUSIVE, xfs_cnp_to_proc(cnp)))
+ goto again;
+ error = 0;
+ goto done;
+ }
+ } while (error == 0);
+
+done:
+ return error;
+}
+
+int
+xfs_lookup_name(struct vnode *dvp,
+ const char *name,
+ struct proc *proc,
+ struct ucred *cred,
+ struct vnode **vpp)
+{
+ xfs_componentname cn;
+
+ xfs_cnp_init (&cn, name, NULL, dvp, proc, cred, CREATE);
+ return xfs_lookup_common (dvp, &cn, vpp);
+}
+
+int
+xfs_create_common(struct vnode *dvp,
+ const char *name,
+ struct vattr *vap,
+ struct ucred *cred)
+{
+ struct xfs *xfsp = XFS_FROM_VNODE(dvp);
+ struct xfs_node *xn = VNODE_TO_XNODE(dvp);
+ int error = 0;
+
+ XFSDEB(XDEBVNOPS, ("xfs_create: (%s)\n", name));
+ {
+ struct xfs_message_create msg;
+
+ msg.header.opcode = XFS_MSG_CREATE;
+ msg.parent_handle = xn->handle;
+ strncpy(msg.name, name, 256);
+ vattr2xfs_attr(vap, &msg.attr);
+
+ msg.mode = 0; /* XXX - mode */
+ if (cred != NOCRED) {
+ msg.cred.uid = cred->cr_uid;
+ msg.cred.pag = xfs_get_pag(cred);
+ } else {
+ msg.cred.uid = 0;
+ msg.cred.pag = XFS_ANONYMOUSID;
+ }
+
+ error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+ if (error == 0)
+ error = ((struct xfs_message_wakeup *) & msg)->error;
+ }
+
+#if 0
+ if (error == EEXIST)
+ error = 0;
+#endif
+
+ return error;
+}
+
+int
+xfs_remove_common(struct vnode *dvp,
+ struct vnode *vp,
+ const char *name,
+ struct ucred *cred)
+{
+ struct xfs *xfsp = XFS_FROM_VNODE(dvp);
+ struct xfs_node *xn = VNODE_TO_XNODE(dvp);
+ struct xfs_message_remove msg;
+ int error;
+
+ XFSDEB(XDEBVNOPS, ("xfs_remove: %s\n", name));
+
+ msg.header.opcode = XFS_MSG_REMOVE;
+ msg.parent_handle = xn->handle;
+ strncpy(msg.name, name, 256);
+ msg.cred.uid = cred->cr_uid;
+ msg.cred.pag = xfs_get_pag(cred);
+ error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+ if (error == 0)
+ error = ((struct xfs_message_wakeup *) &msg)->error;
+
+ if (error == 0)
+ xfs_dnlc_purge (vp);
+
+#if !defined(__FreeBSD__) || __FreeBSD_version < 300000
+ if (dvp == vp)
+ vrele(vp);
+ else
+ vput(vp);
+ vput(dvp);
+#endif
+
+ return error;
+}
+
+int
+xfs_rename_common(struct vnode *fdvp,
+ struct vnode *fvp,
+ const char *fname,
+ struct vnode *tdvp,
+ struct vnode *tvp,
+ const char *tname,
+ struct ucred *cred)
+{
+ struct xfs *xfsp = XFS_FROM_VNODE(fdvp);
+ int error;
+
+ XFSDEB(XDEBVNOPS, ("xfs_rename: %s %s\n", fname, tname));
+
+ if ((fvp->v_mount != tdvp->v_mount)
+ || (tvp && (fvp->v_mount != tvp->v_mount))) {
+ return EXDEV;
+ }
+
+ {
+ struct xfs_message_rename msg;
+
+ msg.header.opcode = XFS_MSG_RENAME;
+ msg.old_parent_handle = VNODE_TO_XNODE(fdvp)->handle;
+ strncpy(msg.old_name, fname, 256);
+ msg.new_parent_handle = VNODE_TO_XNODE(tdvp)->handle;
+ strncpy(msg.new_name, tname, 256);
+ msg.cred.uid = cred->cr_uid;
+ msg.cred.pag = xfs_get_pag(cred);
+ error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+ if (error == 0)
+ error = ((struct xfs_message_wakeup *) &msg)->error;
+
+ }
+
+ XFSDEB(XDEBVNOPS, ("xfs_rename: error = %d\n", error));
+
+ return error;
+}
+
+int
+xfs_mkdir_common(struct vnode *dvp,
+ const char *name,
+ struct vattr *vap,
+ struct ucred *cred)
+{
+ struct xfs *xfsp = XFS_FROM_VNODE(dvp);
+ struct xfs_node *xn = VNODE_TO_XNODE(dvp);
+ int error = 0;
+
+ XFSDEB(XDEBVNOPS, ("xfs_mkdir: %s\n", name));
+ {
+ struct xfs_message_mkdir msg;
+
+ msg.header.opcode = XFS_MSG_MKDIR;
+ msg.parent_handle = xn->handle;
+ strncpy(msg.name, name, 256);
+ vattr2xfs_attr(vap, &msg.attr);
+ if (cred != NOCRED) {
+ msg.cred.uid = cred->cr_uid;
+ msg.cred.pag = xfs_get_pag(cred);
+ } else {
+ msg.cred.uid = 0;
+ msg.cred.pag = XFS_ANONYMOUSID;
+ }
+ error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+ if (error == 0)
+ error = ((struct xfs_message_wakeup *) & msg)->error;
+ }
+
+ return error;
+}
+
+int
+xfs_rmdir_common(struct vnode *dvp,
+ struct vnode *vp,
+ const char *name,
+ struct ucred *cred)
+{
+ struct xfs *xfsp = XFS_FROM_VNODE(dvp);
+ struct xfs_node *xn = VNODE_TO_XNODE(dvp);
+ struct xfs_message_rmdir msg;
+ int error;
+
+ XFSDEB(XDEBVNOPS, ("xfs_rmdir: %s\n", name));
+
+ msg.header.opcode = XFS_MSG_RMDIR;
+ msg.parent_handle = xn->handle;
+ strncpy(msg.name, name, 256);
+ msg.cred.uid = cred->cr_uid;
+ msg.cred.pag = xfs_get_pag(cred);
+ error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+ if (error == 0)
+ error = ((struct xfs_message_wakeup *) &msg)->error;
+
+ if (error == 0)
+ xfs_dnlc_purge (vp);
+
+#if !defined(__FreeBSD__) || __FreeBSD_version < 300000
+ if (dvp == vp)
+ vrele(vp);
+ else
+ vput(vp);
+ vput(dvp);
+#endif
+
+ return error;
+}
+
+int
+xfs_readdir_common(struct vnode *vp,
+ struct uio *uiop,
+ struct ucred *cred,
+ int *eofflag)
+{
+ int error = 0;
+
+ XFSDEB(XDEBVNOPS, ("xfs_readdir\n"));
+
+ if(eofflag)
+ *eofflag = 0;
+ error = xfs_data_valid(vp, cred, XFS_DATA_R);
+ if (error == 0) {
+ struct vnode *t = DATA_FROM_VNODE(vp);
+
+ xfs_vfs_readlock(t, xfs_uio_to_proc(uiop));
+#ifdef __osf__
+ VOP_READ(t, uiop, 0, cred, error);
+#else
+ error = VOP_READ(t, uiop, 0, cred);
+#endif
+ if(eofflag)
+ *eofflag = VNODE_TO_XNODE(vp)->attr.va_size <= uiop->uio_offset;
+ xfs_vfs_unlock(t, xfs_uio_to_proc(uiop));
+ }
+ return error;
+}
+
+int
+xfs_link_common(struct vnode *dvp,
+ struct vnode *vp,
+ const char *name,
+ struct ucred *cred)
+{
+ struct xfs *xfsp = XFS_FROM_VNODE(dvp);
+ struct xfs_node *xn = VNODE_TO_XNODE(dvp);
+ struct xfs_node *xn2 = VNODE_TO_XNODE(vp);
+ struct xfs_message_link msg;
+ int error = 0;
+
+ XFSDEB(XDEBVNOPS, ("xfs_link: %s\n", name));
+
+ msg.header.opcode = XFS_MSG_LINK;
+ msg.parent_handle = xn->handle;
+ msg.from_handle = xn2->handle;
+ strncpy(msg.name, name, 256);
+ msg.cred.uid = cred->cr_uid;
+ msg.cred.pag = xfs_get_pag(cred);
+
+ error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+ if (error == 0)
+ error = ((struct xfs_message_wakeup *) & msg)->error;
+
+ return error;
+}
+
+int
+xfs_symlink_common(struct vnode *dvp,
+ struct vnode **vpp,
+ const char *name,
+ struct proc *proc,
+ struct ucred *cred,
+ struct vattr *vap,
+ char *target)
+{
+ struct xfs *xfsp = XFS_FROM_VNODE(dvp);
+ struct xfs_node *xn = VNODE_TO_XNODE(dvp);
+ struct xfs_message_symlink msg;
+ int error = 0;
+
+ XFSDEB(XDEBVNOPS, ("xfs_symlink: %s\n", name));
+
+ msg.header.opcode = XFS_MSG_SYMLINK;
+ msg.parent_handle = xn->handle;
+ strncpy(msg.name, name, sizeof(msg.name));
+ msg.name[sizeof(msg.name) - 1] = '\0';
+ vattr2xfs_attr(vap, &msg.attr);
+ msg.cred.uid = cred->cr_uid;
+ msg.cred.pag = xfs_get_pag(cred);
+ strncpy (msg.contents, target, sizeof(msg.contents));
+ msg.contents[sizeof(msg.contents) - 1] = '\0';
+
+ error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+ if (error == 0)
+ error = ((struct xfs_message_wakeup *) & msg)->error;
+
+ if (error == 0) {
+ error = xfs_lookup_name(dvp, name, proc, cred, vpp);
+ if (error == 0)
+ vput (*vpp);
+ }
+
+#if !defined(__FreeBSD__) || __FreeBSD_version < 300000
+ vput(dvp);
+#endif
+
+ return error;
+}
+
+int
+xfs_readlink_common(struct vnode *vp, struct uio *uiop, struct ucred *cred)
+{
+ int error = 0;
+
+ XFSDEB(XDEBVNOPS, ("xfs_readlink\n"));
+
+ error = xfs_data_valid(vp, cred, XFS_DATA_R);
+ if (error == 0) {
+ struct vnode *t = DATA_FROM_VNODE(vp);
+
+ xfs_vfs_readlock(t, xfs_uio_to_proc(uiop));
+#ifdef __osf__
+ VOP_READ(t, uiop, 0, cred, error);
+#else
+ error = VOP_READ(t, uiop, 0, cred);
+#endif
+ xfs_vfs_unlock(t, xfs_uio_to_proc(uiop));
+ }
+ return error;
+}
+
+int
+xfs_inactive_common(struct vnode *vp, struct proc *p)
+{
+ struct xfs_message_inactivenode msg;
+ struct xfs *xfsp = XFS_FROM_VNODE(vp);
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+
+ XFSDEB(XDEBVNOPS, ("xfs_inactive, %p\n", vp));
+
+ /*
+ * This seems rather bogus, but sometimes we get an already
+ * cleaned node to be made inactive. Just ignoring it seems safe.
+ */
+
+ if (xn == NULL) {
+ XFSDEB(XDEBVNOPS, ("xfs_inactive: clean node\n"));
+ return 0;
+ }
+
+ xn->tokens = 0;
+ msg.header.opcode = XFS_MSG_INACTIVENODE;
+ msg.handle = xn->handle;
+ msg.flag = XFS_NOREFS;
+ xfs_message_send(xfsp->fd, &msg.header, sizeof(msg));
+
+#ifndef __osf__
+ xfs_vfs_unlock(vp, p);
+#else
+ /* XXX ? */
+#endif
+
+ XFSDEB(XDEBVNOPS, ("return: xfs_inactive\n"));
+
+ return 0;
+}
+
+int
+xfs_reclaim_common(struct vnode *vp)
+{
+ struct xfs_message_inactivenode msg;
+ struct xfs *xfsp = XFS_FROM_VNODE(vp);
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+
+ XFSDEB(XDEBVNOPS, ("xfs_reclaim: %p\n", vp));
+
+ msg.header.opcode = XFS_MSG_INACTIVENODE;
+ msg.handle = xn->handle;
+ msg.flag = XFS_NOREFS | XFS_DELETE;
+ xfs_message_send(xfsp->fd, &msg.header, sizeof(msg));
+
+ xfs_dnlc_purge(vp);
+ free_xfs_node(xn);
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+#if 0
+
+int
+xfs_advlock_common(struct vnode *dvp,
+ int locktype,
+ unsigned long lockid, /* XXX this good ? */
+ struct ucred *cred)
+{
+ struct xfs *xfsp = XFS_FROM_VNODE(dvp);
+ struct xfs_node *xn = VNODE_TO_XNODE(dvp);
+ int error = 0;
+
+ XFSDEB(XDEBVNOPS, ("xfs_advlock\n"));
+ {
+ struct xfs_message_advlock msg;
+
+ msg.header.opcode = XFS_MSG_ADVLOCK;
+ msg.handle = xn->handle;
+ msg.locktype = locktype;
+ msg.lockid = lockid;
+
+ if (cred != NOCRED) {
+ msg.cred.uid = cred->cr_uid;
+ msg.cred.pag = xfs_get_pag(cred);
+ } else {
+ msg.cred.uid = 0;
+ msg.cred.pag = XFS_ANONYMOUSID;
+ }
+ error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+ if (error == 0)
+ error = ((struct xfs_message_wakeup *) & msg)->error;
+ }
+
+ if (error == 0) {
+
+ /* sleep until woken */
+
+ } else {
+
+ /* die */
+ }
+
+ return error;
+}
+
+#endif
+
+/*
+ *
+ */
+
+void
+xfs_printnode_common (struct vnode *vp)
+{
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+
+ printf ("xnode: fid: %d.%d.%d.%d\n",
+ xn->handle.a, xn->handle.b, xn->handle.c, xn->handle.d);
+ printf ("\tattr: %svalid\n",
+ XFS_TOKEN_GOT(xn, XFS_ATTR_VALID) ? "": "in");
+ printf ("\tdata: %svalid\n",
+ XFS_TOKEN_GOT(xn, XFS_DATA_VALID) ? "": "in");
+ printf ("\tflags: 0x%x\n", xn->flags);
+}
diff --git a/sys/xfs/xfs_vnodeops.h b/sys/xfs/xfs_vnodeops.h
new file mode 100644
index 00000000000..c608f6669b1
--- /dev/null
+++ b/sys/xfs/xfs_vnodeops.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/* $Id: xfs_vnodeops.h,v 1.1 1999/04/30 01:59:02 art Exp $ */
+
+#ifndef _xfs_vnodeops_h
+#define _xfs_vnodeops_h
+
+/*
+ * xfs_vfs_readlock
+ * xfs_vfs_writelock
+ * xfs_vfs_unlock
+ */
+
+#ifdef __osf__ /* XXX - what about VN_LOCK? */
+
+#define xfs_vfs_readlock(vp, proc) VREF((vp))
+#define xfs_vfs_writelock(vp, proc) VREF((vp))
+#define xfs_vfs_unlock(vp, proc) vrele((vp))
+
+#elif defined(HAVE_TWO_ARGUMENT_VOP_LOCK)
+
+#define xfs_vfs_readlock(vp, proc) vn_lock((vp), LK_SHARED | LK_RETRY)
+#define xfs_vfs_writelock(vp, proc) vn_lock((vp), LK_EXCLUSIVE | LK_RETRY)
+#define xfs_vfs_unlock(vp, proc) VOP_UNLOCK((vp), 0)
+
+#elif defined(HAVE_THREE_ARGUMENT_VOP_LOCK)
+
+#define xfs_vfs_readlock(vp, proc) vn_lock((vp), LK_SHARED | LK_RETRY, (proc))
+#define xfs_vfs_writelock(vp, proc) vn_lock((vp), LK_EXCLUSIVE | LK_RETRY, (proc))
+#define xfs_vfs_unlock(vp, proc) VOP_UNLOCK((vp), 0, (proc))
+
+#else
+
+#define xfs_vfs_readlock(vp, proc) VOP_LOCK((vp))
+#define xfs_vfs_writelock(vp, proc) VOP_LOCK((vp))
+#define xfs_vfs_unlock(vp, proc) VOP_UNLOCK((vp))
+
+#endif
+
+int
+xfs_open_valid(struct vnode * vp, struct ucred * cred, u_int tok);
+
+int
+xfs_attr_valid(struct vnode * vp, struct ucred * cred, u_int tok);
+
+int
+xfs_fetch_rights(struct vnode * vp, struct ucred * cred);
+
+int
+xfs_data_valid(struct vnode * vp, struct ucred * cred, u_int tok);
+
+int
+xfs_fsync_common(struct vnode *vp, struct ucred *cred,
+ int waitfor, struct proc *proc);
+
+int
+xfs_close_common(struct vnode *vp, int fflag,
+ struct proc *proc, struct ucred *cred);
+
+int
+xfs_read_common(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred);
+
+int
+xfs_write_common(struct vnode *vp, struct uio *uiop, int ioflag, struct ucred *cred);
+
+int
+xfs_getattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred);
+
+int
+xfs_setattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred);
+
+int
+xfs_access_common(struct vnode *vp, int mode, struct ucred *cred);
+
+int
+xfs_lookup_common(struct vnode *dvp,
+ xfs_componentname *cnp,
+ struct vnode **vpp);
+
+int
+xfs_lookup_name(struct vnode *dvp,
+ const char *name,
+ struct proc *proc,
+ struct ucred *cred,
+ struct vnode **vpp);
+
+int
+xfs_create_common(struct vnode *dvp,
+ const char *name,
+ struct vattr *vap,
+ struct ucred *cred);
+
+int
+xfs_remove_common(struct vnode *dvp,
+ struct vnode *vp,
+ const char *name,
+ struct ucred *cred);
+
+int
+xfs_rename_common(struct vnode *fdvp,
+ struct vnode *fvp,
+ const char *fname,
+ struct vnode *tdvp,
+ struct vnode *tvp,
+ const char *tname,
+ struct ucred *cred);
+
+int
+xfs_mkdir_common(struct vnode *dvp,
+ const char *name,
+ struct vattr *vap,
+ struct ucred *cred);
+
+int
+xfs_rmdir_common(struct vnode *dvp,
+ struct vnode *vp,
+ const char *name,
+ struct ucred *cred);
+
+int
+xfs_readdir_common(struct vnode *vp,
+ struct uio *uiop,
+ struct ucred *cred,
+ int *eofflag);
+
+int
+xfs_link_common(struct vnode *dvp,
+ struct vnode *vp,
+ const char *name,
+ struct ucred *cred);
+
+int
+xfs_symlink_common(struct vnode *dvp,
+ struct vnode **vpp,
+ const char *name,
+ struct proc *proc,
+ struct ucred *cred,
+ struct vattr *vap,
+ char *target);
+
+int
+xfs_readlink_common(struct vnode *vp, struct uio *uiop, struct ucred *cred);
+
+int
+xfs_inactive_common(struct vnode *vp, struct proc *p);
+
+int
+xfs_reclaim_common(struct vnode *vp);
+
+int
+xfs_eopnotsupp (void *);
+
+int
+xfs_returnzero (void *v);
+
+void
+xfs_printnode_common (struct vnode *vp);
+
+#endif /* _xfs_vnodeops_h */
diff --git a/sys/xfs/xfs_vopdefs.h b/sys/xfs/xfs_vopdefs.h
new file mode 100644
index 00000000000..f0c3d2706ec
--- /dev/null
+++ b/sys/xfs/xfs_vopdefs.h
@@ -0,0 +1,43 @@
+#define HAVE_VOP_ISLOCKED 1
+#define HAVE_VOP_LOOKUP 1
+#define HAVE_VOP_CREATE 1
+#define HAVE_VOP_MKNOD 1
+#define HAVE_VOP_OPEN 1
+#define HAVE_VOP_CLOSE 1
+#define HAVE_VOP_ACCESS 1
+#define HAVE_VOP_GETATTR 1
+#define HAVE_VOP_SETATTR 1
+#define HAVE_VOP_READ 1
+#define HAVE_VOP_WRITE 1
+#define HAVE_VOP_LEASE 1
+#define HAVE_VOP_IOCTL 1
+#define HAVE_VOP_SELECT 1
+#define HAVE_VOP_REVOKE 1
+#define HAVE_VOP_MMAP 1
+#define HAVE_VOP_FSYNC 1
+#define HAVE_VOP_SEEK 1
+#define HAVE_VOP_REMOVE 1
+#define HAVE_VOP_LINK 1
+#define HAVE_VOP_RENAME 1
+#define HAVE_VOP_MKDIR 1
+#define HAVE_VOP_RMDIR 1
+#define HAVE_VOP_SYMLINK 1
+#define HAVE_VOP_READDIR 1
+#define HAVE_VOP_READLINK 1
+#define HAVE_VOP_ABORTOP 1
+#define HAVE_VOP_INACTIVE 1
+#define HAVE_VOP_RECLAIM 1
+#define HAVE_VOP_LOCK 1
+#define HAVE_VOP_UNLOCK 1
+#define HAVE_VOP_BMAP 1
+#define HAVE_VOP_PRINT 1
+#define HAVE_VOP_PATHCONF 1
+#define HAVE_VOP_ADVLOCK 1
+#define HAVE_VOP_BLKATOFF 1
+#define HAVE_VOP_VALLOC 1
+#define HAVE_VOP_BALLOC 1
+#define HAVE_VOP_REALLOCBLKS 1
+#define HAVE_VOP_VFREE 1
+#define HAVE_VOP_TRUNCATE 1
+#define HAVE_VOP_UPDATE 1
+#define HAVE_VOP_WHITEOUT 1