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.48 (Berkeley) 07/03/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 /* { 64 struct vnode *a_vp; 65 } */ *ap; 66 { 67 register struct vnode *vp = ap->a_vp; 68 register struct inode *ip; 69 int i, type; 70 71 if (prtactive && vp->v_usecount != 0) 72 vprint("ufs_reclaim: pushing active", vp); 73 /* 74 * Remove the inode from its hash chain. 75 */ 76 ip = VTOI(vp); 77 remque(ip); 78 /* 79 * Purge old data structures associated with the inode. 80 */ 81 cache_purge(vp); 82 if (ip->i_devvp) { 83 vrele(ip->i_devvp); 84 ip->i_devvp = 0; 85 } 86 #ifdef QUOTA 87 for (i = 0; i < MAXQUOTAS; i++) { 88 if (ip->i_dquot[i] != NODQUOT) { 89 dqrele(vp, ip->i_dquot[i]); 90 ip->i_dquot[i] = NODQUOT; 91 } 92 } 93 #endif 94 switch (vp->v_mount->mnt_stat.f_type) { 95 case MOUNT_UFS: 96 type = M_FFSNODE; 97 break; 98 case MOUNT_MFS: 99 type = M_MFSNODE; 100 break; 101 case MOUNT_LFS: 102 type = M_LFSNODE; 103 break; 104 default: 105 panic("ufs_reclaim: not ufs file"); 106 } 107 FREE(vp->v_data, type); 108 vp->v_data = NULL; 109 return (0); 110 } 111 112 /* 113 * Lock an inode. If its already locked, set the WANT bit and sleep. 114 */ 115 void 116 ufs_ilock(ip) 117 register struct inode *ip; 118 { 119 struct proc *p = curproc; /* XXX */ 120 121 while (ip->i_flag & ILOCKED) { 122 ip->i_flag |= IWANT; 123 #ifdef DIAGNOSTIC 124 if (p) { 125 if (p->p_pid == ip->i_lockholder) 126 panic("locking against myself"); 127 ip->i_lockwaiter = p->p_pid; 128 } 129 #endif 130 (void) sleep((caddr_t)ip, PINOD); 131 } 132 #ifdef DIAGNOSTIC 133 ip->i_lockwaiter = 0; 134 if (p) 135 ip->i_lockholder = p->p_pid; 136 #endif 137 ip->i_flag |= ILOCKED; 138 } 139 140 /* 141 * Unlock an inode. If WANT bit is on, wakeup. 142 */ 143 void 144 ufs_iunlock(ip) 145 register struct inode *ip; 146 { 147 148 if ((ip->i_flag & ILOCKED) == 0) 149 vprint("ufs_iunlock: unlocked inode", ITOV(ip)); 150 #ifdef DIAGNOSTIC 151 ip->i_lockholder = 0; 152 #endif 153 ip->i_flag &= ~ILOCKED; 154 if (ip->i_flag&IWANT) { 155 ip->i_flag &= ~IWANT; 156 wakeup((caddr_t)ip); 157 } 158 } 159