Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
script3r
GitHub Repository: script3r/os161
Path: blob/master/kern/vfs/vnode.c
2093 views
1
/*
2
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
3
* The President and Fellows of Harvard College.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* 3. Neither the name of the University nor the names of its contributors
14
* may be used to endorse or promote products derived from this software
15
* without specific prior written permission.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
18
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
21
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
* SUCH DAMAGE.
28
*/
29
30
/*
31
* Basic vnode support functions.
32
*/
33
#include <types.h>
34
#include <kern/errno.h>
35
#include <lib.h>
36
#include <synch.h>
37
#include <vfs.h>
38
#include <vnode.h>
39
40
/*
41
* Initialize an abstract vnode.
42
* Invoked by VOP_INIT.
43
*/
44
int
45
vnode_init(struct vnode *vn, const struct vnode_ops *ops,
46
struct fs *fs, void *fsdata)
47
{
48
KASSERT(vn!=NULL);
49
KASSERT(ops!=NULL);
50
51
vn->vn_ops = ops;
52
vn->vn_refcount = 1;
53
vn->vn_opencount = 0;
54
vn->vn_fs = fs;
55
vn->vn_data = fsdata;
56
return 0;
57
}
58
59
/*
60
* Destroy an abstract vnode.
61
* Invoked by VOP_CLEANUP.
62
*/
63
void
64
vnode_cleanup(struct vnode *vn)
65
{
66
KASSERT(vn->vn_refcount==1);
67
KASSERT(vn->vn_opencount==0);
68
69
vn->vn_ops = NULL;
70
vn->vn_refcount = 0;
71
vn->vn_opencount = 0;
72
vn->vn_fs = NULL;
73
vn->vn_data = NULL;
74
}
75
76
77
/*
78
* Increment refcount.
79
* Called by VOP_INCREF.
80
*/
81
void
82
vnode_incref(struct vnode *vn)
83
{
84
KASSERT(vn != NULL);
85
86
vfs_biglock_acquire();
87
88
vn->vn_refcount++;
89
90
vfs_biglock_release();
91
}
92
93
/*
94
* Decrement refcount.
95
* Called by VOP_DECREF.
96
* Calls VOP_RECLAIM if the refcount hits zero.
97
*/
98
void
99
vnode_decref(struct vnode *vn)
100
{
101
int result;
102
103
KASSERT(vn != NULL);
104
105
vfs_biglock_acquire();
106
107
KASSERT(vn->vn_refcount>0);
108
if (vn->vn_refcount>1) {
109
vn->vn_refcount--;
110
}
111
else {
112
result = VOP_RECLAIM(vn);
113
if (result != 0 && result != EBUSY) {
114
// XXX: lame.
115
kprintf("vfs: Warning: VOP_RECLAIM: %s\n",
116
strerror(result));
117
}
118
}
119
120
vfs_biglock_release();
121
}
122
123
/*
124
* Increment the open count.
125
* Called by VOP_INCOPEN.
126
*/
127
void
128
vnode_incopen(struct vnode *vn)
129
{
130
KASSERT(vn != NULL);
131
132
vfs_biglock_acquire();
133
vn->vn_opencount++;
134
vfs_biglock_release();
135
}
136
137
/*
138
* Decrement the open count.
139
* Called by VOP_DECOPEN.
140
*/
141
void
142
vnode_decopen(struct vnode *vn)
143
{
144
int result;
145
146
KASSERT(vn != NULL);
147
148
vfs_biglock_acquire();
149
150
KASSERT(vn->vn_opencount>0);
151
vn->vn_opencount--;
152
153
if (vn->vn_opencount > 0) {
154
vfs_biglock_release();
155
return;
156
}
157
158
result = VOP_CLOSE(vn);
159
if (result) {
160
// XXX: also lame.
161
// The FS should do what it can to make sure this code
162
// doesn't get reached...
163
kprintf("vfs: Warning: VOP_CLOSE: %s\n", strerror(result));
164
}
165
166
vfs_biglock_release();
167
}
168
169
/*
170
* Check for various things being valid.
171
* Called before all VOP_* calls.
172
*/
173
void
174
vnode_check(struct vnode *v, const char *opstr)
175
{
176
vfs_biglock_acquire();
177
178
if (v == NULL) {
179
panic("vnode_check: vop_%s: null vnode\n", opstr);
180
}
181
if (v == (void *)0xdeadbeef) {
182
panic("vnode_check: vop_%s: deadbeef vnode\n", opstr);
183
}
184
185
if (v->vn_ops == NULL) {
186
panic("vnode_check: vop_%s: null ops pointer\n", opstr);
187
}
188
if (v->vn_ops == (void *)0xdeadbeef) {
189
panic("vnode_check: vop_%s: deadbeef ops pointer\n", opstr);
190
}
191
192
if (v->vn_ops->vop_magic != VOP_MAGIC) {
193
panic("vnode_check: vop_%s: ops with bad magic number %lx\n",
194
opstr, v->vn_ops->vop_magic);
195
}
196
197
// Device vnodes have null fs pointers.
198
//if (v->vn_fs == NULL) {
199
// panic("vnode_check: vop_%s: null fs pointer\n", opstr);
200
//}
201
if (v->vn_fs == (void *)0xdeadbeef) {
202
panic("vnode_check: vop_%s: deadbeef fs pointer\n", opstr);
203
}
204
205
if (v->vn_refcount < 0) {
206
panic("vnode_check: vop_%s: negative refcount %d\n", opstr,
207
v->vn_refcount);
208
}
209
else if (v->vn_refcount == 0 && strcmp(opstr, "reclaim")) {
210
panic("vnode_check: vop_%s: zero refcount\n", opstr);
211
}
212
else if (v->vn_refcount > 0x100000) {
213
kprintf("vnode_check: vop_%s: warning: large refcount %d\n",
214
opstr, v->vn_refcount);
215
}
216
217
if (v->vn_opencount < 0) {
218
panic("vnode_check: vop_%s: negative opencount %d\n", opstr,
219
v->vn_opencount);
220
}
221
else if (v->vn_opencount > 0x100000) {
222
kprintf("vnode_check: vop_%s: warning: large opencount %d\n",
223
opstr, v->vn_opencount);
224
}
225
226
vfs_biglock_release();
227
}
228
229