summaryrefslogtreecommitdiffstats
path: root/sys/fs/devfs/devfs_vfsops.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2000-08-20 21:34:39 +0000
committerphk <phk@FreeBSD.org>2000-08-20 21:34:39 +0000
commitb648921accec69a7e5c83e915ded3037cbca7f3d (patch)
treefa2e43c05e3c1d31732408f806d72db091c03d14 /sys/fs/devfs/devfs_vfsops.c
parent1c624ac57c791b6df4b51eb86e04dc404052c700 (diff)
downloadFreeBSD-src-b648921accec69a7e5c83e915ded3037cbca7f3d.zip
FreeBSD-src-b648921accec69a7e5c83e915ded3037cbca7f3d.tar.gz
Remove all traces of Julians DEVFS (incl from kern/subr_diskslice.c)
Remove old DEVFS support fields from dev_t. Make uid, gid & mode members of dev_t and set them in make_dev(). Use correct uid, gid & mode in make_dev in disk minilayer. Add support for registering alias names for a dev_t using the new function make_dev_alias(). These will show up as symlinks in DEVFS. Use makedev() rather than make_dev() for MFSs magic devices to prevent DEVFS from noticing this abuse. Add a field for DEVFS inode number in dev_t. Add new DEVFS in fs/devfs. Add devfs cloning to: disk minilayer (ie: ad(4), sd(4), cd(4) etc etc) md(4), tun(4), bpf(4), fd(4) If DEVFS add -d flag to /sbin/inits args to make it mount devfs. Add commented out DEVFS to GENERIC
Diffstat (limited to 'sys/fs/devfs/devfs_vfsops.c')
-rw-r--r--sys/fs/devfs/devfs_vfsops.c243
1 files changed, 243 insertions, 0 deletions
diff --git a/sys/fs/devfs/devfs_vfsops.c b/sys/fs/devfs/devfs_vfsops.c
new file mode 100644
index 0000000..2cd7611
--- /dev/null
+++ b/sys/fs/devfs/devfs_vfsops.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 1992, 1993, 1995
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 2000
+ * Poul-Henning Kamp. All rights reserved.
+ *
+ * This code is derived from software donated to Berkeley by
+ * Jan-Simon Pendry.
+ *
+ * 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. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)kernfs_vfsops.c 8.10 (Berkeley) 5/14/95
+ * From: FreeBSD: src/sys/miscfs/kernfs/kernfs_vfsops.c 1.36
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/dirent.h>
+#include <sys/conf.h>
+#include <sys/proc.h>
+#include <sys/vnode.h>
+#include <sys/mount.h>
+#include <sys/malloc.h>
+#include <sys/eventhandler.h>
+
+#define DEVFS_INTERN
+#include <fs/devfs/devfs.h>
+
+MALLOC_DEFINE(M_DEVFS, "DEVFS", "DEVFS data");
+
+static int devfs_mount __P((struct mount *mp, char *path, caddr_t data,
+ struct nameidata *ndp, struct proc *p));
+static int devfs_unmount __P((struct mount *mp, int mntflags,
+ struct proc *p));
+static int devfs_root __P((struct mount *mp, struct vnode **vpp));
+static int devfs_statfs __P((struct mount *mp, struct statfs *sbp,
+ struct proc *p));
+
+/*
+ * Mount the filesystem
+ */
+static int
+devfs_mount(mp, path, data, ndp, p)
+ struct mount *mp;
+ char *path;
+ caddr_t data;
+ struct nameidata *ndp;
+ struct proc *p;
+{
+ int error = 0;
+ u_int size;
+ struct devfs_mount *fmp;
+ struct vnode *rvp;
+
+ /*
+ * Update is a no-op
+ */
+ if (mp->mnt_flag & MNT_UPDATE)
+ return (EOPNOTSUPP);
+
+ MALLOC(fmp, struct devfs_mount *, sizeof(struct devfs_mount), M_DEVFS, M_WAITOK);
+
+ bzero(fmp, sizeof(*fmp));
+
+ error = getnewvnode(VT_DEVFS, mp, devfs_vnodeop_p, &rvp);
+ if (error) {
+ FREE(fmp, M_DEVFS);
+ return (error);
+ }
+
+ vhold(rvp);
+ rvp->v_type = VDIR;
+ rvp->v_flag |= VROOT;
+ mp->mnt_flag |= MNT_LOCAL;
+ mp->mnt_data = (qaddr_t) fmp;
+ vfs_getnewfsid(mp);
+
+ fmp->dm_inode = NDEVINO;
+ fmp->dm_root = rvp;
+ fmp->dm_rootdir = devfs_vmkdir();
+ rvp->v_data = fmp->dm_rootdir;
+ TAILQ_FIRST(&fmp->dm_rootdir->dd_list)->de_vnode = rvp;
+ TAILQ_FIRST(&fmp->dm_rootdir->dd_list)->de_inode = 2;
+
+#ifdef DEVFS_DEVBASE
+ {
+ struct devfs_dirent *de;
+
+ fmp->dm_basedir = devfs_vmkdir();
+ de = devfs_newdirent("dev", 3);
+ de->de_inode = fmp->dm_inode++;
+ de->de_dir = fmp->dm_basedir;
+ TAILQ_FIRST(&de->de_dir->dd_list)->de_inode = de->de_inode;
+ de->de_uid = 0;
+ de->de_gid = 0;
+ de->de_mode = 0755;
+ de->de_dirent->d_type = DT_DIR;
+ TAILQ_INSERT_TAIL(&fmp->dm_rootdir->dd_list, de, de_list);
+ }
+#else
+ fmp->dm_basedir = fmp->dm_rootdir;
+#endif
+
+ if (path != NULL) {
+ (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
+ } else {
+ strcpy(mp->mnt_stat.f_mntonname, "/");
+ size = 1;
+ }
+ bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
+ bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
+ bcopy("devfs", mp->mnt_stat.f_mntfromname, sizeof("devfs"));
+ (void)devfs_statfs(mp, &mp->mnt_stat, p);
+ devfs_populate(fmp);
+
+ return (0);
+}
+
+static int
+devfs_unmount(mp, mntflags, p)
+ struct mount *mp;
+ int mntflags;
+ struct proc *p;
+{
+ int error;
+ int flags = 0;
+ struct vnode *rootvp = VFSTODEVFS(mp)->dm_root;
+ struct devfs_mount *fmp;
+
+ fmp = (struct devfs_mount*) mp->mnt_data;
+ if (mntflags & MNT_FORCE)
+ flags |= FORCECLOSE;
+
+ /*
+ * Clear out buffer cache. I don't think we
+ * ever get anything cached at this level at the
+ * moment, but who knows...
+ */
+ if (rootvp->v_usecount > 2)
+ return (EBUSY);
+ devfs_purge(fmp->dm_rootdir);
+ error = vflush(mp, rootvp, flags);
+ if (error)
+ return (error);
+
+ /*
+ * Release reference on underlying root vnode
+ */
+ vrele(rootvp);
+ /*
+ * And blow it away for future re-use
+ */
+ vgone(rootvp);
+ /*
+ * Finally, throw away the devfs_mount structure
+ */
+ free(mp->mnt_data, M_DEVFS);
+ mp->mnt_data = 0;
+ return 0;
+}
+
+static int
+devfs_root(mp, vpp)
+ struct mount *mp;
+ struct vnode **vpp;
+{
+ struct proc *p = curproc; /* XXX */
+ struct vnode *vp;
+
+ /*
+ * Return locked reference to root.
+ */
+ vp = VFSTODEVFS(mp)->dm_root;
+ VREF(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+ *vpp = vp;
+ return (0);
+}
+
+static int
+devfs_statfs(mp, sbp, p)
+ struct mount *mp;
+ struct statfs *sbp;
+ struct proc *p;
+{
+
+ sbp->f_flags = 0;
+ sbp->f_bsize = DEV_BSIZE;
+ sbp->f_iosize = DEV_BSIZE;
+ sbp->f_blocks = 2; /* 1K to keep df happy */
+ sbp->f_bfree = 0;
+ sbp->f_bavail = 0;
+ sbp->f_files = 0;
+ sbp->f_ffree = 0;
+ if (sbp != &mp->mnt_stat) {
+ sbp->f_type = mp->mnt_vfc->vfc_typenum;
+ bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
+ bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
+ bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
+ }
+ return (0);
+}
+
+static struct vfsops devfs_vfsops = {
+ devfs_mount,
+ vfs_stdstart,
+ devfs_unmount,
+ devfs_root,
+ vfs_stdquotactl,
+ devfs_statfs,
+ vfs_stdsync,
+ vfs_stdvget,
+ vfs_stdfhtovp,
+ vfs_stdcheckexp,
+ vfs_stdvptofh,
+ vfs_stdinit,
+ vfs_stduninit,
+ vfs_stdextattrctl,
+};
+
+VFS_SET(devfs_vfsops, devfs, VFCF_SYNTHETIC);
OpenPOWER on IntegriCloud