- register int i, x;
- register struct inode *jp;
- int mode;
-
- if (ip->i_count == 1) {
- ip->i_flag |= ILOCK;
- if (ip->i_nlink <= 0) {
- itrunc(ip);
- mode = ip->i_mode;
- ip->i_mode = 0;
- ip->i_flag |= IUPD|ICHG;
- ifree(ip, ip->i_number, mode);
- }
- IUPDAT(ip, &time, &time, 0);
- iunlock(ip);
- i = INOHASH(ip->i_dev, ip->i_number);
- x = ip - inode;
- if (inohash[i] == x) {
- inohash[i] = ip->i_hlink;
- } else {
- for (jp = &inode[inohash[i]]; jp != &inode[-1];
- jp = &inode[jp->i_hlink])
- if (jp->i_hlink == x) {
- jp->i_hlink = ip->i_hlink;
- goto done;
- }
- panic("iput");
+ register struct inode *ip = VTOI(vp);
+ int mode, error = 0;
+
+ if (prtactive && vp->v_usecount != 0)
+ vprint("ufs_inactive: pushing active", vp);
+ /*
+ * Get rid of inodes related to stale file handles.
+ */
+ if (ip->i_mode == 0) {
+ if ((vp->v_flag & VXLOCK) == 0)
+ vgone(vp);
+ return (0);
+ }
+ ILOCK(ip);
+ if (ip->i_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
+#ifdef QUOTA
+ if (!getinoquota(ip))
+ (void) chkiq(ip, -1, NOCRED, 0);
+#endif
+ error = itrunc(ip, (u_long)0, 0);
+ mode = ip->i_mode;
+ ip->i_mode = 0;
+ ip->i_rdev = 0;
+ ip->i_flag |= IUPD|ICHG;
+ ifree(ip, ip->i_number, mode);
+ }
+ IUPDAT(ip, &time, &time, 0);
+ IUNLOCK(ip);
+ ip->i_flag = 0;
+ /*
+ * If we are done with the inode, reclaim it
+ * so that it can be reused immediately.
+ */
+ if (vp->v_usecount == 0 && ip->i_mode == 0)
+ vgone(vp);
+ return (error);
+}
+
+/*
+ * Reclaim an inode so that it can be used for other purposes.
+ */
+ufs_reclaim(vp)
+ register struct vnode *vp;
+{
+ register struct inode *ip = VTOI(vp);
+ int i;
+
+ if (prtactive && vp->v_usecount != 0)
+ vprint("ufs_reclaim: pushing active", vp);
+ /*
+ * Remove the inode from its hash chain.
+ */
+ remque(ip);
+ ip->i_forw = ip;
+ ip->i_back = ip;
+ /*
+ * Purge old data structures associated with the inode.
+ */
+ cache_purge(vp);
+ if (ip->i_devvp) {
+ vrele(ip->i_devvp);
+ ip->i_devvp = 0;
+ }
+#ifdef QUOTA
+ for (i = 0; i < MAXQUOTAS; i++) {
+ if (ip->i_dquot[i] != NODQUOT) {
+ dqrele(vp, ip->i_dquot[i]);
+ ip->i_dquot[i] = NODQUOT;