155344Spendry /* 263233Sbostic * Copyright (c) 1992, 1993 363233Sbostic * The Regents of the University of California. All rights reserved. 455344Spendry * All rights reserved. 555344Spendry * 655344Spendry * This code is derived from software donated to Berkeley by 755344Spendry * Jan-Simon Pendry. 855344Spendry * 955344Spendry * %sccs.include.redist.c% 1055344Spendry * 11*65380Spendry * @(#)kernfs_vfsops.c 8.2 (Berkeley) 01/04/94 1255344Spendry */ 1355344Spendry 1455344Spendry /* 1555344Spendry * Kernel params Filesystem 1655344Spendry */ 1755344Spendry 1855344Spendry #include <sys/param.h> 1955344Spendry #include <sys/systm.h> 2055356Spendry #include <sys/conf.h> 2155344Spendry #include <sys/types.h> 2255344Spendry #include <sys/proc.h> 2355344Spendry #include <sys/vnode.h> 2455344Spendry #include <sys/mount.h> 2555344Spendry #include <sys/namei.h> 2655344Spendry #include <sys/malloc.h> 2755356Spendry 2855356Spendry #include <miscfs/specfs/specdev.h> 2955344Spendry #include <miscfs/kernfs/kernfs.h> 3055344Spendry 3155356Spendry struct vnode *rrootvp; 3255356Spendry 3355356Spendry /* 3455356Spendry * Create a vnode for a character device. 3555356Spendry */ 3655356Spendry int 3755356Spendry cdevvp(dev, vpp) 3855356Spendry dev_t dev; 3955356Spendry struct vnode **vpp; 4055356Spendry { 4155356Spendry register struct vnode *vp; 4255356Spendry struct vnode *nvp; 4355356Spendry int error; 4455356Spendry 4555356Spendry if (dev == NODEV) 4655356Spendry return (0); 4755356Spendry error = getnewvnode(VT_NON, (struct mount *)0, spec_vnodeop_p, &nvp); 4855356Spendry if (error) { 4955356Spendry *vpp = 0; 5055356Spendry return (error); 5155356Spendry } 5255356Spendry vp = nvp; 5355356Spendry vp->v_type = VCHR; 5455356Spendry if (nvp = checkalias(vp, dev, (struct mount *)0)) { 5555356Spendry vput(vp); 5655356Spendry vp = nvp; 5755356Spendry } 5855356Spendry *vpp = vp; 5955356Spendry return (0); 6055356Spendry } 6155356Spendry 6255344Spendry kernfs_init() 6355344Spendry { 6455356Spendry int cmaj; 6555356Spendry int bmaj = major(rootdev); 6655821Spendry int error = ENXIO; 6755356Spendry 6855344Spendry #ifdef KERNFS_DIAGNOSTIC 6955344Spendry printf("kernfs_init\n"); /* printed during system boot */ 7055344Spendry #endif 7155356Spendry 7255356Spendry for (cmaj = 0; cmaj < nchrdev; cmaj++) { 7355356Spendry if (cdevsw[cmaj].d_open == bdevsw[bmaj].d_open) { 7455356Spendry dev_t cdev = makedev(cmaj, minor(rootdev)); 7555356Spendry error = cdevvp(cdev, &rrootvp); 7655356Spendry if (error == 0) 7755356Spendry break; 7855356Spendry } 7955356Spendry } 8055356Spendry 8155356Spendry if (error) { 8255356Spendry printf("kernfs: no raw boot device\n"); 8355356Spendry rrootvp = 0; 8455356Spendry } 8555344Spendry } 8655344Spendry 8755344Spendry /* 8855344Spendry * Mount the Kernel params filesystem 8955344Spendry */ 9055344Spendry kernfs_mount(mp, path, data, ndp, p) 9155344Spendry struct mount *mp; 9255344Spendry char *path; 9355344Spendry caddr_t data; 9455344Spendry struct nameidata *ndp; 9555344Spendry struct proc *p; 9655344Spendry { 9755344Spendry int error = 0; 9855344Spendry u_int size; 9955344Spendry struct kernfs_mount *fmp; 10055344Spendry struct vnode *rvp; 10155344Spendry 10255344Spendry #ifdef KERNFS_DIAGNOSTIC 10355344Spendry printf("kernfs_mount(mp = %x)\n", mp); 10455344Spendry #endif 10555344Spendry 10655344Spendry /* 10755344Spendry * Update is a no-op 10855344Spendry */ 10955344Spendry if (mp->mnt_flag & MNT_UPDATE) 11055344Spendry return (EOPNOTSUPP); 11155344Spendry 112*65380Spendry error = getnewvnode(VT_KERNFS, mp, kernfs_vnodeop_p, &rvp); /* XXX */ 11355344Spendry if (error) 11455344Spendry return (error); 11555344Spendry 11655344Spendry MALLOC(fmp, struct kernfs_mount *, sizeof(struct kernfs_mount), 11755344Spendry M_UFSMNT, M_WAITOK); /* XXX */ 11855344Spendry rvp->v_type = VDIR; 11955344Spendry rvp->v_flag |= VROOT; 12055344Spendry #ifdef KERNFS_DIAGNOSTIC 12155344Spendry printf("kernfs_mount: root vp = %x\n", rvp); 12255344Spendry #endif 12355344Spendry fmp->kf_root = rvp; 12455344Spendry mp->mnt_flag |= MNT_LOCAL; 12555344Spendry mp->mnt_data = (qaddr_t) fmp; 12655344Spendry getnewfsid(mp, MOUNT_KERNFS); 12755344Spendry 12855344Spendry (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 12955344Spendry bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 13055344Spendry bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 13155344Spendry bcopy("kernfs", mp->mnt_stat.f_mntfromname, sizeof("kernfs")); 13255344Spendry #ifdef KERNFS_DIAGNOSTIC 13355344Spendry printf("kernfs_mount: at %s\n", mp->mnt_stat.f_mntonname); 13455344Spendry #endif 13555344Spendry return (0); 13655344Spendry } 13755344Spendry 13855344Spendry kernfs_start(mp, flags, p) 13955344Spendry struct mount *mp; 14055344Spendry int flags; 14155344Spendry struct proc *p; 14255344Spendry { 14355344Spendry return (0); 14455344Spendry } 14555344Spendry 14655344Spendry kernfs_unmount(mp, mntflags, p) 14755344Spendry struct mount *mp; 14855344Spendry int mntflags; 14955344Spendry struct proc *p; 15055344Spendry { 15155344Spendry int error; 15255344Spendry int flags = 0; 15355344Spendry extern int doforce; 15455344Spendry struct vnode *rootvp = VFSTOKERNFS(mp)->kf_root; 15555344Spendry 15655344Spendry #ifdef KERNFS_DIAGNOSTIC 15755344Spendry printf("kernfs_unmount(mp = %x)\n", mp); 15855344Spendry #endif 15955344Spendry 16055344Spendry if (mntflags & MNT_FORCE) { 16155344Spendry /* kernfs can never be rootfs so don't check for it */ 16255344Spendry if (!doforce) 16355344Spendry return (EINVAL); 16455344Spendry flags |= FORCECLOSE; 16555344Spendry } 16655344Spendry 16755344Spendry /* 16855344Spendry * Clear out buffer cache. I don't think we 16955344Spendry * ever get anything cached at this level at the 17055344Spendry * moment, but who knows... 17155344Spendry */ 17255344Spendry if (rootvp->v_usecount > 1) 17355344Spendry return (EBUSY); 17455344Spendry #ifdef KERNFS_DIAGNOSTIC 17555344Spendry printf("kernfs_unmount: calling vflush\n"); 17655344Spendry #endif 17755344Spendry if (error = vflush(mp, rootvp, flags)) 17855344Spendry return (error); 17955344Spendry 18055344Spendry #ifdef KERNFS_DIAGNOSTIC 18155344Spendry vprint("kernfs root", rootvp); 18255351Spendry #endif 18355344Spendry /* 18455344Spendry * Release reference on underlying root vnode 18555344Spendry */ 18655344Spendry vrele(rootvp); 18755344Spendry /* 18855344Spendry * And blow it away for future re-use 18955344Spendry */ 19055344Spendry vgone(rootvp); 19155344Spendry /* 19255344Spendry * Finally, throw away the kernfs_mount structure 19355344Spendry */ 19455344Spendry free(mp->mnt_data, M_UFSMNT); /* XXX */ 19555344Spendry mp->mnt_data = 0; 19655344Spendry return 0; 19755344Spendry } 19855344Spendry 19955344Spendry kernfs_root(mp, vpp) 20055344Spendry struct mount *mp; 20155344Spendry struct vnode **vpp; 20255344Spendry { 20355344Spendry struct vnode *vp; 20455344Spendry int error; 20555344Spendry 20655344Spendry #ifdef KERNFS_DIAGNOSTIC 20755344Spendry printf("kernfs_root(mp = %x)\n", mp); 20855344Spendry #endif 20955344Spendry 21055344Spendry /* 21155344Spendry * Return locked reference to root. 21255344Spendry */ 21355344Spendry vp = VFSTOKERNFS(mp)->kf_root; 21455344Spendry VREF(vp); 21555344Spendry VOP_LOCK(vp); 21655344Spendry *vpp = vp; 21755344Spendry return (0); 21855344Spendry } 21955344Spendry 22055344Spendry kernfs_quotactl(mp, cmd, uid, arg, p) 22155344Spendry struct mount *mp; 22255344Spendry int cmd; 22355344Spendry uid_t uid; 22455344Spendry caddr_t arg; 22555344Spendry struct proc *p; 22655344Spendry { 22755344Spendry return (EOPNOTSUPP); 22855344Spendry } 22955344Spendry 23055344Spendry kernfs_statfs(mp, sbp, p) 23155344Spendry struct mount *mp; 23255344Spendry struct statfs *sbp; 23355344Spendry struct proc *p; 23455344Spendry { 23555344Spendry #ifdef KERNFS_DIAGNOSTIC 23655344Spendry printf("kernfs_statfs(mp = %x)\n", mp); 23755344Spendry #endif 23855344Spendry 23955344Spendry sbp->f_type = MOUNT_KERNFS; 24055344Spendry sbp->f_flags = 0; 24155344Spendry sbp->f_bsize = DEV_BSIZE; 24255344Spendry sbp->f_iosize = DEV_BSIZE; 24355344Spendry sbp->f_blocks = 2; /* 1K to keep df happy */ 24455344Spendry sbp->f_bfree = 0; 24555344Spendry sbp->f_bavail = 0; 24655821Spendry sbp->f_files = 0; 24755821Spendry sbp->f_ffree = 0; 24855344Spendry if (sbp != &mp->mnt_stat) { 24955344Spendry bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 25055344Spendry bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 25155344Spendry bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 25255344Spendry } 25355344Spendry return (0); 25455344Spendry } 25555344Spendry 25655344Spendry kernfs_sync(mp, waitfor) 25755344Spendry struct mount *mp; 25855344Spendry int waitfor; 25955344Spendry { 26055344Spendry return (0); 26155344Spendry } 26255344Spendry 26355344Spendry /* 26455351Spendry * Kernfs flat namespace lookup. 26555344Spendry * Currently unsupported. 26655344Spendry */ 26755344Spendry kernfs_vget(mp, ino, vpp) 26855344Spendry struct mount *mp; 26955344Spendry ino_t ino; 27055344Spendry struct vnode **vpp; 27155344Spendry { 27255344Spendry 27355344Spendry return (EOPNOTSUPP); 27455344Spendry } 27555344Spendry 27655344Spendry 27755344Spendry kernfs_fhtovp(mp, fhp, setgen, vpp) 27855344Spendry struct mount *mp; 27955344Spendry struct fid *fhp; 28055344Spendry int setgen; 28155344Spendry struct vnode **vpp; 28255344Spendry { 28355344Spendry return (EOPNOTSUPP); 28455344Spendry } 28555344Spendry 28655344Spendry kernfs_vptofh(vp, fhp) 28755344Spendry struct vnode *vp; 28855344Spendry struct fid *fhp; 28955344Spendry { 29055344Spendry return (EOPNOTSUPP); 29155344Spendry } 29255344Spendry 29355344Spendry struct vfsops kernfs_vfsops = { 29455344Spendry kernfs_mount, 29555344Spendry kernfs_start, 29655344Spendry kernfs_unmount, 29755344Spendry kernfs_root, 29855344Spendry kernfs_quotactl, 29955344Spendry kernfs_statfs, 30055344Spendry kernfs_sync, 30155344Spendry kernfs_vget, 30255344Spendry kernfs_fhtovp, 30355344Spendry kernfs_vptofh, 30455344Spendry kernfs_init, 30555344Spendry }; 306