155344Spendry /* 263233Sbostic * Copyright (c) 1992, 1993 363233Sbostic * The Regents of the University of California. All rights reserved. 455344Spendry * 555344Spendry * This code is derived from software donated to Berkeley by 655344Spendry * Jan-Simon Pendry. 755344Spendry * 855344Spendry * %sccs.include.redist.c% 955344Spendry * 10*67387Spendry * @(#)kernfs_vfsops.c 8.5 (Berkeley) 06/15/94 1155344Spendry */ 1255344Spendry 1355344Spendry /* 1455344Spendry * Kernel params Filesystem 1555344Spendry */ 1655344Spendry 1755344Spendry #include <sys/param.h> 1855344Spendry #include <sys/systm.h> 1955356Spendry #include <sys/conf.h> 2055344Spendry #include <sys/types.h> 2155344Spendry #include <sys/proc.h> 2255344Spendry #include <sys/vnode.h> 2355344Spendry #include <sys/mount.h> 2455344Spendry #include <sys/namei.h> 2555344Spendry #include <sys/malloc.h> 2655356Spendry 2755356Spendry #include <miscfs/specfs/specdev.h> 2855344Spendry #include <miscfs/kernfs/kernfs.h> 2955344Spendry 30*67387Spendry dev_t rrootdev = NODEV; 3155356Spendry 32*67387Spendry kernfs_init() 3355356Spendry { 3455356Spendry 3555356Spendry } 3655356Spendry 37*67387Spendry void 38*67387Spendry kernfs_get_rrootdev() 3955344Spendry { 40*67387Spendry static int tried = 0; 4155356Spendry int cmaj; 4255356Spendry 43*67387Spendry if (tried) { 44*67387Spendry /* Already did it once. */ 45*67387Spendry return; 46*67387Spendry } 47*67387Spendry tried = 1; 4855356Spendry 49*67387Spendry if (rootdev == NODEV) 50*67387Spendry return; 5155356Spendry for (cmaj = 0; cmaj < nchrdev; cmaj++) { 52*67387Spendry rrootdev = makedev(cmaj, minor(rootdev)); 53*67387Spendry if (chrtoblk(rrootdev) == rootdev) 54*67387Spendry return; 5555356Spendry } 56*67387Spendry rrootdev = NODEV; 57*67387Spendry printf("kernfs_get_rrootdev: no raw root device\n"); 5855344Spendry } 5955344Spendry 6055344Spendry /* 6155344Spendry * Mount the Kernel params filesystem 6255344Spendry */ 6355344Spendry kernfs_mount(mp, path, data, ndp, p) 6455344Spendry struct mount *mp; 6555344Spendry char *path; 6655344Spendry caddr_t data; 6755344Spendry struct nameidata *ndp; 6855344Spendry struct proc *p; 6955344Spendry { 7055344Spendry int error = 0; 7155344Spendry u_int size; 7255344Spendry struct kernfs_mount *fmp; 7355344Spendry struct vnode *rvp; 7455344Spendry 7555344Spendry #ifdef KERNFS_DIAGNOSTIC 7655344Spendry printf("kernfs_mount(mp = %x)\n", mp); 7755344Spendry #endif 7855344Spendry 7955344Spendry /* 8055344Spendry * Update is a no-op 8155344Spendry */ 8255344Spendry if (mp->mnt_flag & MNT_UPDATE) 8355344Spendry return (EOPNOTSUPP); 8455344Spendry 8565380Spendry error = getnewvnode(VT_KERNFS, mp, kernfs_vnodeop_p, &rvp); /* XXX */ 8655344Spendry if (error) 8755344Spendry return (error); 8855344Spendry 8955344Spendry MALLOC(fmp, struct kernfs_mount *, sizeof(struct kernfs_mount), 9055344Spendry M_UFSMNT, M_WAITOK); /* XXX */ 9155344Spendry rvp->v_type = VDIR; 9255344Spendry rvp->v_flag |= VROOT; 9355344Spendry #ifdef KERNFS_DIAGNOSTIC 9455344Spendry printf("kernfs_mount: root vp = %x\n", rvp); 9555344Spendry #endif 9655344Spendry fmp->kf_root = rvp; 9755344Spendry mp->mnt_flag |= MNT_LOCAL; 9855344Spendry mp->mnt_data = (qaddr_t) fmp; 9955344Spendry getnewfsid(mp, MOUNT_KERNFS); 10055344Spendry 10155344Spendry (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 10255344Spendry bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 10355344Spendry bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 10455344Spendry bcopy("kernfs", mp->mnt_stat.f_mntfromname, sizeof("kernfs")); 10555344Spendry #ifdef KERNFS_DIAGNOSTIC 10655344Spendry printf("kernfs_mount: at %s\n", mp->mnt_stat.f_mntonname); 10755344Spendry #endif 108*67387Spendry 109*67387Spendry kernfs_get_rrootdev(); 11055344Spendry return (0); 11155344Spendry } 11255344Spendry 11355344Spendry kernfs_start(mp, flags, p) 11455344Spendry struct mount *mp; 11555344Spendry int flags; 11655344Spendry struct proc *p; 11755344Spendry { 11855344Spendry return (0); 11955344Spendry } 12055344Spendry 12155344Spendry kernfs_unmount(mp, mntflags, p) 12255344Spendry struct mount *mp; 12355344Spendry int mntflags; 12455344Spendry struct proc *p; 12555344Spendry { 12655344Spendry int error; 12755344Spendry int flags = 0; 12855344Spendry extern int doforce; 12955344Spendry struct vnode *rootvp = VFSTOKERNFS(mp)->kf_root; 13055344Spendry 13155344Spendry #ifdef KERNFS_DIAGNOSTIC 13255344Spendry printf("kernfs_unmount(mp = %x)\n", mp); 13355344Spendry #endif 13455344Spendry 13555344Spendry if (mntflags & MNT_FORCE) { 13655344Spendry /* kernfs can never be rootfs so don't check for it */ 13755344Spendry if (!doforce) 13855344Spendry return (EINVAL); 13955344Spendry flags |= FORCECLOSE; 14055344Spendry } 14155344Spendry 14255344Spendry /* 14355344Spendry * Clear out buffer cache. I don't think we 14455344Spendry * ever get anything cached at this level at the 14555344Spendry * moment, but who knows... 14655344Spendry */ 14755344Spendry if (rootvp->v_usecount > 1) 14855344Spendry return (EBUSY); 14955344Spendry #ifdef KERNFS_DIAGNOSTIC 15055344Spendry printf("kernfs_unmount: calling vflush\n"); 15155344Spendry #endif 15255344Spendry if (error = vflush(mp, rootvp, flags)) 15355344Spendry return (error); 15455344Spendry 15555344Spendry #ifdef KERNFS_DIAGNOSTIC 15655344Spendry vprint("kernfs root", rootvp); 15755351Spendry #endif 15855344Spendry /* 15955344Spendry * Release reference on underlying root vnode 16055344Spendry */ 16155344Spendry vrele(rootvp); 16255344Spendry /* 16355344Spendry * And blow it away for future re-use 16455344Spendry */ 16555344Spendry vgone(rootvp); 16655344Spendry /* 16755344Spendry * Finally, throw away the kernfs_mount structure 16855344Spendry */ 16955344Spendry free(mp->mnt_data, M_UFSMNT); /* XXX */ 17055344Spendry mp->mnt_data = 0; 17155344Spendry return 0; 17255344Spendry } 17355344Spendry 17455344Spendry kernfs_root(mp, vpp) 17555344Spendry struct mount *mp; 17655344Spendry struct vnode **vpp; 17755344Spendry { 17855344Spendry struct vnode *vp; 17955344Spendry 18055344Spendry #ifdef KERNFS_DIAGNOSTIC 18155344Spendry printf("kernfs_root(mp = %x)\n", mp); 18255344Spendry #endif 18355344Spendry 18455344Spendry /* 18555344Spendry * Return locked reference to root. 18655344Spendry */ 18755344Spendry vp = VFSTOKERNFS(mp)->kf_root; 18855344Spendry VREF(vp); 18955344Spendry VOP_LOCK(vp); 19055344Spendry *vpp = vp; 19155344Spendry return (0); 19255344Spendry } 19355344Spendry 19455344Spendry kernfs_quotactl(mp, cmd, uid, arg, p) 19555344Spendry struct mount *mp; 19655344Spendry int cmd; 19755344Spendry uid_t uid; 19855344Spendry caddr_t arg; 19955344Spendry struct proc *p; 20055344Spendry { 20155344Spendry return (EOPNOTSUPP); 20255344Spendry } 20355344Spendry 20455344Spendry kernfs_statfs(mp, sbp, p) 20555344Spendry struct mount *mp; 20655344Spendry struct statfs *sbp; 20755344Spendry struct proc *p; 20855344Spendry { 20955344Spendry #ifdef KERNFS_DIAGNOSTIC 21055344Spendry printf("kernfs_statfs(mp = %x)\n", mp); 21155344Spendry #endif 21255344Spendry 21355344Spendry sbp->f_type = MOUNT_KERNFS; 21455344Spendry sbp->f_flags = 0; 21555344Spendry sbp->f_bsize = DEV_BSIZE; 21655344Spendry sbp->f_iosize = DEV_BSIZE; 21755344Spendry sbp->f_blocks = 2; /* 1K to keep df happy */ 21855344Spendry sbp->f_bfree = 0; 21955344Spendry sbp->f_bavail = 0; 22055821Spendry sbp->f_files = 0; 22155821Spendry sbp->f_ffree = 0; 22255344Spendry if (sbp != &mp->mnt_stat) { 22355344Spendry bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 22455344Spendry bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 22555344Spendry bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 22655344Spendry } 22755344Spendry return (0); 22855344Spendry } 22955344Spendry 23055344Spendry kernfs_sync(mp, waitfor) 23155344Spendry struct mount *mp; 23255344Spendry int waitfor; 23355344Spendry { 23455344Spendry return (0); 23555344Spendry } 23655344Spendry 23755344Spendry /* 23855351Spendry * Kernfs flat namespace lookup. 23955344Spendry * Currently unsupported. 24055344Spendry */ 24155344Spendry kernfs_vget(mp, ino, vpp) 24255344Spendry struct mount *mp; 24355344Spendry ino_t ino; 24455344Spendry struct vnode **vpp; 24555344Spendry { 24655344Spendry 24755344Spendry return (EOPNOTSUPP); 24855344Spendry } 24955344Spendry 25055344Spendry 25155344Spendry kernfs_fhtovp(mp, fhp, setgen, vpp) 25255344Spendry struct mount *mp; 25355344Spendry struct fid *fhp; 25455344Spendry int setgen; 25555344Spendry struct vnode **vpp; 25655344Spendry { 25755344Spendry return (EOPNOTSUPP); 25855344Spendry } 25955344Spendry 26055344Spendry kernfs_vptofh(vp, fhp) 26155344Spendry struct vnode *vp; 26255344Spendry struct fid *fhp; 26355344Spendry { 26455344Spendry return (EOPNOTSUPP); 26555344Spendry } 26655344Spendry 26755344Spendry struct vfsops kernfs_vfsops = { 26855344Spendry kernfs_mount, 26955344Spendry kernfs_start, 27055344Spendry kernfs_unmount, 27155344Spendry kernfs_root, 27255344Spendry kernfs_quotactl, 27355344Spendry kernfs_statfs, 27455344Spendry kernfs_sync, 27555344Spendry kernfs_vget, 27655344Spendry kernfs_fhtovp, 27755344Spendry kernfs_vptofh, 27855344Spendry kernfs_init, 27955344Spendry }; 280