X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/f93197fc776222d2758eb666b8fbabb1bd6feb18..3e00400bea3a971636ad614723aba73df9ae4fa4:/usr/src/sys/ufs/lfs/lfs_vfsops.c diff --git a/usr/src/sys/ufs/lfs/lfs_vfsops.c b/usr/src/sys/ufs/lfs/lfs_vfsops.c index 463816177b..66e84b276d 100644 --- a/usr/src/sys/ufs/lfs/lfs_vfsops.c +++ b/usr/src/sys/ufs/lfs/lfs_vfsops.c @@ -1,17 +1,22 @@ -/* lfs_vfsops.c 6.2 84/01/03 */ +/* + * Copyright (c) 1982 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + * + * @(#)lfs_vfsops.c 6.11 (Berkeley) %G% + */ -#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() { @@ -19,36 +24,40 @@ 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 | NOCACHE, 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) { + if (ip->i_count != 1) { iput(ip); u.u_error = EBUSY; return; } + if ((ip->i_mode&IFMT) != IFDIR) { + iput(ip); + u.u_error = ENOTDIR; + return; + } 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) @@ -63,30 +72,38 @@ mountfs(dev, ronly, ip) int blks; caddr_t space; int i, size; + register error; + int needclose = 0; - 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; - } + needclose = 1; 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, @@ -94,15 +111,15 @@ found: 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) @@ -113,7 +130,7 @@ found: goto out; } bcopy((caddr_t)tp->b_un.b_addr, space, (u_int)size); - fs->fs_csp[i / fs->fs_frag] = (struct csum *)space; + fs->fs_csp[fragstoblks(fs, i)] = (struct csum *)space; space += size; brelse(tp); tp = 0; @@ -126,7 +143,8 @@ found: } return (fs); out: - u.u_error = EBUSY; + if (error == 0) + error = EIO; if (ip) iput(ip); if (mp) @@ -135,6 +153,10 @@ out: brelse(bp); if (tp) brelse(tp); + if (needclose) + (*bdevsw[major(dev)].d_close)(dev, ronly ? FREAD : FREAD|FWRITE); + binval(dev); + u.u_error = error; return (0); } @@ -142,12 +164,13 @@ umount() { 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; @@ -156,7 +179,7 @@ unmount1(forcibly) 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++) @@ -230,23 +253,33 @@ sbupdate(mp) * 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); - if (ip == NULL) + ndp->ni_nameiop = LOOKUP | FOLLOW; + ndp->ni_segflg = UIO_USERSPACE; + ndp->ni_dirp = fname; + ip = namei(ndp); + if (ip == NULL) { + if (u.u_error == ENOENT) + return (ENODEV); /* needs translation */ 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); }