123399Smckusick /* 251509Sbostic * Copyright (c) 1991 Regents of the University of California. 337736Smckusick * All rights reserved. 423399Smckusick * 544537Sbostic * %sccs.include.redist.c% 637736Smckusick * 7*51547Smckusick * @(#)ufs_inode.c 7.42 (Berkeley) 11/05/91 823399Smckusick */ 924Sbill 1051509Sbostic #include <sys/param.h> 1151509Sbostic #include <sys/systm.h> 1251509Sbostic #include <sys/proc.h> 1351509Sbostic #include <sys/vnode.h> 1451509Sbostic #include <sys/mount.h> 1551509Sbostic #include <sys/kernel.h> 1624Sbill 1751509Sbostic #include <ufs/ufs/quota.h> 1851509Sbostic #include <ufs/ufs/inode.h> 1951509Sbostic #include <ufs/ufs/ufsmount.h> 2051509Sbostic #include <ufs/ufs/ufs_extern.h> 2147571Skarels 2251509Sbostic u_long nextgennumber; /* Next generation number to assign. */ 23*51547Smckusick int prtactive = 0; /* 1 => print out reclaim of active vnodes */ 2424Sbill 2551509Sbostic int 2639440Smckusick ufs_init() 2724Sbill { 2851509Sbostic static int first = 1; 2924Sbill 3051509Sbostic if (!first) 3151509Sbostic return (0); 3251509Sbostic first = 0; 3351509Sbostic 3451509Sbostic #ifdef DIAGNOSTIC 3539392Smckusick if (VN_MAXPRIVATE < sizeof(struct inode)) 3651509Sbostic panic("ufs_init: inode too small"); 3751509Sbostic #endif 3851509Sbostic ufs_ihashinit(); 3941313Smckusick dqinit(); 4037736Smckusick return (0); 4137736Smckusick } 427334Skre 4337736Smckusick /* 4439392Smckusick * Unlock and decrement the reference count of an inode structure. 4524Sbill */ 4651509Sbostic void 4751509Sbostic ufs_iput(ip) 484818Swnj register struct inode *ip; 4924Sbill { 507118Smckusick 518452Sroot if ((ip->i_flag & ILOCKED) == 0) 527118Smckusick panic("iput"); 5316665Smckusick IUNLOCK(ip); 5437736Smckusick vrele(ITOV(ip)); 557118Smckusick } 567118Smckusick 5739392Smckusick /* 5839392Smckusick * Reclaim an inode so that it can be used for other purposes. 5924Sbill */ 6051509Sbostic int 6139392Smckusick ufs_reclaim(vp) 6239392Smckusick register struct vnode *vp; 6339392Smckusick { 6451509Sbostic register struct inode *ip; 6541313Smckusick int i; 6639392Smckusick 6739816Smckusick if (prtactive && vp->v_usecount != 0) 6839676Smckusick vprint("ufs_reclaim: pushing active", vp); 6939392Smckusick /* 7039392Smckusick * Remove the inode from its hash chain. 7139392Smckusick */ 7251509Sbostic ip = VTOI(vp); 7339392Smckusick remque(ip); 7439392Smckusick ip->i_forw = ip; 7539392Smckusick ip->i_back = ip; 7639392Smckusick /* 7739392Smckusick * Purge old data structures associated with the inode. 7839392Smckusick */ 7939392Smckusick cache_purge(vp); 8039392Smckusick if (ip->i_devvp) { 8139392Smckusick vrele(ip->i_devvp); 8239392Smckusick ip->i_devvp = 0; 8339392Smckusick } 8439392Smckusick #ifdef QUOTA 8541313Smckusick for (i = 0; i < MAXQUOTAS; i++) { 8641313Smckusick if (ip->i_dquot[i] != NODQUOT) { 8741313Smckusick dqrele(vp, ip->i_dquot[i]); 8841313Smckusick ip->i_dquot[i] = NODQUOT; 8941313Smckusick } 9041313Smckusick } 9139392Smckusick #endif 9239392Smckusick ip->i_flag = 0; 9339392Smckusick return (0); 9439392Smckusick } 9539392Smckusick 9639392Smckusick /* 974818Swnj * Lock an inode. If its already locked, set the WANT bit and sleep. 983617Sroot */ 9951509Sbostic void 10051509Sbostic ufs_ilock(ip) 1014818Swnj register struct inode *ip; 1023617Sroot { 1033617Sroot 10437736Smckusick while (ip->i_flag & ILOCKED) { 10537736Smckusick ip->i_flag |= IWANT; 10647571Skarels if (ip->i_spare0 == curproc->p_pid) 10739795Smckusick panic("locking against myself"); 10847571Skarels ip->i_spare1 = curproc->p_pid; 10937736Smckusick (void) sleep((caddr_t)ip, PINOD); 11037736Smckusick } 11139795Smckusick ip->i_spare1 = 0; 11247571Skarels ip->i_spare0 = curproc->p_pid; 11337736Smckusick ip->i_flag |= ILOCKED; 1143617Sroot } 1153617Sroot 1163617Sroot /* 1174818Swnj * Unlock an inode. If WANT bit is on, wakeup. 1183617Sroot */ 11951509Sbostic void 12051509Sbostic ufs_iunlock(ip) 1214818Swnj register struct inode *ip; 1223617Sroot { 1233617Sroot 12437736Smckusick if ((ip->i_flag & ILOCKED) == 0) 12551509Sbostic vprint("ufs_iunlock: unlocked inode", ITOV(ip)); 12639795Smckusick ip->i_spare0 = 0; 12737736Smckusick ip->i_flag &= ~ILOCKED; 12837736Smckusick if (ip->i_flag&IWANT) { 12937736Smckusick ip->i_flag &= ~IWANT; 13037736Smckusick wakeup((caddr_t)ip); 13137736Smckusick } 1323617Sroot } 133