1: /*
   2:  * Copyright (c) 1982, 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)ufs_mount.c	7.1 (Berkeley) 6/5/86
   7:  */
   8: 
   9: #include "param.h"
  10: #include "systm.h"
  11: #include "dir.h"
  12: #include "user.h"
  13: #include "inode.h"
  14: #include "proc.h"
  15: #include "fs.h"
  16: #include "buf.h"
  17: #include "mount.h"
  18: #include "file.h"
  19: #include "conf.h"
  20: 
  21: smount()
  22: {
  23:     register struct a {
  24:         char    *fspec;
  25:         char    *freg;
  26:         int ronly;
  27:     } *uap = (struct a *)u.u_ap;
  28:     dev_t dev;
  29:     register struct inode *ip;
  30:     register struct fs *fs;
  31:     register struct nameidata *ndp = &u.u_nd;
  32:     u_int len;
  33: 
  34:     u.u_error = getmdev(&dev, uap->fspec);
  35:     if (u.u_error)
  36:         return;
  37:     ndp->ni_nameiop = LOOKUP | FOLLOW;
  38:     ndp->ni_segflg = UIO_USERSPACE;
  39:     ndp->ni_dirp = (caddr_t)uap->freg;
  40:     ip = namei(ndp);
  41:     if (ip == NULL)
  42:         return;
  43:     if (ip->i_count != 1) {
  44:         iput(ip);
  45:         u.u_error = EBUSY;
  46:         return;
  47:     }
  48:     if ((ip->i_mode&IFMT) != IFDIR) {
  49:         iput(ip);
  50:         u.u_error = ENOTDIR;
  51:         return;
  52:     }
  53:     fs = mountfs(dev, uap->ronly, ip);
  54:     if (fs == 0)
  55:         return;
  56:     (void) copyinstr(uap->freg, fs->fs_fsmnt, sizeof(fs->fs_fsmnt)-1, &len);
  57:     bzero(fs->fs_fsmnt + len, sizeof (fs->fs_fsmnt) - len);
  58: }
  59: 
  60: /* this routine has races if running twice */
  61: struct fs *
  62: mountfs(dev, ronly, ip)
  63:     dev_t dev;
  64:     int ronly;
  65:     struct inode *ip;
  66: {
  67:     register struct mount *mp = 0;
  68:     struct buf *tp = 0;
  69:     register struct buf *bp = 0;
  70:     register struct fs *fs;
  71:     int blks;
  72:     caddr_t space;
  73:     int i, size;
  74:     register error;
  75:     int needclose = 0;
  76: 
  77:     error =
  78:         (*bdevsw[major(dev)].d_open)(dev, ronly ? FREAD : FREAD|FWRITE);
  79:     if (error)
  80:         goto out;
  81:     needclose = 1;
  82:     tp = bread(dev, SBLOCK, SBSIZE);
  83:     if (tp->b_flags & B_ERROR)
  84:         goto out;
  85:     for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
  86:         if (mp->m_bufp != 0 && dev == mp->m_dev) {
  87:             mp = 0;
  88:             error = EBUSY;
  89:             needclose = 0;
  90:             goto out;
  91:         }
  92:     for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
  93:         if (mp->m_bufp == 0)
  94:             goto found;
  95:     mp = 0;
  96:     error = EMFILE;     /* needs translation */
  97:     goto out;
  98: found:
  99:     mp->m_bufp = tp;    /* just to reserve this slot */
 100:     mp->m_dev = NODEV;
 101:     fs = tp->b_un.b_fs;
 102:     if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE
 103:         || fs->fs_bsize < sizeof(struct fs)) {
 104:         error = EINVAL;     /* also needs translation */
 105:         goto out;
 106:     }
 107:     bp = geteblk((int)fs->fs_sbsize);
 108:     mp->m_bufp = bp;
 109:     bcopy((caddr_t)tp->b_un.b_addr, (caddr_t)bp->b_un.b_addr,
 110:        (u_int)fs->fs_sbsize);
 111:     brelse(tp);
 112:     tp = 0;
 113:     fs = bp->b_un.b_fs;
 114:     fs->fs_ronly = (ronly != 0);
 115:     if (ronly == 0)
 116:         fs->fs_fmod = 1;
 117:     blks = howmany(fs->fs_cssize, fs->fs_fsize);
 118:     space = wmemall(vmemall, (int)fs->fs_cssize);
 119:     if (space == 0) {
 120:         error = ENOMEM;
 121:         goto out;
 122:     }
 123:     for (i = 0; i < blks; i += fs->fs_frag) {
 124:         size = fs->fs_bsize;
 125:         if (i + fs->fs_frag > blks)
 126:             size = (blks - i) * fs->fs_fsize;
 127:         tp = bread(dev, fsbtodb(fs, fs->fs_csaddr + i), size);
 128:         if (tp->b_flags&B_ERROR) {
 129:             wmemfree(space, (int)fs->fs_cssize);
 130:             goto out;
 131:         }
 132:         bcopy((caddr_t)tp->b_un.b_addr, space, (u_int)size);
 133:         fs->fs_csp[fragstoblks(fs, i)] = (struct csum *)space;
 134:         space += size;
 135:         brelse(tp);
 136:         tp = 0;
 137:     }
 138:     mp->m_inodp = ip;
 139:     mp->m_dev = dev;
 140:     if (ip) {
 141:         ip->i_flag |= IMOUNT;
 142:         cacheinval(ip);
 143:         iunlock(ip);
 144:     }
 145:     return (fs);
 146: out:
 147:     if (error == 0)
 148:         error = EIO;
 149:     if (ip)
 150:         iput(ip);
 151:     if (mp)
 152:         mp->m_bufp = 0;
 153:     if (bp)
 154:         brelse(bp);
 155:     if (tp)
 156:         brelse(tp);
 157:     if (needclose) {
 158:         (*bdevsw[major(dev)].d_close)(dev, ronly? FREAD : FREAD|FWRITE);
 159:         binval(dev);
 160:     }
 161:     u.u_error = error;
 162:     return (0);
 163: }
 164: 
 165: umount()
 166: {
 167:     struct a {
 168:         char    *fspec;
 169:     } *uap = (struct a *)u.u_ap;
 170: 
 171:     u.u_error = unmount1(uap->fspec, 0);
 172: }
 173: 
 174: unmount1(fname, forcibly)
 175:     caddr_t fname;
 176:     int forcibly;
 177: {
 178:     dev_t dev;
 179:     register struct mount *mp;
 180:     int stillopen, flag, error;
 181:     register struct inode *ip;
 182:     register struct fs *fs;
 183: 
 184:     error = getmdev(&dev, fname);
 185:     if (error)
 186:         return (error);
 187:     for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
 188:         if (mp->m_bufp != NULL && dev == mp->m_dev)
 189:             goto found;
 190:     return (EINVAL);
 191: found:
 192:     xumount(dev);   /* remove unused sticky files from text table */
 193:     nchinval(dev);  /* flush the name cache */
 194:     update();
 195: #ifdef QUOTA
 196:     if ((stillopen = iflush(dev, mp->m_qinod)) < 0 && !forcibly)
 197: #else
 198:     if ((stillopen = iflush(dev)) < 0 && !forcibly)
 199: #endif
 200:         return (EBUSY);
 201:     if (stillopen < 0)
 202:         return (EBUSY);         /* XXX */
 203: #ifdef QUOTA
 204:     closedq(mp);
 205:     /*
 206: 	 * Here we have to iflush again to get rid of the quota inode.
 207: 	 * A drag, but it would be ugly to cheat, & this doesn't happen often
 208: 	 */
 209:     (void)iflush(dev, (struct inode *)NULL);
 210: #endif
 211:     ip = mp->m_inodp;
 212:     ip->i_flag &= ~IMOUNT;
 213:     irele(ip);
 214:     fs = mp->m_bufp->b_un.b_fs;
 215:     wmemfree((caddr_t)fs->fs_csp[0], (int)fs->fs_cssize);
 216:     flag = !fs->fs_ronly;
 217:     brelse(mp->m_bufp);
 218:     mp->m_bufp = 0;
 219:     mp->m_dev = 0;
 220:     mpurge(mp - &mount[0]);
 221:     if (!stillopen) {
 222:         (*bdevsw[major(dev)].d_close)(dev, flag);
 223:         binval(dev);
 224:     }
 225:     return (0);
 226: }
 227: 
 228: sbupdate(mp)
 229:     struct mount *mp;
 230: {
 231:     register struct fs *fs = mp->m_bufp->b_un.b_fs;
 232:     register struct buf *bp;
 233:     int blks;
 234:     caddr_t space;
 235:     int i, size;
 236: 
 237:     bp = getblk(mp->m_dev, SBLOCK, (int)fs->fs_sbsize);
 238:     bcopy((caddr_t)fs, bp->b_un.b_addr, (u_int)fs->fs_sbsize);
 239:     bwrite(bp);
 240:     blks = howmany(fs->fs_cssize, fs->fs_fsize);
 241:     space = (caddr_t)fs->fs_csp[0];
 242:     for (i = 0; i < blks; i += fs->fs_frag) {
 243:         size = fs->fs_bsize;
 244:         if (i + fs->fs_frag > blks)
 245:             size = (blks - i) * fs->fs_fsize;
 246:         bp = getblk(mp->m_dev, fsbtodb(fs, fs->fs_csaddr + i), size);
 247:         bcopy(space, bp->b_un.b_addr, (u_int)size);
 248:         space += size;
 249:         bwrite(bp);
 250:     }
 251: }
 252: 
 253: /*
 254:  * Common code for mount and umount.
 255:  * Check that the user's argument is a reasonable
 256:  * thing on which to mount, and return the device number if so.
 257:  */
 258: getmdev(pdev, fname)
 259:     caddr_t fname;
 260:     dev_t *pdev;
 261: {
 262:     dev_t dev;
 263:     register struct inode *ip;
 264:     register struct nameidata *ndp = &u.u_nd;
 265: 
 266:     if (!suser())
 267:         return (u.u_error);
 268:     ndp->ni_nameiop = LOOKUP | FOLLOW;
 269:     ndp->ni_segflg = UIO_USERSPACE;
 270:     ndp->ni_dirp = fname;
 271:     ip = namei(ndp);
 272:     if (ip == NULL) {
 273:         if (u.u_error == ENOENT)
 274:             return (ENODEV); /* needs translation */
 275:         return (u.u_error);
 276:     }
 277:     if ((ip->i_mode&IFMT) != IFBLK) {
 278:         iput(ip);
 279:         return (ENOTBLK);
 280:     }
 281:     dev = (dev_t)ip->i_rdev;
 282:     iput(ip);
 283:     if (major(dev) >= nblkdev)
 284:         return (ENXIO);
 285:     *pdev = dev;
 286:     return (0);
 287: }

Defined functions

getmdev defined in line 258; used 3 times
mountfs defined in line 61; used 3 times
sbupdate defined in line 228; used 1 times
smount defined in line 21; used 2 times
umount defined in line 165; used 2 times
unmount1 defined in line 174; used 1 times

Defined struct's

a defined in line 167; used 4 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1374
Valid CSS Valid XHTML 1.0 Strict