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