123399Smckusick /* 2*63376Sbostic * Copyright (c) 1991, 1993 3*63376Sbostic * The Regents of the University of California. All rights reserved. 423399Smckusick * 544537Sbostic * %sccs.include.redist.c% 637736Smckusick * 7*63376Sbostic * @(#)ufs_inode.c 8.1 (Berkeley) 06/11/93 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 /* 4556746Smckusick * Last reference to an inode, write the inode out and if necessary, 4656746Smckusick * truncate and deallocate the file. 4756746Smckusick */ 4856746Smckusick int 4956746Smckusick ufs_inactive(ap) 5056746Smckusick struct vop_inactive_args /* { 5156746Smckusick struct vnode *a_vp; 5256746Smckusick } */ *ap; 5356746Smckusick { 5456746Smckusick register struct vnode *vp = ap->a_vp; 5556746Smckusick register struct inode *ip = VTOI(vp); 5656746Smckusick struct timeval tv; 5756746Smckusick int mode, error; 5856746Smckusick extern int prtactive; 5956746Smckusick 6056746Smckusick if (prtactive && vp->v_usecount != 0) 6156746Smckusick vprint("ffs_inactive: pushing active", vp); 6256746Smckusick 6356746Smckusick /* Get rid of inodes related to stale file handles. */ 6456746Smckusick if (ip->i_mode == 0) { 6556746Smckusick if ((vp->v_flag & VXLOCK) == 0) 6656746Smckusick vgone(vp); 6756746Smckusick return (0); 6856746Smckusick } 6956746Smckusick 7056746Smckusick error = 0; 7156746Smckusick #ifdef DIAGNOSTIC 7256746Smckusick if (VOP_ISLOCKED(vp)) 7356746Smckusick panic("ffs_inactive: locked inode"); 7457052Smckusick if (curproc) 7557052Smckusick ip->i_lockholder = curproc->p_pid; 7657052Smckusick else 7757052Smckusick ip->i_lockholder = -1; 7856746Smckusick #endif 7956746Smckusick ip->i_flag |= ILOCKED; 8056746Smckusick if (ip->i_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { 8156746Smckusick #ifdef QUOTA 8256746Smckusick if (!getinoquota(ip)) 8356746Smckusick (void)chkiq(ip, -1, NOCRED, 0); 8456746Smckusick #endif 8556746Smckusick error = VOP_TRUNCATE(vp, (off_t)0, 0, NOCRED, NULL); 8656746Smckusick mode = ip->i_mode; 8756746Smckusick ip->i_mode = 0; 8856746Smckusick ip->i_rdev = 0; 8956746Smckusick ip->i_flag |= IUPD|ICHG; 9056746Smckusick VOP_VFREE(vp, ip->i_number, mode); 9156746Smckusick } 9256746Smckusick if (ip->i_flag&(IUPD|IACC|ICHG|IMOD)) { 9356746Smckusick tv = time; 9456746Smckusick VOP_UPDATE(vp, &tv, &tv, 0); 9556746Smckusick } 9656746Smckusick VOP_UNLOCK(vp); 9756746Smckusick /* 9856746Smckusick * If we are done with the inode, reclaim it 9956746Smckusick * so that it can be reused immediately. 10056746Smckusick */ 10156746Smckusick if (vp->v_usecount == 0 && ip->i_mode == 0) 10256746Smckusick vgone(vp); 10356746Smckusick return (error); 10456746Smckusick } 10556746Smckusick 10656746Smckusick /* 10739392Smckusick * Reclaim an inode so that it can be used for other purposes. 10824Sbill */ 10951509Sbostic int 11054648Smckusick ufs_reclaim(ap) 11154648Smckusick struct vop_reclaim_args /* { 11254648Smckusick struct vnode *a_vp; 11354648Smckusick } */ *ap; 11439392Smckusick { 11553864Sheideman register struct vnode *vp = ap->a_vp; 11651509Sbostic register struct inode *ip; 11751987Smckusick int i, type; 11839392Smckusick 11953864Sheideman if (prtactive && vp->v_usecount != 0) 12053864Sheideman vprint("ufs_reclaim: pushing active", vp); 12139392Smckusick /* 12239392Smckusick * Remove the inode from its hash chain. 12339392Smckusick */ 12453864Sheideman ip = VTOI(vp); 12555413Smckusick ufs_ihashrem(ip); 12639392Smckusick /* 12739392Smckusick * Purge old data structures associated with the inode. 12839392Smckusick */ 12953864Sheideman cache_purge(vp); 13039392Smckusick if (ip->i_devvp) { 13139392Smckusick vrele(ip->i_devvp); 13239392Smckusick ip->i_devvp = 0; 13339392Smckusick } 13439392Smckusick #ifdef QUOTA 13541313Smckusick for (i = 0; i < MAXQUOTAS; i++) { 13641313Smckusick if (ip->i_dquot[i] != NODQUOT) { 13753864Sheideman dqrele(vp, ip->i_dquot[i]); 13841313Smckusick ip->i_dquot[i] = NODQUOT; 13941313Smckusick } 14041313Smckusick } 14139392Smckusick #endif 14253864Sheideman switch (vp->v_mount->mnt_stat.f_type) { 14351987Smckusick case MOUNT_UFS: 14451987Smckusick type = M_FFSNODE; 14551987Smckusick break; 14651987Smckusick case MOUNT_MFS: 14751987Smckusick type = M_MFSNODE; 14851987Smckusick break; 14951987Smckusick case MOUNT_LFS: 15051987Smckusick type = M_LFSNODE; 15151987Smckusick break; 15251987Smckusick default: 15351987Smckusick panic("ufs_reclaim: not ufs file"); 15451987Smckusick } 15553864Sheideman FREE(vp->v_data, type); 15653864Sheideman vp->v_data = NULL; 15739392Smckusick return (0); 15839392Smckusick } 159