123399Smckusick /* 251509Sbostic * Copyright (c) 1991 Regents of the University of California. 337736Smckusick * All rights reserved. 423399Smckusick * 544537Sbostic * %sccs.include.redist.c% 637736Smckusick * 7*55413Smckusick * @(#)ufs_inode.c 7.49 (Berkeley) 07/20/92 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> 1651987Smckusick #include <sys/malloc.h> 1724Sbill 1851509Sbostic #include <ufs/ufs/quota.h> 1951509Sbostic #include <ufs/ufs/inode.h> 2051509Sbostic #include <ufs/ufs/ufsmount.h> 2151509Sbostic #include <ufs/ufs/ufs_extern.h> 2247571Skarels 2351509Sbostic u_long nextgennumber; /* Next generation number to assign. */ 2451547Smckusick int prtactive = 0; /* 1 => print out reclaim of active vnodes */ 2524Sbill 2651509Sbostic int 2739440Smckusick ufs_init() 2824Sbill { 2951509Sbostic static int first = 1; 3024Sbill 3151509Sbostic if (!first) 3251509Sbostic return (0); 3351509Sbostic first = 0; 3451509Sbostic 3551509Sbostic #ifdef DIAGNOSTIC 3651987Smckusick if ((sizeof(struct inode) - 1) & sizeof(struct inode)) 3751987Smckusick printf("ufs_init: bad size %d\n", sizeof(struct inode)); 3851509Sbostic #endif 3951509Sbostic ufs_ihashinit(); 4041313Smckusick dqinit(); 4137736Smckusick return (0); 4237736Smckusick } 437334Skre 4437736Smckusick /* 4539392Smckusick * Unlock and decrement the reference count of an inode structure. 4624Sbill */ 4751509Sbostic void 4851509Sbostic ufs_iput(ip) 494818Swnj register struct inode *ip; 5024Sbill { 517118Smckusick 528452Sroot if ((ip->i_flag & ILOCKED) == 0) 537118Smckusick panic("iput"); 5416665Smckusick IUNLOCK(ip); 5537736Smckusick vrele(ITOV(ip)); 567118Smckusick } 577118Smckusick 5839392Smckusick /* 5939392Smckusick * Reclaim an inode so that it can be used for other purposes. 6024Sbill */ 6151509Sbostic int 6254648Smckusick ufs_reclaim(ap) 6354648Smckusick struct vop_reclaim_args /* { 6454648Smckusick struct vnode *a_vp; 6554648Smckusick } */ *ap; 6639392Smckusick { 6753864Sheideman register struct vnode *vp = ap->a_vp; 6851509Sbostic register struct inode *ip; 6951987Smckusick int i, type; 7039392Smckusick 7153864Sheideman if (prtactive && vp->v_usecount != 0) 7253864Sheideman vprint("ufs_reclaim: pushing active", vp); 7339392Smckusick /* 7439392Smckusick * Remove the inode from its hash chain. 7539392Smckusick */ 7653864Sheideman ip = VTOI(vp); 77*55413Smckusick ufs_ihashrem(ip); 7839392Smckusick /* 7939392Smckusick * Purge old data structures associated with the inode. 8039392Smckusick */ 8153864Sheideman cache_purge(vp); 8239392Smckusick if (ip->i_devvp) { 8339392Smckusick vrele(ip->i_devvp); 8439392Smckusick ip->i_devvp = 0; 8539392Smckusick } 8639392Smckusick #ifdef QUOTA 8741313Smckusick for (i = 0; i < MAXQUOTAS; i++) { 8841313Smckusick if (ip->i_dquot[i] != NODQUOT) { 8953864Sheideman dqrele(vp, ip->i_dquot[i]); 9041313Smckusick ip->i_dquot[i] = NODQUOT; 9141313Smckusick } 9241313Smckusick } 9339392Smckusick #endif 9453864Sheideman switch (vp->v_mount->mnt_stat.f_type) { 9551987Smckusick case MOUNT_UFS: 9651987Smckusick type = M_FFSNODE; 9751987Smckusick break; 9851987Smckusick case MOUNT_MFS: 9951987Smckusick type = M_MFSNODE; 10051987Smckusick break; 10151987Smckusick case MOUNT_LFS: 10251987Smckusick type = M_LFSNODE; 10351987Smckusick break; 10451987Smckusick default: 10551987Smckusick panic("ufs_reclaim: not ufs file"); 10651987Smckusick } 10753864Sheideman FREE(vp->v_data, type); 10853864Sheideman vp->v_data = NULL; 10939392Smckusick return (0); 11039392Smckusick } 11139392Smckusick 11239392Smckusick /* 1134818Swnj * Lock an inode. If its already locked, set the WANT bit and sleep. 1143617Sroot */ 11551509Sbostic void 11651509Sbostic ufs_ilock(ip) 1174818Swnj register struct inode *ip; 1183617Sroot { 11952037Smckusick struct proc *p = curproc; /* XXX */ 1203617Sroot 12137736Smckusick while (ip->i_flag & ILOCKED) { 12237736Smckusick ip->i_flag |= IWANT; 12352037Smckusick #ifdef DIAGNOSTIC 12452037Smckusick if (p) { 12552037Smckusick if (p->p_pid == ip->i_lockholder) 12652037Smckusick panic("locking against myself"); 12752037Smckusick ip->i_lockwaiter = p->p_pid; 12852037Smckusick } 12952037Smckusick #endif 13037736Smckusick (void) sleep((caddr_t)ip, PINOD); 13137736Smckusick } 13252037Smckusick #ifdef DIAGNOSTIC 13351987Smckusick ip->i_lockwaiter = 0; 13452037Smckusick if (p) 13552037Smckusick ip->i_lockholder = p->p_pid; 13652037Smckusick #endif 13737736Smckusick ip->i_flag |= ILOCKED; 1383617Sroot } 1393617Sroot 1403617Sroot /* 1414818Swnj * Unlock an inode. If WANT bit is on, wakeup. 1423617Sroot */ 14351509Sbostic void 14451509Sbostic ufs_iunlock(ip) 1454818Swnj register struct inode *ip; 1463617Sroot { 1473617Sroot 14837736Smckusick if ((ip->i_flag & ILOCKED) == 0) 14951509Sbostic vprint("ufs_iunlock: unlocked inode", ITOV(ip)); 15052037Smckusick #ifdef DIAGNOSTIC 15151987Smckusick ip->i_lockholder = 0; 15252037Smckusick #endif 15337736Smckusick ip->i_flag &= ~ILOCKED; 15437736Smckusick if (ip->i_flag&IWANT) { 15537736Smckusick ip->i_flag &= ~IWANT; 15637736Smckusick wakeup((caddr_t)ip); 15737736Smckusick } 1583617Sroot } 159