00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <types.h>
00034 #include <kern/errno.h>
00035 #include <lib.h>
00036 #include <synch.h>
00037 #include <vfs.h>
00038 #include <vnode.h>
00039
00040
00041
00042
00043
00044 int
00045 vnode_init(struct vnode *vn, const struct vnode_ops *ops,
00046 struct fs *fs, void *fsdata)
00047 {
00048 KASSERT(vn!=NULL);
00049 KASSERT(ops!=NULL);
00050
00051 vn->vn_ops = ops;
00052 vn->vn_refcount = 1;
00053 vn->vn_opencount = 0;
00054 vn->vn_fs = fs;
00055 vn->vn_data = fsdata;
00056 return 0;
00057 }
00058
00059
00060
00061
00062
00063 void
00064 vnode_cleanup(struct vnode *vn)
00065 {
00066 KASSERT(vn->vn_refcount==1);
00067 KASSERT(vn->vn_opencount==0);
00068
00069 vn->vn_ops = NULL;
00070 vn->vn_refcount = 0;
00071 vn->vn_opencount = 0;
00072 vn->vn_fs = NULL;
00073 vn->vn_data = NULL;
00074 }
00075
00076
00077
00078
00079
00080
00081 void
00082 vnode_incref(struct vnode *vn)
00083 {
00084 KASSERT(vn != NULL);
00085
00086 vfs_biglock_acquire();
00087
00088 vn->vn_refcount++;
00089
00090 vfs_biglock_release();
00091 }
00092
00093
00094
00095
00096
00097
00098 void
00099 vnode_decref(struct vnode *vn)
00100 {
00101 int result;
00102
00103 KASSERT(vn != NULL);
00104
00105 vfs_biglock_acquire();
00106
00107 KASSERT(vn->vn_refcount>0);
00108 if (vn->vn_refcount>1) {
00109 vn->vn_refcount--;
00110 }
00111 else {
00112 result = VOP_RECLAIM(vn);
00113 if (result != 0 && result != EBUSY) {
00114
00115 kprintf("vfs: Warning: VOP_RECLAIM: %s\n",
00116 strerror(result));
00117 }
00118 }
00119
00120 vfs_biglock_release();
00121 }
00122
00123
00124
00125
00126
00127 void
00128 vnode_incopen(struct vnode *vn)
00129 {
00130 KASSERT(vn != NULL);
00131
00132 vfs_biglock_acquire();
00133 vn->vn_opencount++;
00134 vfs_biglock_release();
00135 }
00136
00137
00138
00139
00140
00141 void
00142 vnode_decopen(struct vnode *vn)
00143 {
00144 int result;
00145
00146 KASSERT(vn != NULL);
00147
00148 vfs_biglock_acquire();
00149
00150 KASSERT(vn->vn_opencount>0);
00151 vn->vn_opencount--;
00152
00153 if (vn->vn_opencount > 0) {
00154 vfs_biglock_release();
00155 return;
00156 }
00157
00158 result = VOP_CLOSE(vn);
00159 if (result) {
00160
00161
00162
00163 kprintf("vfs: Warning: VOP_CLOSE: %s\n", strerror(result));
00164 }
00165
00166 vfs_biglock_release();
00167 }
00168
00169
00170
00171
00172
00173 void
00174 vnode_check(struct vnode *v, const char *opstr)
00175 {
00176 vfs_biglock_acquire();
00177
00178 if (v == NULL) {
00179 panic("vnode_check: vop_%s: null vnode\n", opstr);
00180 }
00181 if (v == (void *)0xdeadbeef) {
00182 panic("vnode_check: vop_%s: deadbeef vnode\n", opstr);
00183 }
00184
00185 if (v->vn_ops == NULL) {
00186 panic("vnode_check: vop_%s: null ops pointer\n", opstr);
00187 }
00188 if (v->vn_ops == (void *)0xdeadbeef) {
00189 panic("vnode_check: vop_%s: deadbeef ops pointer\n", opstr);
00190 }
00191
00192 if (v->vn_ops->vop_magic != VOP_MAGIC) {
00193 panic("vnode_check: vop_%s: ops with bad magic number %lx\n",
00194 opstr, v->vn_ops->vop_magic);
00195 }
00196
00197
00198
00199
00200
00201 if (v->vn_fs == (void *)0xdeadbeef) {
00202 panic("vnode_check: vop_%s: deadbeef fs pointer\n", opstr);
00203 }
00204
00205 if (v->vn_refcount < 0) {
00206 panic("vnode_check: vop_%s: negative refcount %d\n", opstr,
00207 v->vn_refcount);
00208 }
00209 else if (v->vn_refcount == 0 && strcmp(opstr, "reclaim")) {
00210 panic("vnode_check: vop_%s: zero refcount\n", opstr);
00211 }
00212 else if (v->vn_refcount > 0x100000) {
00213 kprintf("vnode_check: vop_%s: warning: large refcount %d\n",
00214 opstr, v->vn_refcount);
00215 }
00216
00217 if (v->vn_opencount < 0) {
00218 panic("vnode_check: vop_%s: negative opencount %d\n", opstr,
00219 v->vn_opencount);
00220 }
00221 else if (v->vn_opencount > 0x100000) {
00222 kprintf("vnode_check: vop_%s: warning: large opencount %d\n",
00223 opstr, v->vn_opencount);
00224 }
00225
00226 vfs_biglock_release();
00227 }