Annotation of sys/ufs/ufs/ufs_inode.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ufs_inode.c,v 1.37 2007/06/01 23:47:57 deraadt Exp $ */
2: /* $NetBSD: ufs_inode.c,v 1.7 1996/05/11 18:27:52 mycroft Exp $ */
3:
4: /*
5: * Copyright (c) 1991, 1993
6: * The Regents of the University of California. All rights reserved.
7: * (c) UNIX System Laboratories, Inc.
8: * All or some portions of this file are derived from material licensed
9: * to the University of California by American Telephone and Telegraph
10: * Co. or Unix System Laboratories, Inc. and are reproduced herein with
11: * the permission of UNIX System Laboratories, Inc.
12: *
13: * Redistribution and use in source and binary forms, with or without
14: * modification, are permitted provided that the following conditions
15: * are met:
16: * 1. Redistributions of source code must retain the above copyright
17: * notice, this list of conditions and the following disclaimer.
18: * 2. Redistributions in binary form must reproduce the above copyright
19: * notice, this list of conditions and the following disclaimer in the
20: * documentation and/or other materials provided with the distribution.
21: * 3. Neither the name of the University nor the names of its contributors
22: * may be used to endorse or promote products derived from this software
23: * without specific prior written permission.
24: *
25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35: * SUCH DAMAGE.
36: *
37: * @(#)ufs_inode.c 8.7 (Berkeley) 7/22/94
38: */
39:
40: #include <sys/param.h>
41: #include <sys/systm.h>
42: #include <sys/proc.h>
43: #include <sys/vnode.h>
44: #include <sys/mount.h>
45: #include <sys/kernel.h>
46: #include <sys/malloc.h>
47: #include <sys/namei.h>
48:
49: #include <ufs/ufs/quota.h>
50: #include <ufs/ufs/inode.h>
51: #include <ufs/ufs/ufsmount.h>
52: #include <ufs/ufs/ufs_extern.h>
53: #ifdef UFS_DIRHASH
54: #include <ufs/ufs/dir.h>
55: #include <ufs/ufs/dirhash.h>
56: #endif
57:
58: /*
59: * Last reference to an inode. If necessary, write or delete it.
60: */
61: int
62: ufs_inactive(void *v)
63: {
64: struct vop_inactive_args *ap = v;
65: struct vnode *vp = ap->a_vp;
66: struct inode *ip = VTOI(vp);
67: struct proc *p = ap->a_p;
68: mode_t mode;
69: int error = 0;
70: #ifdef DIAGNOSTIC
71: extern int prtactive;
72:
73: if (prtactive && vp->v_usecount != 0)
74: vprint("ffs_inactive: pushing active", vp);
75: #endif
76:
77: /*
78: * Ignore inodes related to stale file handles.
79: */
80: if (ip->i_din1 == NULL || DIP(ip, mode) == 0)
81: goto out;
82:
83: if (DIP(ip, nlink) <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
84: if (getinoquota(ip) == 0)
85: (void)ufs_quota_free_inode(ip, NOCRED);
86:
87: error = UFS_TRUNCATE(ip, (off_t)0, 0, NOCRED);
88:
89: DIP_ASSIGN(ip, rdev, 0);
90: mode = DIP(ip, mode);
91: DIP_ASSIGN(ip, mode, 0);
92: ip->i_flag |= IN_CHANGE | IN_UPDATE;
93:
94: /*
95: * Setting the mode to zero needs to wait for the inode to be
96: * written just as does a change to the link count. So, rather
97: * than creating a new entry point to do the same thing, we
98: * just use softdep_change_linkcnt(). Also, we can't let
99: * softdep co-opt us to help on its worklist, as we may end up
100: * trying to recycle vnodes and getting to this same point a
101: * couple of times, blowing the kernel stack. However, this
102: * could be optimized by checking if we are coming from
103: * vrele(), vput() or vclean() (by checking for VXLOCK) and
104: * just avoiding the co-opt to happen in the last case.
105: */
106: if (DOINGSOFTDEP(vp))
107: softdep_change_linkcnt(ip, 1);
108:
109: UFS_INODE_FREE(ip, ip->i_number, mode);
110: }
111:
112: if (ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) {
113: UFS_UPDATE(ip, 0);
114: }
115: out:
116: VOP_UNLOCK(vp, 0, p);
117:
118: /*
119: * If we are done with the inode, reclaim it
120: * so that it can be reused immediately.
121: */
122: if (ip->i_din1 == NULL || DIP(ip, mode) == 0)
123: vrecycle(vp, p);
124:
125: return (error);
126: }
127:
128: /*
129: * Reclaim an inode so that it can be used for other purposes.
130: */
131: int
132: ufs_reclaim(struct vnode *vp, struct proc *p)
133: {
134: struct inode *ip;
135: #ifdef DIAGNOSTIC
136: extern int prtactive;
137:
138: if (prtactive && vp->v_usecount != 0)
139: vprint("ufs_reclaim: pushing active", vp);
140: #endif
141:
142: /*
143: * Remove the inode from its hash chain.
144: */
145: ip = VTOI(vp);
146: ufs_ihashrem(ip);
147: /*
148: * Purge old data structures associated with the inode.
149: */
150: cache_purge(vp);
151:
152: if (ip->i_devvp) {
153: vrele(ip->i_devvp);
154: }
155: #ifdef UFS_DIRHASH
156: if (ip->i_dirhash != NULL)
157: ufsdirhash_free(ip);
158: #endif
159: ufs_quota_delete(ip);
160: return (0);
161: }
CVSweb