This source file includes following definitions.
- nfs_nhinit
- nfs_nget
- nfs_inactive
- nfs_reclaim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/proc.h>
42 #include <sys/mount.h>
43 #include <sys/namei.h>
44 #include <sys/vnode.h>
45 #include <sys/kernel.h>
46 #include <sys/malloc.h>
47 #include <sys/pool.h>
48 #include <sys/hash.h>
49 #include <sys/rwlock.h>
50
51 #include <nfs/rpcv2.h>
52 #include <nfs/nfsproto.h>
53 #include <nfs/nfs.h>
54 #include <nfs/nfsnode.h>
55 #include <nfs/nfsmount.h>
56 #include <nfs/nfs_var.h>
57
58 LIST_HEAD(nfsnodehashhead, nfsnode) *nfsnodehashtbl;
59 u_long nfsnodehash;
60 struct rwlock nfs_hashlock = RWLOCK_INITIALIZER("nfshshlk");
61
62 struct pool nfs_node_pool;
63
64 extern int prtactive;
65
66 #define TRUE 1
67 #define FALSE 0
68
69 #define nfs_hash(x,y) hash32_buf((x), (y), HASHINIT)
70
71
72
73
74
75 void
76 nfs_nhinit()
77 {
78 nfsnodehashtbl = hashinit(desiredvnodes, M_NFSNODE, M_WAITOK, &nfsnodehash);
79 pool_init(&nfs_node_pool, sizeof(struct nfsnode), 0, 0, 0, "nfsnodepl",
80 &pool_allocator_nointr);
81 }
82
83
84
85
86
87
88
89 int
90 nfs_nget(mntp, fhp, fhsize, npp)
91 struct mount *mntp;
92 nfsfh_t *fhp;
93 int fhsize;
94 struct nfsnode **npp;
95 {
96 struct proc *p = curproc;
97 struct nfsnode *np;
98 struct nfsnodehashhead *nhpp;
99 struct vnode *vp;
100 extern int (**nfsv2_vnodeop_p)(void *);
101 struct vnode *nvp;
102 int error;
103
104 nhpp = NFSNOHASH(nfs_hash(fhp, fhsize));
105 loop:
106 for (np = LIST_FIRST(nhpp); np != NULL; np = LIST_NEXT(np, n_hash)) {
107 if (mntp != NFSTOV(np)->v_mount || np->n_fhsize != fhsize ||
108 bcmp((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize))
109 continue;
110 vp = NFSTOV(np);
111 if (vget(vp, LK_EXCLUSIVE, p))
112 goto loop;
113 *npp = np;
114 return(0);
115 }
116 if (rw_enter(&nfs_hashlock, RW_WRITE|RW_SLEEPFAIL))
117 goto loop;
118 error = getnewvnode(VT_NFS, mntp, nfsv2_vnodeop_p, &nvp);
119 if (error) {
120 *npp = 0;
121 rw_exit(&nfs_hashlock);
122 return (error);
123 }
124 vp = nvp;
125 np = pool_get(&nfs_node_pool, PR_WAITOK);
126 bzero((caddr_t)np, sizeof *np);
127 vp->v_data = np;
128 np->n_vnode = vp;
129
130 rw_init(&np->n_commitlock, "nfs_commitlk");
131
132
133
134
135
136 {
137 struct nfsmount *nmp = VFSTONFS(mntp);
138 if ((fhsize == nmp->nm_fhsize) &&
139 !bcmp(fhp, nmp->nm_fh, fhsize)) {
140 if (vp->v_type == VNON)
141 vp->v_type = VDIR;
142 vp->v_flag |= VROOT;
143 }
144 }
145
146 LIST_INSERT_HEAD(nhpp, np, n_hash);
147 if (fhsize > NFS_SMALLFH) {
148 np->n_fhp = malloc(fhsize, M_NFSBIGFH, M_WAITOK);
149 } else
150 np->n_fhp = &np->n_fh;
151 bcopy((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize);
152 np->n_fhsize = fhsize;
153 rw_exit(&nfs_hashlock);
154 *npp = np;
155 return (0);
156 }
157
158 int
159 nfs_inactive(v)
160 void *v;
161 {
162 struct vop_inactive_args *ap = v;
163 struct nfsnode *np;
164 struct sillyrename *sp;
165 struct proc *p = curproc;
166
167 np = VTONFS(ap->a_vp);
168
169 #ifdef DIAGNOSTIC
170 if (prtactive && ap->a_vp->v_usecount != 0)
171 vprint("nfs_inactive: pushing active", ap->a_vp);
172 #endif
173
174 if (ap->a_vp->v_type != VDIR) {
175 sp = np->n_sillyrename;
176 np->n_sillyrename = (struct sillyrename *)0;
177 } else
178 sp = (struct sillyrename *)0;
179 if (sp) {
180
181
182
183 (void) nfs_vinvalbuf(ap->a_vp, 0, sp->s_cred, p, 1);
184 nfs_removeit(sp);
185 crfree(sp->s_cred);
186 vrele(sp->s_dvp);
187 FREE((caddr_t)sp, M_NFSREQ);
188 }
189 np->n_flag &= (NMODIFIED | NFLUSHINPROG | NFLUSHWANT);
190
191 VOP_UNLOCK(ap->a_vp, 0, ap->a_p);
192 return (0);
193 }
194
195
196
197
198 int
199 nfs_reclaim(v)
200 void *v;
201 {
202 struct vop_reclaim_args *ap = v;
203 struct vnode *vp = ap->a_vp;
204 struct nfsnode *np = VTONFS(vp);
205 struct nfsdmap *dp, *dp2;
206
207 #ifdef DIAGNOSTIC
208 if (prtactive && vp->v_usecount != 0)
209 vprint("nfs_reclaim: pushing active", vp);
210 #endif
211
212 if (np->n_hash.le_prev != NULL)
213 LIST_REMOVE(np, n_hash);
214
215
216
217
218
219
220 if (vp->v_type == VDIR) {
221 dp = LIST_FIRST(&np->n_cookies);
222 while (dp) {
223 dp2 = dp;
224 dp = LIST_NEXT(dp, ndm_list);
225 FREE((caddr_t)dp2, M_NFSDIROFF);
226 }
227 }
228 if (np->n_fhsize > NFS_SMALLFH) {
229 free(np->n_fhp, M_NFSBIGFH);
230 }
231
232 if (np->n_rcred)
233 crfree(np->n_rcred);
234 if (np->n_wcred)
235 crfree(np->n_wcred);
236 cache_purge(vp);
237 pool_put(&nfs_node_pool, vp->v_data);
238 vp->v_data = NULL;
239 return (0);
240 }
241