1 /* 2 * Copyright (c) 1991 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)ufs_inode.c 7.47 (Berkeley) 06/04/92 8 */ 9 10 #include <sys/param.h> 11 #include <sys/systm.h> 12 #include <sys/proc.h> 13 #include <sys/vnode.h> 14 #include <sys/mount.h> 15 #include <sys/kernel.h> 16 #include <sys/malloc.h> 17 18 #include <ufs/ufs/quota.h> 19 #include <ufs/ufs/inode.h> 20 #include <ufs/ufs/ufsmount.h> 21 #include <ufs/ufs/ufs_extern.h> 22 23 u_long nextgennumber; /* Next generation number to assign. */ 24 int prtactive = 0; /* 1 => print out reclaim of active vnodes */ 25 26 int 27 ufs_init() 28 { 29 static int first = 1; 30 31 if (!first) 32 return (0); 33 first = 0; 34 35 #ifdef DIAGNOSTIC 36 if ((sizeof(struct inode) - 1) & sizeof(struct inode)) 37 printf("ufs_init: bad size %d\n", sizeof(struct inode)); 38 #endif 39 ufs_ihashinit(); 40 dqinit(); 41 return (0); 42 } 43 44 /* 45 * Unlock and decrement the reference count of an inode structure. 46 */ 47 void 48 ufs_iput(ip) 49 register struct inode *ip; 50 { 51 52 if ((ip->i_flag & ILOCKED) == 0) 53 panic("iput"); 54 IUNLOCK(ip); 55 vrele(ITOV(ip)); 56 } 57 58 /* 59 * Reclaim an inode so that it can be used for other purposes. 60 */ 61 int 62 ufs_reclaim (ap) 63 struct vop_reclaim_args *ap; 64 { 65 register struct vnode *vp = ap->a_vp; 66 register struct inode *ip; 67 int i, type; 68 69 if (prtactive && vp->v_usecount != 0) 70 vprint("ufs_reclaim: pushing active", vp); 71 /* 72 * Remove the inode from its hash chain. 73 */ 74 ip = VTOI(vp); 75 remque(ip); 76 /* 77 * Purge old data structures associated with the inode. 78 */ 79 cache_purge(vp); 80 if (ip->i_devvp) { 81 vrele(ip->i_devvp); 82 ip->i_devvp = 0; 83 } 84 #ifdef QUOTA 85 for (i = 0; i < MAXQUOTAS; i++) { 86 if (ip->i_dquot[i] != NODQUOT) { 87 dqrele(vp, ip->i_dquot[i]); 88 ip->i_dquot[i] = NODQUOT; 89 } 90 } 91 #endif 92 switch (vp->v_mount->mnt_stat.f_type) { 93 case MOUNT_UFS: 94 type = M_FFSNODE; 95 break; 96 case MOUNT_MFS: 97 type = M_MFSNODE; 98 break; 99 case MOUNT_LFS: 100 type = M_LFSNODE; 101 break; 102 default: 103 panic("ufs_reclaim: not ufs file"); 104 } 105 FREE(vp->v_data, type); 106 vp->v_data = NULL; 107 return (0); 108 } 109 110 /* 111 * Lock an inode. If its already locked, set the WANT bit and sleep. 112 */ 113 void 114 ufs_ilock(ip) 115 register struct inode *ip; 116 { 117 struct proc *p = curproc; /* XXX */ 118 119 while (ip->i_flag & ILOCKED) { 120 ip->i_flag |= IWANT; 121 #ifdef DIAGNOSTIC 122 if (p) { 123 if (p->p_pid == ip->i_lockholder) 124 panic("locking against myself"); 125 ip->i_lockwaiter = p->p_pid; 126 } 127 #endif 128 (void) sleep((caddr_t)ip, PINOD); 129 } 130 #ifdef DIAGNOSTIC 131 ip->i_lockwaiter = 0; 132 if (p) 133 ip->i_lockholder = p->p_pid; 134 #endif 135 ip->i_flag |= ILOCKED; 136 } 137 138 /* 139 * Unlock an inode. If WANT bit is on, wakeup. 140 */ 141 void 142 ufs_iunlock(ip) 143 register struct inode *ip; 144 { 145 146 if ((ip->i_flag & ILOCKED) == 0) 147 vprint("ufs_iunlock: unlocked inode", ITOV(ip)); 148 #ifdef DIAGNOSTIC 149 ip->i_lockholder = 0; 150 #endif 151 ip->i_flag &= ~ILOCKED; 152 if (ip->i_flag&IWANT) { 153 ip->i_flag &= ~IWANT; 154 wakeup((caddr_t)ip); 155 } 156 } 157