-/* lfs_vfsops.c 4.1 83/05/27 */
+/* lfs_vfsops.c 6.8 84/08/29 */
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/inode.h"
-#include "../h/proc.h"
-#include "../h/fs.h"
-#include "../h/buf.h"
-#include "../h/mount.h"
-#include "../h/file.h"
-#include "../h/nami.h"
-#include "../h/conf.h"
+#include "param.h"
+#include "systm.h"
+#include "dir.h"
+#include "user.h"
+#include "inode.h"
+#include "proc.h"
+#include "fs.h"
+#include "buf.h"
+#include "mount.h"
+#include "file.h"
+#include "conf.h"
smount()
{
char *fspec;
char *freg;
int ronly;
- } *uap;
+ } *uap = (struct a *)u.u_ap;
dev_t dev;
register struct inode *ip;
register struct fs *fs;
register char *cp;
+ register struct nameidata *ndp = &u.u_nd;
+ u_int len;
- uap = (struct a *)u.u_ap;
- u.u_error = getmdev(&dev);
+ u.u_error = getmdev(&dev, uap->fspec);
if (u.u_error)
return;
- u.u_dirp = (caddr_t)uap->freg;
- ip = namei(uchar, LOOKUP, 1);
+ ndp->ni_nameiop = LOOKUP | NOCACHE | FOLLOW;
+ ndp->ni_segflg = UIO_USERSPACE;
+ ndp->ni_dirp = (caddr_t)uap->freg;
+ ip = namei(ndp);
if (ip == NULL)
return;
if (ip->i_count!=1 || (ip->i_mode&IFMT) != IFDIR) {
fs = mountfs(dev, uap->ronly, ip);
if (fs == 0)
return;
- u.u_dirp = uap->freg;
- for (cp = fs->fs_fsmnt; cp < &fs->fs_fsmnt[sizeof(fs->fs_fsmnt) - 2]; )
- if ((*cp++ = uchar()) == 0)
- u.u_dirp--; /* get 0 again */
- *cp = 0;
+ (void) copyinstr(uap->freg, fs->fs_fsmnt, sizeof(fs->fs_fsmnt)-1, &len);
+ bzero(fs->fs_fsmnt + len, sizeof (fs->fs_fsmnt) - len);
}
-/* this routine has lousy error codes */
/* this routine has races if running twice */
struct fs *
mountfs(dev, ronly, ip)
int blks;
caddr_t space;
int i, size;
+ register error;
- u.u_error =
+ error =
(*bdevsw[major(dev)].d_open)(dev, ronly ? FREAD : FREAD|FWRITE);
- if (u.u_error) {
- u.u_error = EIO;
+ if (error)
goto out;
- }
tp = bread(dev, SBLOCK, SBSIZE);
if (tp->b_flags & B_ERROR)
goto out;
for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
if (mp->m_bufp != 0 && dev == mp->m_dev) {
mp = 0;
+ error = EBUSY;
goto out;
}
for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
if (mp->m_bufp == 0)
goto found;
mp = 0;
+ error = EMFILE; /* needs translation */
goto out;
found:
mp->m_bufp = tp; /* just to reserve this slot */
mp->m_dev = NODEV;
fs = tp->b_un.b_fs;
+ if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE
+ || fs->fs_bsize < sizeof(struct fs)) {
+ error = EINVAL; /* also needs translation */
+ goto out;
+ }
bp = geteblk((int)fs->fs_sbsize);
mp->m_bufp = bp;
bcopy((caddr_t)tp->b_un.b_addr, (caddr_t)bp->b_un.b_addr,
brelse(tp);
tp = 0;
fs = bp->b_un.b_fs;
- if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE)
- goto out;
fs->fs_ronly = (ronly != 0);
if (ronly == 0)
fs->fs_fmod = 1;
blks = howmany(fs->fs_cssize, fs->fs_fsize);
space = wmemall(vmemall, (int)fs->fs_cssize);
- if (space == 0)
+ if (space == 0) {
+ error = ENOMEM;
goto out;
+ }
for (i = 0; i < blks; i += fs->fs_frag) {
size = fs->fs_bsize;
if (i + fs->fs_frag > blks)
}
return (fs);
out:
- u.u_error = EBUSY;
+ if (error == 0)
+ error = EIO;
if (ip)
iput(ip);
if (mp)
brelse(bp);
if (tp)
brelse(tp);
+ u.u_error = error;
return (0);
}
{
struct a {
char *fspec;
- };
+ } *uap = (struct a *)u.u_ap;
- u.u_error = unmount1(0);
+ u.u_error = unmount1(uap->fspec, 0);
}
-unmount1(forcibly)
+unmount1(fname, forcibly)
+ caddr_t fname;
int forcibly;
{
dev_t dev;
register struct inode *ip;
register struct fs *fs;
- error = getmdev(&dev);
+ error = getmdev(&dev, fname);
if (error)
return (error);
for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
return (EINVAL);
found:
xumount(dev); /* remove unused sticky files from text table */
+ nchinval(dev); /* flush the name cache */
update();
#ifdef QUOTA
if ((stillopen = iflush(dev, mp->m_qinod)) < 0 && !forcibly)
* Check that the user's argument is a reasonable
* thing on which to mount, and return the device number if so.
*/
-getmdev(pdev)
+getmdev(pdev, fname)
+ caddr_t fname;
dev_t *pdev;
{
dev_t dev;
register struct inode *ip;
+ register struct nameidata *ndp = &u.u_nd;
if (!suser())
return (u.u_error);
- ip = namei(uchar, LOOKUP, 1);
+ ndp->ni_nameiop = LOOKUP | FOLLOW;
+ ndp->ni_segflg = UIO_USERSPACE;
+ ndp->ni_dirp = fname;
+ ip = namei(ndp);
if (ip == NULL)
return (u.u_error);
- if ((ip->i_mode&IFMT) != IFBLK)
+ if ((ip->i_mode&IFMT) != IFBLK) {
+ iput(ip);
return (ENOTBLK);
+ }
dev = (dev_t)ip->i_rdev;
+ iput(ip);
if (major(dev) >= nblkdev)
return (ENXIO);
- iput(ip);
*pdev = dev;
return (0);
}