155344Spendry /* 255344Spendry * Copyright (c) 1992 The Regents of the University of California 355344Spendry * Copyright (c) 1990, 1992 Jan-Simon Pendry 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*55351Spendry * @(#)kernfs_vfsops.c 7.2 (Berkeley) 07/18/92 1255344Spendry */ 1355344Spendry 1455344Spendry /* 1555344Spendry * Kernel params Filesystem 1655344Spendry */ 1755344Spendry 1855344Spendry #include <sys/param.h> 1955344Spendry #include <sys/systm.h> 2055344Spendry #include <sys/time.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> 2755344Spendry #include <miscfs/kernfs/kernfs.h> 2855344Spendry 2955344Spendry kernfs_init() 3055344Spendry { 3155344Spendry #ifdef KERNFS_DIAGNOSTIC 3255344Spendry printf("kernfs_init\n"); /* printed during system boot */ 3355344Spendry #endif 3455344Spendry } 3555344Spendry 3655344Spendry /* 3755344Spendry * Mount the Kernel params filesystem 3855344Spendry */ 3955344Spendry kernfs_mount(mp, path, data, ndp, p) 4055344Spendry struct mount *mp; 4155344Spendry char *path; 4255344Spendry caddr_t data; 4355344Spendry struct nameidata *ndp; 4455344Spendry struct proc *p; 4555344Spendry { 4655344Spendry int error = 0; 4755344Spendry u_int size; 4855344Spendry struct kernfs_mount *fmp; 4955344Spendry struct vnode *rvp; 5055344Spendry 5155344Spendry #ifdef KERNFS_DIAGNOSTIC 5255344Spendry printf("kernfs_mount(mp = %x)\n", mp); 5355344Spendry #endif 5455344Spendry 5555344Spendry /* 5655344Spendry * Update is a no-op 5755344Spendry */ 5855344Spendry if (mp->mnt_flag & MNT_UPDATE) 5955344Spendry return (EOPNOTSUPP); 6055344Spendry 6155344Spendry error = getnewvnode(VT_UFS, mp, kernfs_vnodeop_p, &rvp); /* XXX */ 6255344Spendry if (error) 6355344Spendry return (error); 6455344Spendry 6555344Spendry MALLOC(fmp, struct kernfs_mount *, sizeof(struct kernfs_mount), 6655344Spendry M_UFSMNT, M_WAITOK); /* XXX */ 6755344Spendry rvp->v_type = VDIR; 6855344Spendry rvp->v_flag |= VROOT; 6955344Spendry #ifdef KERNFS_DIAGNOSTIC 7055344Spendry printf("kernfs_mount: root vp = %x\n", rvp); 7155344Spendry #endif 7255344Spendry fmp->kf_root = rvp; 7355344Spendry mp->mnt_flag |= MNT_LOCAL; 7455344Spendry mp->mnt_data = (qaddr_t) fmp; 7555344Spendry getnewfsid(mp, MOUNT_KERNFS); 7655344Spendry 7755344Spendry (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 7855344Spendry bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 7955344Spendry bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 8055344Spendry bcopy("kernfs", mp->mnt_stat.f_mntfromname, sizeof("kernfs")); 8155344Spendry #ifdef KERNFS_DIAGNOSTIC 8255344Spendry printf("kernfs_mount: at %s\n", mp->mnt_stat.f_mntonname); 8355344Spendry #endif 8455344Spendry return (0); 8555344Spendry } 8655344Spendry 8755344Spendry kernfs_start(mp, flags, p) 8855344Spendry struct mount *mp; 8955344Spendry int flags; 9055344Spendry struct proc *p; 9155344Spendry { 9255344Spendry return (0); 9355344Spendry } 9455344Spendry 9555344Spendry kernfs_unmount(mp, mntflags, p) 9655344Spendry struct mount *mp; 9755344Spendry int mntflags; 9855344Spendry struct proc *p; 9955344Spendry { 10055344Spendry int error; 10155344Spendry int flags = 0; 10255344Spendry extern int doforce; 10355344Spendry struct vnode *rootvp = VFSTOKERNFS(mp)->kf_root; 10455344Spendry 10555344Spendry #ifdef KERNFS_DIAGNOSTIC 10655344Spendry printf("kernfs_unmount(mp = %x)\n", mp); 10755344Spendry #endif 10855344Spendry 10955344Spendry if (mntflags & MNT_FORCE) { 11055344Spendry /* kernfs can never be rootfs so don't check for it */ 11155344Spendry if (!doforce) 11255344Spendry return (EINVAL); 11355344Spendry flags |= FORCECLOSE; 11455344Spendry } 11555344Spendry 11655344Spendry /* 11755344Spendry * Clear out buffer cache. I don't think we 11855344Spendry * ever get anything cached at this level at the 11955344Spendry * moment, but who knows... 12055344Spendry */ 12155344Spendry #if 0 12255344Spendry #ifdef KERNFS_DIAGNOSTIC 12355344Spendry printf("kernfs_unmount: calling mntflushbuf\n"); 12455344Spendry #endif 125*55351Spendry mntflushbuf(mp, 0); 12655344Spendry #ifdef KERNFS_DIAGNOSTIC 12755344Spendry printf("kernfs_unmount: calling mntinvalbuf\n"); 12855344Spendry #endif 12955344Spendry if (mntinvalbuf(mp, 1)) 13055344Spendry return (EBUSY); 13155344Spendry #endif 13255344Spendry if (rootvp->v_usecount > 1) 13355344Spendry return (EBUSY); 13455344Spendry #ifdef KERNFS_DIAGNOSTIC 13555344Spendry printf("kernfs_unmount: calling vflush\n"); 13655344Spendry #endif 13755344Spendry if (error = vflush(mp, rootvp, flags)) 13855344Spendry return (error); 13955344Spendry 14055344Spendry #ifdef KERNFS_DIAGNOSTIC 14155344Spendry vprint("kernfs root", rootvp); 142*55351Spendry #endif 14355344Spendry /* 14455344Spendry * Release reference on underlying root vnode 14555344Spendry */ 14655344Spendry vrele(rootvp); 14755344Spendry /* 14855344Spendry * And blow it away for future re-use 14955344Spendry */ 15055344Spendry vgone(rootvp); 15155344Spendry /* 15255344Spendry * Finally, throw away the kernfs_mount structure 15355344Spendry */ 15455344Spendry free(mp->mnt_data, M_UFSMNT); /* XXX */ 15555344Spendry mp->mnt_data = 0; 15655344Spendry return 0; 15755344Spendry } 15855344Spendry 15955344Spendry kernfs_root(mp, vpp) 16055344Spendry struct mount *mp; 16155344Spendry struct vnode **vpp; 16255344Spendry { 16355344Spendry struct vnode *vp; 16455344Spendry int error; 16555344Spendry 16655344Spendry #ifdef KERNFS_DIAGNOSTIC 16755344Spendry printf("kernfs_root(mp = %x)\n", mp); 16855344Spendry #endif 16955344Spendry 17055344Spendry /* 17155344Spendry * Return locked reference to root. 17255344Spendry */ 17355344Spendry vp = VFSTOKERNFS(mp)->kf_root; 17455344Spendry VREF(vp); 17555344Spendry VOP_LOCK(vp); 17655344Spendry *vpp = vp; 17755344Spendry return (0); 17855344Spendry } 17955344Spendry 18055344Spendry kernfs_quotactl(mp, cmd, uid, arg, p) 18155344Spendry struct mount *mp; 18255344Spendry int cmd; 18355344Spendry uid_t uid; 18455344Spendry caddr_t arg; 18555344Spendry struct proc *p; 18655344Spendry { 18755344Spendry return (EOPNOTSUPP); 18855344Spendry } 18955344Spendry 19055344Spendry kernfs_statfs(mp, sbp, p) 19155344Spendry struct mount *mp; 19255344Spendry struct statfs *sbp; 19355344Spendry struct proc *p; 19455344Spendry { 19555344Spendry #ifdef KERNFS_DIAGNOSTIC 19655344Spendry printf("kernfs_statfs(mp = %x)\n", mp); 19755344Spendry #endif 19855344Spendry 19955344Spendry sbp->f_type = MOUNT_KERNFS; 20055344Spendry sbp->f_flags = 0; 20155344Spendry sbp->f_bsize = DEV_BSIZE; 20255344Spendry sbp->f_iosize = DEV_BSIZE; 20355344Spendry sbp->f_blocks = 2; /* 1K to keep df happy */ 20455344Spendry sbp->f_bfree = 0; 20555344Spendry sbp->f_bavail = 0; 20655344Spendry sbp->f_files = 0; /* Allow for "." */ 20755344Spendry sbp->f_ffree = 0; /* See comments above */ 20855344Spendry if (sbp != &mp->mnt_stat) { 20955344Spendry bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 21055344Spendry bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 21155344Spendry bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 21255344Spendry } 21355344Spendry return (0); 21455344Spendry } 21555344Spendry 21655344Spendry kernfs_sync(mp, waitfor) 21755344Spendry struct mount *mp; 21855344Spendry int waitfor; 21955344Spendry { 22055344Spendry return (0); 22155344Spendry } 22255344Spendry 22355344Spendry /* 224*55351Spendry * Kernfs flat namespace lookup. 22555344Spendry * Currently unsupported. 22655344Spendry */ 22755344Spendry kernfs_vget(mp, ino, vpp) 22855344Spendry struct mount *mp; 22955344Spendry ino_t ino; 23055344Spendry struct vnode **vpp; 23155344Spendry { 23255344Spendry 23355344Spendry return (EOPNOTSUPP); 23455344Spendry } 23555344Spendry 23655344Spendry 23755344Spendry kernfs_fhtovp(mp, fhp, setgen, vpp) 23855344Spendry struct mount *mp; 23955344Spendry struct fid *fhp; 24055344Spendry int setgen; 24155344Spendry struct vnode **vpp; 24255344Spendry { 24355344Spendry return (EOPNOTSUPP); 24455344Spendry } 24555344Spendry 24655344Spendry kernfs_vptofh(vp, fhp) 24755344Spendry struct vnode *vp; 24855344Spendry struct fid *fhp; 24955344Spendry { 25055344Spendry return (EOPNOTSUPP); 25155344Spendry } 25255344Spendry 25355344Spendry struct vfsops kernfs_vfsops = { 25455344Spendry kernfs_mount, 25555344Spendry kernfs_start, 25655344Spendry kernfs_unmount, 25755344Spendry kernfs_root, 25855344Spendry kernfs_quotactl, 25955344Spendry kernfs_statfs, 26055344Spendry kernfs_sync, 26155344Spendry kernfs_vget, 26255344Spendry kernfs_fhtovp, 26355344Spendry kernfs_vptofh, 26455344Spendry kernfs_init, 26555344Spendry }; 266