1*37488Smckusick /* 2*37488Smckusick * Copyright (c) 1989 The Regents of the University of California. 3*37488Smckusick * All rights reserved. 4*37488Smckusick * 5*37488Smckusick * Redistribution and use in source and binary forms are permitted 6*37488Smckusick * provided that the above copyright notice and this paragraph are 7*37488Smckusick * duplicated in all such forms and that any documentation, 8*37488Smckusick * advertising materials, and other materials related to such 9*37488Smckusick * distribution and use acknowledge that the software was developed 10*37488Smckusick * by the University of California, Berkeley. The name of the 11*37488Smckusick * University may not be used to endorse or promote products derived 12*37488Smckusick * from this software without specific prior written permission. 13*37488Smckusick * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*37488Smckusick * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*37488Smckusick * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16*37488Smckusick * 17*37488Smckusick * @(#)vfs_subr.c 7.1 (Berkeley) 04/24/89 18*37488Smckusick */ 19*37488Smckusick 20*37488Smckusick /* 21*37488Smckusick * External virtual filesystem routines 22*37488Smckusick */ 23*37488Smckusick 24*37488Smckusick #include "param.h" 25*37488Smckusick #include "mount.h" 26*37488Smckusick #include "time.h" 27*37488Smckusick #include "vnode.h" 28*37488Smckusick #include "errno.h" 29*37488Smckusick 30*37488Smckusick /* 31*37488Smckusick * Add a new mount point to the list of mounted filesystems. 32*37488Smckusick * Lock the filesystem so that namei will not cross into the 33*37488Smckusick * the tree below the covered vnode. 34*37488Smckusick */ 35*37488Smckusick vfs_add(mountedvp, mp, flags) 36*37488Smckusick register struct vnode *mountedvp; 37*37488Smckusick register struct mount *mp; 38*37488Smckusick int flags; 39*37488Smckusick { 40*37488Smckusick register int error; 41*37488Smckusick 42*37488Smckusick error = vfs_lock(mp); 43*37488Smckusick if (error) 44*37488Smckusick return (error); 45*37488Smckusick if (mountedvp == (struct vnode *)0) { 46*37488Smckusick /* 47*37488Smckusick * We are mounting the root filesystem. 48*37488Smckusick */ 49*37488Smckusick rootfs = mp; 50*37488Smckusick mp->m_next = mp; 51*37488Smckusick mp->m_prev = mp; 52*37488Smckusick } else { 53*37488Smckusick if (mountedvp->v_mountedhere != (struct mount *)0) { 54*37488Smckusick vfs_unlock(mp); 55*37488Smckusick return(EBUSY); 56*37488Smckusick } 57*37488Smckusick /* 58*37488Smckusick * Put the new filesystem on the mount list after root. 59*37488Smckusick */ 60*37488Smckusick mp->m_next = rootfs->m_next; 61*37488Smckusick mp->m_prev = rootfs; 62*37488Smckusick rootfs->m_next = mp; 63*37488Smckusick mp->m_next->m_prev = mp; 64*37488Smckusick mountedvp->v_mountedhere = mp; 65*37488Smckusick } 66*37488Smckusick mp->m_vnodecovered = mountedvp; 67*37488Smckusick if (flags & M_RDONLY) { 68*37488Smckusick mp->m_flag |= M_RDONLY; 69*37488Smckusick } else { 70*37488Smckusick mp->m_flag &= ~M_RDONLY; 71*37488Smckusick } 72*37488Smckusick if (flags & M_NOSUID) { 73*37488Smckusick mp->m_flag |= M_NOSUID; 74*37488Smckusick } else { 75*37488Smckusick mp->m_flag &= ~M_NOSUID; 76*37488Smckusick } 77*37488Smckusick return (0); 78*37488Smckusick } 79*37488Smckusick 80*37488Smckusick /* 81*37488Smckusick * Remove a mount point from the list of mounted filesystems. 82*37488Smckusick * Unmount of the root is illegal. 83*37488Smckusick */ 84*37488Smckusick void 85*37488Smckusick vfs_remove(mp) 86*37488Smckusick register struct mount *mp; 87*37488Smckusick { 88*37488Smckusick 89*37488Smckusick if (mp == rootfs) 90*37488Smckusick panic("vfs_remove: unmounting root"); 91*37488Smckusick mp->m_prev->m_next = mp->m_next; 92*37488Smckusick mp->m_next->m_prev = mp->m_prev; 93*37488Smckusick mp->m_vnodecovered->v_mountedhere = (struct mount *)0; 94*37488Smckusick vfs_unlock(mp); 95*37488Smckusick } 96*37488Smckusick 97*37488Smckusick /* 98*37488Smckusick * Lock a filesystem. 99*37488Smckusick * Used to prevent access to it while mounting and unmounting. 100*37488Smckusick */ 101*37488Smckusick vfs_lock(mp) 102*37488Smckusick register struct mount *mp; 103*37488Smckusick { 104*37488Smckusick 105*37488Smckusick if (mp->m_flag & M_MLOCK) 106*37488Smckusick return (EBUSY); 107*37488Smckusick mp->m_flag |= M_MLOCK; 108*37488Smckusick return (0); 109*37488Smckusick } 110*37488Smckusick 111*37488Smckusick /* 112*37488Smckusick * Unlock a locked filesystem. 113*37488Smckusick * Panic if filesystem is not locked. 114*37488Smckusick */ 115*37488Smckusick void 116*37488Smckusick vfs_unlock(mp) 117*37488Smckusick register struct mount *mp; 118*37488Smckusick { 119*37488Smckusick 120*37488Smckusick if ((mp->m_flag & M_MLOCK) == 0) 121*37488Smckusick panic("vfs_unlock: locked fs"); 122*37488Smckusick mp->m_flag &= ~M_MLOCK; 123*37488Smckusick if (mp->m_flag & M_MWAIT) { 124*37488Smckusick mp->m_flag &= ~M_MWAIT; 125*37488Smckusick wakeup((caddr_t)mp); 126*37488Smckusick } 127*37488Smckusick } 128*37488Smckusick 129*37488Smckusick /* 130*37488Smckusick * Lookup a mount point by filesystem identifier. 131*37488Smckusick */ 132*37488Smckusick struct mount * 133*37488Smckusick getvfs(fsid) 134*37488Smckusick fsid_t *fsid; 135*37488Smckusick { 136*37488Smckusick register struct mount *mp; 137*37488Smckusick 138*37488Smckusick for (mp = rootfs; mp; mp = mp->m_next) { 139*37488Smckusick if (mp->m_fsid.val[0] == fsid->val[0] && 140*37488Smckusick mp->m_fsid.val[1] == fsid->val[1]) { 141*37488Smckusick break; 142*37488Smckusick } 143*37488Smckusick } 144*37488Smckusick return (mp); 145*37488Smckusick } 146*37488Smckusick 147*37488Smckusick /* 148*37488Smckusick * Set vnode attributes to VNOVAL 149*37488Smckusick */ 150*37488Smckusick void vattr_null(vap) 151*37488Smckusick register struct vattr *vap; 152*37488Smckusick { 153*37488Smckusick 154*37488Smckusick vap->va_type = VNON; 155*37488Smckusick vap->va_mode = vap->va_nlink = vap->va_uid = vap->va_gid = 156*37488Smckusick vap->va_fsid = vap->va_fileid = vap->va_size = 157*37488Smckusick vap->va_size1 = vap->va_blocksize = vap->va_rdev = 158*37488Smckusick vap->va_bytes = vap->va_bytes1 = 159*37488Smckusick vap->va_atime.tv_sec = vap->va_atime.tv_usec = 160*37488Smckusick vap->va_mtime.tv_sec = vap->va_mtime.tv_usec = 161*37488Smckusick vap->va_ctime.tv_sec = vap->va_ctime.tv_usec = VNOVAL; 162*37488Smckusick } 163