#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/mount.h>
#include <sys/vnode.h>
#include <vfs/procfs/procfs.h>
extern struct vop_ops procfs_vnode_vops;
static int procfs_mount (struct mount *mp, char *path, caddr_t data,
struct ucred *cred);
static int procfs_statfs (struct mount *mp, struct statfs *sbp,
struct ucred *cred);
static int procfs_unmount (struct mount *mp, int mntflags);
static int
procfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
{
size_t size;
int error;
if (mp->mnt_flag & MNT_UPDATE)
return (EOPNOTSUPP);
if (mp->mnt_vfc->vfc_refcount == 1 && (error = at_exit(procfs_exit))) {
kprintf("procfs: cannot register procfs_exit with at_exit\n");
return(error);
}
mp->mnt_flag |= MNT_LOCAL;
mp->mnt_kern_flag |= MNTK_NOSTKMNT;
mp->mnt_kern_flag |= MNTK_QUICKHALT;
mp->mnt_data = NULL;
vfs_getnewfsid(mp);
size = sizeof("procfs") - 1;
bcopy("procfs", mp->mnt_stat.f_mntfromname, size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
procfs_statfs(mp, &mp->mnt_stat, cred);
vfs_add_vnodeops(mp, &procfs_vnode_vops, &mp->mnt_vn_norm_ops);
return (0);
}
static int
procfs_unmount(struct mount *mp, int mntflags)
{
int error;
int flags = 0;
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
error = vflush(mp, 0, flags);
if (error)
return (error);
if (mp->mnt_vfc->vfc_refcount == 1)
rm_at_exit(procfs_exit);
return (0);
}
int
procfs_root(struct mount *mp, struct vnode **vpp)
{
return (procfs_allocvp(mp, vpp, 0, Proot));
}
static int
procfs_statfs(struct mount *mp, struct statfs *sbp, struct ucred *cred)
{
sbp->f_bsize = PAGE_SIZE;
sbp->f_iosize = PAGE_SIZE;
sbp->f_blocks = 1;
sbp->f_bfree = 0;
sbp->f_bavail = 0;
sbp->f_files = maxproc;
sbp->f_ffree = maxproc - nprocs;
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_mntfromname, sbp->f_mntfromname, MNAMELEN);
}
return (0);
}
static struct vfsops procfs_vfsops = {
.vfs_flags = 0,
.vfs_mount = procfs_mount,
.vfs_unmount = procfs_unmount,
.vfs_root = procfs_root,
.vfs_statfs = procfs_statfs,
};
VFS_SET(procfs_vfsops, procfs, VFCF_SYNTHETIC | VFCF_MPSAFE);
MODULE_VERSION(procfs, 1);