1df8bae1dSRodney W. Grimes /* 2df8bae1dSRodney W. Grimes * Copyright (c) 1991, 1993 3df8bae1dSRodney W. Grimes * The Regents of the University of California. All rights reserved. 4df8bae1dSRodney W. Grimes * (c) UNIX System Laboratories, Inc. 5df8bae1dSRodney W. Grimes * All or some portions of this file are derived from material licensed 6df8bae1dSRodney W. Grimes * to the University of California by American Telephone and Telegraph 7df8bae1dSRodney W. Grimes * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8df8bae1dSRodney W. Grimes * the permission of UNIX System Laboratories, Inc. 9df8bae1dSRodney W. Grimes * 10df8bae1dSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 11df8bae1dSRodney W. Grimes * modification, are permitted provided that the following conditions 12df8bae1dSRodney W. Grimes * are met: 13df8bae1dSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 14df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 15df8bae1dSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 16df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 17df8bae1dSRodney W. Grimes * documentation and/or other materials provided with the distribution. 18df8bae1dSRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 19df8bae1dSRodney W. Grimes * must display the following acknowledgement: 20df8bae1dSRodney W. Grimes * This product includes software developed by the University of 21df8bae1dSRodney W. Grimes * California, Berkeley and its contributors. 22df8bae1dSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 23df8bae1dSRodney W. Grimes * may be used to endorse or promote products derived from this software 24df8bae1dSRodney W. Grimes * without specific prior written permission. 25df8bae1dSRodney W. Grimes * 26df8bae1dSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27df8bae1dSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28df8bae1dSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29df8bae1dSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30df8bae1dSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31df8bae1dSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32df8bae1dSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33df8bae1dSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34df8bae1dSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35df8bae1dSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36df8bae1dSRodney W. Grimes * SUCH DAMAGE. 37df8bae1dSRodney W. Grimes * 38df8bae1dSRodney W. Grimes * @(#)ufs_inode.c 8.4 (Berkeley) 1/21/94 39df8bae1dSRodney W. Grimes */ 40df8bae1dSRodney W. Grimes 41df8bae1dSRodney W. Grimes #include <sys/param.h> 42df8bae1dSRodney W. Grimes #include <sys/systm.h> 43df8bae1dSRodney W. Grimes #include <sys/proc.h> 44df8bae1dSRodney W. Grimes #include <sys/vnode.h> 45df8bae1dSRodney W. Grimes #include <sys/mount.h> 46df8bae1dSRodney W. Grimes #include <sys/kernel.h> 47df8bae1dSRodney W. Grimes #include <sys/malloc.h> 48df8bae1dSRodney W. Grimes 49df8bae1dSRodney W. Grimes #include <ufs/ufs/quota.h> 50df8bae1dSRodney W. Grimes #include <ufs/ufs/inode.h> 51df8bae1dSRodney W. Grimes #include <ufs/ufs/ufsmount.h> 52df8bae1dSRodney W. Grimes #include <ufs/ufs/ufs_extern.h> 53df8bae1dSRodney W. Grimes 54df8bae1dSRodney W. Grimes u_long nextgennumber; /* Next generation number to assign. */ 55df8bae1dSRodney W. Grimes int prtactive = 0; /* 1 => print out reclaim of active vnodes */ 56df8bae1dSRodney W. Grimes 57df8bae1dSRodney W. Grimes int 58df8bae1dSRodney W. Grimes ufs_init() 59df8bae1dSRodney W. Grimes { 60df8bae1dSRodney W. Grimes static int first = 1; 61df8bae1dSRodney W. Grimes 62df8bae1dSRodney W. Grimes if (!first) 63df8bae1dSRodney W. Grimes return (0); 64df8bae1dSRodney W. Grimes first = 0; 65df8bae1dSRodney W. Grimes 66df8bae1dSRodney W. Grimes #ifdef DIAGNOSTIC 67df8bae1dSRodney W. Grimes if ((sizeof(struct inode) - 1) & sizeof(struct inode)) 68df8bae1dSRodney W. Grimes printf("ufs_init: bad size %d\n", sizeof(struct inode)); 69df8bae1dSRodney W. Grimes #endif 70df8bae1dSRodney W. Grimes ufs_ihashinit(); 71df8bae1dSRodney W. Grimes dqinit(); 72df8bae1dSRodney W. Grimes return (0); 73df8bae1dSRodney W. Grimes } 74df8bae1dSRodney W. Grimes 75df8bae1dSRodney W. Grimes /* 76df8bae1dSRodney W. Grimes * Last reference to an inode. If necessary, write or delete it. 77df8bae1dSRodney W. Grimes */ 78df8bae1dSRodney W. Grimes int 79df8bae1dSRodney W. Grimes ufs_inactive(ap) 80df8bae1dSRodney W. Grimes struct vop_inactive_args /* { 81df8bae1dSRodney W. Grimes struct vnode *a_vp; 82df8bae1dSRodney W. Grimes } */ *ap; 83df8bae1dSRodney W. Grimes { 84df8bae1dSRodney W. Grimes register struct vnode *vp = ap->a_vp; 85df8bae1dSRodney W. Grimes register struct inode *ip = VTOI(vp); 86df8bae1dSRodney W. Grimes struct timeval tv; 87df8bae1dSRodney W. Grimes int mode, error; 88df8bae1dSRodney W. Grimes extern int prtactive; 89df8bae1dSRodney W. Grimes 90df8bae1dSRodney W. Grimes if (prtactive && vp->v_usecount != 0) 91df8bae1dSRodney W. Grimes vprint("ffs_inactive: pushing active", vp); 92df8bae1dSRodney W. Grimes 93df8bae1dSRodney W. Grimes /* Get rid of inodes related to stale file handles. */ 94df8bae1dSRodney W. Grimes if (ip->i_mode == 0) { 95df8bae1dSRodney W. Grimes if ((vp->v_flag & VXLOCK) == 0) 96df8bae1dSRodney W. Grimes vgone(vp); 97df8bae1dSRodney W. Grimes return (0); 98df8bae1dSRodney W. Grimes } 99df8bae1dSRodney W. Grimes 100df8bae1dSRodney W. Grimes error = 0; 101df8bae1dSRodney W. Grimes #ifdef DIAGNOSTIC 102df8bae1dSRodney W. Grimes if (VOP_ISLOCKED(vp)) 103df8bae1dSRodney W. Grimes panic("ffs_inactive: locked inode"); 104df8bae1dSRodney W. Grimes if (curproc) 105df8bae1dSRodney W. Grimes ip->i_lockholder = curproc->p_pid; 106df8bae1dSRodney W. Grimes else 107df8bae1dSRodney W. Grimes ip->i_lockholder = -1; 108df8bae1dSRodney W. Grimes #endif 109df8bae1dSRodney W. Grimes ip->i_flag |= IN_LOCKED; 110df8bae1dSRodney W. Grimes if (ip->i_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { 111df8bae1dSRodney W. Grimes #ifdef QUOTA 112df8bae1dSRodney W. Grimes if (!getinoquota(ip)) 113df8bae1dSRodney W. Grimes (void)chkiq(ip, -1, NOCRED, 0); 114df8bae1dSRodney W. Grimes #endif 115df8bae1dSRodney W. Grimes error = VOP_TRUNCATE(vp, (off_t)0, 0, NOCRED, NULL); 116df8bae1dSRodney W. Grimes ip->i_rdev = 0; 117df8bae1dSRodney W. Grimes mode = ip->i_mode; 118df8bae1dSRodney W. Grimes ip->i_mode = 0; 119df8bae1dSRodney W. Grimes ip->i_flag |= IN_CHANGE | IN_UPDATE; 120df8bae1dSRodney W. Grimes VOP_VFREE(vp, ip->i_number, mode); 121df8bae1dSRodney W. Grimes } 122df8bae1dSRodney W. Grimes if (ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) { 123df8bae1dSRodney W. Grimes tv = time; 124df8bae1dSRodney W. Grimes VOP_UPDATE(vp, &tv, &tv, 0); 125df8bae1dSRodney W. Grimes } 126df8bae1dSRodney W. Grimes VOP_UNLOCK(vp); 127df8bae1dSRodney W. Grimes /* 128df8bae1dSRodney W. Grimes * If we are done with the inode, reclaim it 129df8bae1dSRodney W. Grimes * so that it can be reused immediately. 130df8bae1dSRodney W. Grimes */ 131df8bae1dSRodney W. Grimes if (vp->v_usecount == 0 && ip->i_mode == 0) 132df8bae1dSRodney W. Grimes vgone(vp); 133df8bae1dSRodney W. Grimes return (error); 134df8bae1dSRodney W. Grimes } 135df8bae1dSRodney W. Grimes 136df8bae1dSRodney W. Grimes /* 137df8bae1dSRodney W. Grimes * Reclaim an inode so that it can be used for other purposes. 138df8bae1dSRodney W. Grimes */ 139df8bae1dSRodney W. Grimes int 140df8bae1dSRodney W. Grimes ufs_reclaim(ap) 141df8bae1dSRodney W. Grimes struct vop_reclaim_args /* { 142df8bae1dSRodney W. Grimes struct vnode *a_vp; 143df8bae1dSRodney W. Grimes } */ *ap; 144df8bae1dSRodney W. Grimes { 145df8bae1dSRodney W. Grimes register struct vnode *vp = ap->a_vp; 146df8bae1dSRodney W. Grimes register struct inode *ip; 147df8bae1dSRodney W. Grimes int i, type; 148df8bae1dSRodney W. Grimes 149df8bae1dSRodney W. Grimes if (prtactive && vp->v_usecount != 0) 150df8bae1dSRodney W. Grimes vprint("ufs_reclaim: pushing active", vp); 151df8bae1dSRodney W. Grimes /* 152df8bae1dSRodney W. Grimes * Remove the inode from its hash chain. 153df8bae1dSRodney W. Grimes */ 154df8bae1dSRodney W. Grimes ip = VTOI(vp); 155df8bae1dSRodney W. Grimes ufs_ihashrem(ip); 156df8bae1dSRodney W. Grimes /* 157df8bae1dSRodney W. Grimes * Purge old data structures associated with the inode. 158df8bae1dSRodney W. Grimes */ 159df8bae1dSRodney W. Grimes cache_purge(vp); 160df8bae1dSRodney W. Grimes if (ip->i_devvp) { 161df8bae1dSRodney W. Grimes vrele(ip->i_devvp); 162df8bae1dSRodney W. Grimes ip->i_devvp = 0; 163df8bae1dSRodney W. Grimes } 164df8bae1dSRodney W. Grimes #ifdef QUOTA 165df8bae1dSRodney W. Grimes for (i = 0; i < MAXQUOTAS; i++) { 166df8bae1dSRodney W. Grimes if (ip->i_dquot[i] != NODQUOT) { 167df8bae1dSRodney W. Grimes dqrele(vp, ip->i_dquot[i]); 168df8bae1dSRodney W. Grimes ip->i_dquot[i] = NODQUOT; 169df8bae1dSRodney W. Grimes } 170df8bae1dSRodney W. Grimes } 171df8bae1dSRodney W. Grimes #endif 172df8bae1dSRodney W. Grimes switch (vp->v_mount->mnt_stat.f_type) { 173df8bae1dSRodney W. Grimes case MOUNT_UFS: 174df8bae1dSRodney W. Grimes type = M_FFSNODE; 175df8bae1dSRodney W. Grimes break; 176df8bae1dSRodney W. Grimes case MOUNT_MFS: 177df8bae1dSRodney W. Grimes type = M_MFSNODE; 178df8bae1dSRodney W. Grimes break; 179df8bae1dSRodney W. Grimes case MOUNT_LFS: 180df8bae1dSRodney W. Grimes type = M_LFSNODE; 181df8bae1dSRodney W. Grimes break; 182df8bae1dSRodney W. Grimes default: 183df8bae1dSRodney W. Grimes panic("ufs_reclaim: not ufs file"); 184df8bae1dSRodney W. Grimes } 185df8bae1dSRodney W. Grimes FREE(vp->v_data, type); 186df8bae1dSRodney W. Grimes vp->v_data = NULL; 187df8bae1dSRodney W. Grimes return (0); 188df8bae1dSRodney W. Grimes } 189