V9/sys/sys/mount.c

Compare this file to the similar file:
Show the results in this format:

/*
 * code related to mounting and unmounting filesystems
 */

/*
 * bugs:
 * temporary extra antique mount points
 * the mount table is now anachronistic.
 * it is still maintained
 * only to help the virtual memory code.
 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/mount.h"
#include "../h/ino.h"
/*#include "../h/reg.h"*/
#include "../h/buf.h"
#include "../h/filsys.h"
#include "../h/dir.h"
#include "../h/user.h"
#include "../h/inode.h"
#include "../h/file.h"
#include "../h/stream.h"
#include "../h/conf.h"
#include "../h/stat.h"

/*
 * sys fmount
 * call the filesystem-specific mount routine with
 *	the inode of the device to be mounted
 *	the inode of the mount point, still locked
 *	the flag argument
 */

fmount()
{
	register struct a {
		int fstype;
		int fd;
		char *name;
		int flag;
	} *uap = (struct a *)u.u_ap;
	struct file *fp;
	struct inode *ip;

	if (uap->fstype < 0 || uap->fstype >= nfstyp) {
		u.u_error = EINVAL;
		return;
	}
	if ((fp = getf(uap->fd)) == NULL) {
		u.u_error = EBADF;
		return;
	}
	u.u_dirp = (caddr_t)uap->name;
	if ((ip = namei(uchar, (struct argnamei *)NULL, 1)) == NULL)
		return;
	(*fstypsw[uap->fstype].t_mount)(fp->f_inode, ip, uap->flag, 1, uap->fstype);
	iput(ip);
}

/*
 * sys funmount
 * call the fs-particular unmount routine with
 * the inode of the mount point
 */

funmount()
{
	struct a {
		char *name;
	} *uap = (struct a *)u.u_ap;
	struct inode *ip, *mip;

	u.u_dirp = (caddr_t)uap->name;
	if ((ip = namei(uchar, (struct argnamei *)NULL, 1)) == NULL)
		return;
	if ((mip = ip->i_mpoint) == NULL) {
		iput(ip);
		u.u_error = EINVAL;
		return;
	}
	iput(ip);
	if (mip->i_mroot == NULL)
		panic("fsunmount");
	if (mip->i_mroot == rootdir) {
		u.u_error = EINVAL;
		return;
	}
	(*fstypsw[ip->i_fstyp].t_mount)((struct inode *)NULL, mip, 0, 0, ip->i_fstyp);
}

/* find the mount slot assigned a particular device */
struct mount *
findmount(fstyp, dev)
	int fstyp;
	dev_t dev;
{
	register struct mount *mp;

	for(mp = mount; mp < mount + NMOUNT; mp++)
		if(mp->m_flags&M_MOUNTED && mp->m_dev==dev && mp->m_fstyp==fstyp)
			return mp;
	return NULL;
}

/* get a free mount slot */
struct mount *
allocmount(fstyp, dev)
	int fstyp;
	dev_t dev;
{
	register struct mount *mp, *free;

	free = NULL;
	for(mp = mount; mp < mount + NMOUNT; mp++) {
		if(!mp->m_flags&M_MOUNTED) {
			if (free == NULL)
				free = mp;
		} else if(mp->m_dev == dev && mp->m_fstyp == fstyp)
			return NULL;	/* mounted twice */
	}
	if (free != NULL) {
		free->m_flags |= M_MOUNTED;
		free->m_dev = dev;
		free->m_fstyp = fstyp;
	}
	return free;
}

/* free up a mount structure */
freemount(mp)
	struct mount *mp;
{
	if (mp == NULL)
		panic("freemount");
	mp->m_flags &= ~M_MOUNTED;
}

/*
 * the old mount system call.
 */

sysmount()
{
	register struct inode *ip, *sip;
	register struct a {
		char	*fspec;
		char	*freg;
		int	ronly;
	} *uap;

	uap = (struct a *)u.u_ap;
	u.u_dirp = (caddr_t)uap->fspec;
	if ((sip = namei(uchar, (struct argnamei *)NULL, 1)) == NULL)
		return;
	u.u_dirp = (caddr_t)uap->freg;
	if ((ip = namei(uchar, (struct argnamei *)NULL, 1)) == NULL) {
		iput(sip);
		return;
	}
	(*fstypsw[0].t_mount)(sip, ip, uap->ronly, 1, 0);
	iput(sip);
	iput(ip);
}

/*
 * the old umount system call.
 */

sysumount()
{
	register struct inode *ip;
	register struct mount *mp;
	register struct a {
		char	*fspec;
	} *uap = (struct a *)u.u_ap;

	u.u_dirp = (caddr_t)uap->fspec;
	if ((ip = namei(uchar, (struct argnamei *)NULL, 1)) == NULL)
		return;
	if ((mp = findmount(0, (dev_t)ip->i_un.i_rdev)) == NULL) {
		iput(ip);
		u.u_error = ENODEV;
		return;
	}
	iput(ip);
	if ((ip = mp->m_inodp) == NULL)
		panic("umount");
	if (ip->i_mroot == rootdir) {
		u.u_error = EINVAL;
		return;
	}
	(*fstypsw[0].t_mount)((struct inode *)NULL, ip, 0, 0, 0);
}

/* gmount(fstyp, ...) */
/* glue until converted to new stuff */
gmount()
{
	struct inode *ip;
	struct inode *cip;
	register struct file *fp;
	struct inode pi;
	int i;
	struct a {
		unsigned int fstyp;
		int gumby;	/* unqname or freg */
		int flag;
		int cfd;
		char *freg;
	} *uap = (struct a *)u.u_ap;

	switch (uap->fstyp) {
	case 1:
	case 7:
		i = uap->fstyp;
		if (uap->flag == 0) {	/* mount */
			if ((fp = getf(uap->cfd)) == NULL)
				return;
			u.u_dirp = (caddr_t)uap->freg;
			if ((ip = namei(uchar, (struct argnamei *)NULL, 1)) == NULL)
				return;
			(*fstypsw[i].t_mount)(fp->f_inode, ip, uap->gumby, 1, i);
			iput(ip);
		}
		else {			/* unmount */
			pi.i_fstyp = uap->fstyp;
			pi.i_dev = uap->gumby;
			pi.i_un.i_cip = NULL;
			if ((ip = iget(&pi, pi.i_dev, ROOTINO)) == NULL) {
				u.u_error = EINVAL;	/* for setup */
				return;
			}
			if (ip->i_un.i_cip == NULL) {	/* got the fake */
				iput(ip);
				u.u_error = EINVAL;
				return;
			}
			cip = ip->i_mpoint;
			iput(ip);
			(*fstypsw[i].t_mount)((struct inode *)NULL, cip, uap->gumby, 0, i);
		}
		break;

	case 2:
		u.u_dirp = (caddr_t)uap->gumby;
		if ((ip = namei(uchar, (struct argnamei *)NULL, 1)) == NULL)
			return;
		(*fstypsw[2].t_mount)((struct inode *)NULL, ip, 0, !uap->flag, 2);
		if (uap->flag == 0)
			iput(ip);
		break;

	case 3:
		if (uap->flag == 0) {
			if ((fp = getf(uap->cfd)) == NULL)
				return;
			cip = fp->f_inode;
		}
		u.u_dirp = (caddr_t)uap->freg;
		if ((ip = namei(uchar, (struct argnamei *)NULL, 1)) == NULL)
			return;
		(*fstypsw[3].t_mount)(cip, ip, 0, !uap->flag, 3);
		iput(ip);
		break;

	default:
		u.u_error = EINVAL;
		break;
	}
}