diff options
author | 1999-04-30 01:58:59 +0000 | |
---|---|---|
committer | 1999-04-30 01:58:59 +0000 | |
commit | e09bdadb1962e70cc6e11d77adfe7d6a2dbb2c7e (patch) | |
tree | bd2fe53f0944ae30b5bb7ce3422bedb4455e3f7d /sys | |
parent | more cruft (diff) | |
download | wireguard-openbsd-e09bdadb1962e70cc6e11d77adfe7d6a2dbb2c7e.tar.xz wireguard-openbsd-e09bdadb1962e70cc6e11d77adfe7d6a2dbb2c7e.zip |
upgrade Arla to fresher code. Too many new features and bugfixes.
Diffstat (limited to 'sys')
33 files changed, 7030 insertions, 460 deletions
diff --git a/sys/conf/files b/sys/conf/files index e8c75ceeee8..23cbc85d874 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $OpenBSD: files,v 1.115 1999/04/20 20:06:10 niklas Exp $ +# $OpenBSD: files,v 1.116 1999/04/30 01:58:59 art Exp $ # $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -570,14 +570,19 @@ file ufs/ext2fs/ext2fs_readwrite.c ext2fs file ufs/ext2fs/ext2fs_subr.c ext2fs file ufs/ext2fs/ext2fs_vfsops.c ext2fs file ufs/ext2fs/ext2fs_vnops.c ext2fs -file xfs/xfs_common.c xfs +file xfs/xfs_common-bsd.c xfs file xfs/xfs_deb.c xfs -file xfs/xfs_dev.c xfs +file xfs/xfs_dev-bsd.c xfs +file xfs/xfs_dev-common.c xfs file xfs/xfs_message.c xfs -file xfs/xfs_node.c xfs -file xfs/xfs_syscalls.c -file xfs/xfs_vfsops.c xfs -file xfs/xfs_vnodeops.c xfs +file xfs/xfs_node-bsd.c xfs +file xfs/xfs_syscalls-common.c xfs +file xfs/xfs_vfsops-bsd.c xfs +file xfs/xfs_vfsops-common.c xfs +file xfs/xfs_vfsops-openbsd.c xfs +file xfs/xfs_vnodeops-bsd.c xfs +file xfs/xfs_vnodeops-common.c xfs +file xfs/xfs_syscalls-dummy.c !xfs file vm/device_pager.c !uvm & devpager file vm/swap_pager.c !uvm & swappager file vm/vm_fault.c !uvm 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 |