vm: remove leftover diag print
[minix.git] / servers / vfs / vnode.c
blob04b6a2869fe287d314855cadaf1d7ee001780fc2
1 /* This file contains the routines related to vnodes.
2 * The entry points are:
3 *
4 * get_vnode - increase counter and get details of an inode
5 * get_free_vnode - get a pointer to a free vnode obj
6 * find_vnode - find a vnode according to the FS endpoint and the inode num.
7 * dup_vnode - duplicate vnode (i.e. increase counter)
8 * put_vnode - drop vnode (i.e. decrease counter)
9 */
11 #include "fs.h"
12 #include "vnode.h"
13 #include "vmnt.h"
14 #include "fproc.h"
15 #include "file.h"
16 #include <minix/vfsif.h>
18 /* Is vnode pointer reasonable? */
19 #define SANEVP(v) ((((v) >= &vnode[0] && (v) < &vnode[NR_VNODES])))
21 #define BADVP(v, f, l) printf("%s:%d: bad vp 0x%x\n", f, l, v)
23 /* vp check that returns 0 for use in check_vrefs() */
24 #define CHECKVN(v) if(!SANEVP(v)) { \
25 BADVP(v, __FILE__, __LINE__); \
26 return 0; \
29 /* vp check that panics */
30 #define ASSERTVP(v) if(!SANEVP(v)) { \
31 BADVP(v, __FILE__, __LINE__); panic("bad vp"); }
33 /*===========================================================================*
34 * get_free_vnode *
35 *===========================================================================*/
36 PUBLIC struct vnode *get_free_vnode()
38 /* Find a free vnode slot in the vnode table (it's not actually allocated) */
39 struct vnode *vp;
41 for (vp = &vnode[0]; vp < &vnode[NR_VNODES]; ++vp) {
42 if (vp->v_ref_count == 0) {
43 vp->v_pipe = NO_PIPE;
44 vp->v_uid = -1;
45 vp->v_gid = -1;
46 vp->v_sdev = NO_DEV;
47 vp->v_mapfs_e = 0;
48 vp->v_mapinode_nr = 0;
49 return(vp);
53 err_code = ENFILE;
54 return(NIL_VNODE);
58 /*===========================================================================*
59 * find_vnode *
60 *===========================================================================*/
61 PUBLIC struct vnode *find_vnode(int fs_e, int numb)
63 /* Find a specified (FS endpoint and inode number) vnode in the
64 * vnode table */
65 struct vnode *vp;
67 for (vp = &vnode[0]; vp < &vnode[NR_VNODES]; ++vp)
68 if (vp->v_ref_count > 0 && vp->v_inode_nr == numb && vp->v_fs_e == fs_e)
69 return(vp);
71 return(NIL_VNODE);
75 /*===========================================================================*
76 * dup_vnode *
77 *===========================================================================*/
78 PUBLIC void dup_vnode(struct vnode *vp)
80 /* dup_vnode() is called to increment the vnode and therefore the
81 * referred inode's counter.
83 ASSERTVP(vp);
84 vp->v_ref_count++;
88 /*===========================================================================*
89 * put_vnode *
90 *===========================================================================*/
91 PUBLIC void put_vnode(struct vnode *vp)
93 /* Decrease vnode's usage counter and decrease inode's usage counter in the
94 * corresponding FS process. Decreasing the fs_count each time we decrease the
95 * ref count would lead to poor performance. Instead, only decrease fs_count
96 * when the ref count hits zero. However, this could lead to fs_count to wrap.
97 * To prevent this, we drop the counter to 1 when the counter hits 256.
98 * We maintain fs_count as a sanity check to make sure VFS and the FS are in
99 * sync.
101 ASSERTVP(vp);
103 if (vp->v_ref_count > 1) {
104 /* Decrease counter */
105 vp->v_ref_count--;
106 if (vp->v_fs_count > 256)
107 vnode_clean_refs(vp);
109 return;
112 /* A vnode that's not in use can't be put. */
113 if (vp->v_ref_count <= 0) {
114 printf("put_vnode: bad v_ref_count %d\n", vp->v_ref_count);
115 panic("put_vnode failed");
118 /* fs_count should indicate that the file is in use. */
119 if (vp->v_fs_count <= 0) {
120 printf("put_vnode: bad v_fs_count %d\n", vp->v_fs_count);
121 panic("put_vnode failed");
124 /* Tell FS we don't need this inode to be open anymore. */
125 req_putnode(vp->v_fs_e, vp->v_inode_nr, vp->v_fs_count);
127 /* This inode could've been mapped. If so, tell PFS to close it as well. */
128 if(vp->v_mapfs_e != 0 && vp->v_mapinode_nr != vp->v_inode_nr &&
129 vp->v_mapfs_e != vp->v_fs_e) {
130 req_putnode(vp->v_mapfs_e, vp->v_mapinode_nr, vp->v_mapfs_count);
133 vp->v_fs_count = 0;
134 vp->v_ref_count = 0;
135 vp->v_pipe = NO_PIPE;
136 vp->v_sdev = NO_DEV;
137 vp->v_mapfs_e = 0;
138 vp->v_mapinode_nr = 0;
139 vp->v_mapfs_count = 0;
143 /*===========================================================================*
144 * vnode_clean_refs *
145 *===========================================================================*/
146 PUBLIC void vnode_clean_refs(struct vnode *vp)
148 /* Tell the underlying FS to drop all reference but one. */
150 if (vp == NIL_VNODE) return;
151 if (vp->v_fs_count <= 1) return; /* Nothing to do */
153 /* Drop all references except one */
154 req_putnode(vp->v_fs_e, vp->v_inode_nr, vp->v_fs_count - 1);
155 vp->v_fs_count = 1;
159 #define REFVP(v) { vp = (v); CHECKVN(v); vp->v_ref_check++; }
161 #if DO_SANITYCHECKS
162 /*===========================================================================*
163 * check_vrefs *
164 *===========================================================================*/
165 PUBLIC int check_vrefs()
167 int i, bad;
168 int ispipe_flag, ispipe_mode;
169 struct vnode *vp;
170 struct vmnt *vmp;
171 struct fproc *rfp;
172 struct filp *f;
174 /* Clear v_ref_check */
175 for (vp = &vnode[0]; vp < &vnode[NR_VNODES]; ++vp)
176 vp->v_ref_check= 0;
178 /* Count reference for processes */
179 for (rfp=&fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
180 if (rfp->fp_pid == PID_FREE)
181 continue;
182 if(rfp->fp_rd) REFVP(rfp->fp_rd);
183 if(rfp->fp_wd) REFVP(rfp->fp_wd);
186 /* Count references from filedescriptors */
187 for (f = &filp[0]; f < &filp[NR_FILPS]; f++)
189 if (f->filp_count == 0)
190 continue;
191 REFVP(f->filp_vno);
194 /* Count references to mount points */
195 for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp)
197 if (vmp->m_dev == NO_DEV)
198 continue;
199 REFVP(vmp->m_root_node);
200 if(vmp->m_mounted_on)
201 REFVP(vmp->m_mounted_on);
204 /* Check references */
205 bad= 0;
206 for (vp = &vnode[0]; vp < &vnode[NR_VNODES]; ++vp)
208 if (vp->v_ref_count != vp->v_ref_check)
210 printf(
211 "Bad reference count for inode %d on device 0x%x: found %d, listed %d\n",
212 vp->v_inode_nr, vp->v_dev, vp->v_ref_check,
213 vp->v_ref_count);
214 printf("last marked at %s, %d\n",
215 vp->v_file, vp->v_line);
216 bad= 1;
219 /* Also check v_pipe */
220 if (vp->v_ref_count != 0)
222 ispipe_flag= (vp->v_pipe == I_PIPE);
223 ispipe_mode= ((vp->v_mode & I_TYPE) == I_NAMED_PIPE);
224 if (ispipe_flag != ispipe_mode)
226 printf(
227 "Bad v_pipe for inode %d on device 0x%x: found %d, mode 0%o\n",
228 vp->v_inode_nr, vp->v_dev, vp->v_pipe,
229 vp->v_mode);
230 printf("last marked at %s, %d\n",
231 vp->v_file, vp->v_line);
232 bad= 1;
236 return !bad;
238 #endif