summaryrefslogtreecommitdiff
path: root/sys/xfs/xfs_vfsops-common.c
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>1999-04-30 01:59:03 +0000
committerArtur Grabowski <art@cvs.openbsd.org>1999-04-30 01:59:03 +0000
commitb0d7a6a83d7eaa1e9a526c576527d81957b28268 (patch)
tree0baa2e9e6f6c86554b23b30e24ff2c2801debe48 /sys/xfs/xfs_vfsops-common.c
parent55728d80a6017f4e7da4b56865862c70d4d75897 (diff)
Import of xfs from arla-0.35.7
Diffstat (limited to 'sys/xfs/xfs_vfsops-common.c')
-rw-r--r--sys/xfs/xfs_vfsops-common.c269
1 files changed, 269 insertions, 0 deletions
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;
+}