Commit | Line | Data |
---|---|---|
a2907882 KM |
1 | /* |
2 | * Copyright (c) 1989 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * This code is derived from software contributed to Berkeley by | |
6 | * Rick Macklem at The University of Guelph. | |
7 | * | |
dbf0c423 | 8 | * %sccs.include.redist.c% |
a2907882 | 9 | * |
5548a02f | 10 | * @(#)nfs_node.c 7.44 (Berkeley) %G% |
a2907882 KM |
11 | */ |
12 | ||
5548a02f KB |
13 | #include <sys/param.h> |
14 | #include <sys/systm.h> | |
15 | #include <sys/proc.h> | |
16 | #include <sys/mount.h> | |
17 | #include <sys/namei.h> | |
18 | #include <sys/vnode.h> | |
19 | #include <sys/kernel.h> | |
20 | #include <sys/malloc.h> | |
058dee65 | 21 | |
5548a02f KB |
22 | #include <nfs/rpcv2.h> |
23 | #include <nfs/nfsv2.h> | |
24 | #include <nfs/nfs.h> | |
25 | #include <nfs/nfsnode.h> | |
26 | #include <nfs/nfsmount.h> | |
27 | #include <nfs/nqnfs.h> | |
a2907882 | 28 | |
96964be4 KM |
29 | struct nfsnode **nheadhashtbl; |
30 | u_long nheadhash; | |
31 | #define NFSNOHASH(fhsum) ((fhsum)&nheadhash) | |
a2907882 | 32 | |
9238aa59 RM |
33 | #define TRUE 1 |
34 | #define FALSE 0 | |
35 | ||
a2907882 KM |
36 | /* |
37 | * Initialize hash links for nfsnodes | |
38 | * and build nfsnode free list. | |
39 | */ | |
40 | nfs_nhinit() | |
41 | { | |
a2907882 | 42 | |
0bd503ad | 43 | #ifndef lint |
315f50fe KM |
44 | if ((sizeof(struct nfsnode) - 1) & sizeof(struct nfsnode)) |
45 | printf("nfs_nhinit: bad size %d\n", sizeof(struct nfsnode)); | |
0bd503ad | 46 | #endif /* not lint */ |
96964be4 | 47 | nheadhashtbl = hashinit(desiredvnodes, M_NFSNODE, &nheadhash); |
a2907882 KM |
48 | } |
49 | ||
7f79aa94 KM |
50 | /* |
51 | * Compute an entry in the NFS hash table structure | |
52 | */ | |
96964be4 | 53 | struct nfsnode ** |
7f79aa94 KM |
54 | nfs_hash(fhp) |
55 | register nfsv2fh_t *fhp; | |
56 | { | |
57 | register u_char *fhpp; | |
58 | register u_long fhsum; | |
59 | int i; | |
60 | ||
61 | fhpp = &fhp->fh_bytes[0]; | |
62 | fhsum = 0; | |
63 | for (i = 0; i < NFSX_FH; i++) | |
64 | fhsum += *fhpp++; | |
96964be4 | 65 | return (&nheadhashtbl[NFSNOHASH(fhsum)]); |
7f79aa94 KM |
66 | } |
67 | ||
a2907882 | 68 | /* |
bfb2d643 | 69 | * Look up a vnode/nfsnode by file handle. |
a2907882 KM |
70 | * Callers must check for mount points!! |
71 | * In all cases, a pointer to a | |
72 | * nfsnode structure is returned. | |
73 | */ | |
74 | nfs_nget(mntp, fhp, npp) | |
75 | struct mount *mntp; | |
76 | register nfsv2fh_t *fhp; | |
77 | struct nfsnode **npp; | |
78 | { | |
96964be4 | 79 | register struct nfsnode *np, *nq, **nhpp; |
a2907882 | 80 | register struct vnode *vp; |
9342689a | 81 | extern int (**nfsv2_vnodeop_p)(); |
bfb2d643 | 82 | struct vnode *nvp; |
7f79aa94 | 83 | int error; |
a2907882 | 84 | |
96964be4 | 85 | nhpp = nfs_hash(fhp); |
a2907882 | 86 | loop: |
96964be4 | 87 | for (np = *nhpp; np; np = np->n_forw) { |
bfb2d643 KM |
88 | if (mntp != NFSTOV(np)->v_mount || |
89 | bcmp((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH)) | |
90 | continue; | |
bfb2d643 | 91 | vp = NFSTOV(np); |
7f79aa94 KM |
92 | if (vget(vp)) |
93 | goto loop; | |
bfb2d643 KM |
94 | *npp = np; |
95 | return(0); | |
9238aa59 | 96 | } |
9342689a | 97 | if (error = getnewvnode(VT_NFS, mntp, nfsv2_vnodeop_p, &nvp)) { |
a2907882 | 98 | *npp = 0; |
bfb2d643 | 99 | return (error); |
9238aa59 | 100 | } |
bfb2d643 | 101 | vp = nvp; |
315f50fe KM |
102 | MALLOC(np, struct nfsnode *, sizeof *np, M_NFSNODE, M_WAITOK); |
103 | vp->v_data = np; | |
bfb2d643 | 104 | np->n_vnode = vp; |
9238aa59 RM |
105 | /* |
106 | * Insert the nfsnode in the hash queue for its new file handle | |
107 | */ | |
226812f6 | 108 | np->n_flag = 0; |
96964be4 KM |
109 | if (nq = *nhpp) |
110 | nq->n_back = &np->n_forw; | |
111 | np->n_forw = nq; | |
112 | np->n_back = nhpp; | |
113 | *nhpp = np; | |
a2907882 | 114 | bcopy((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH); |
a2907882 | 115 | np->n_attrstamp = 0; |
f0f1cbaa | 116 | np->n_direofoffset = 0; |
a2907882 | 117 | np->n_sillyrename = (struct sillyrename *)0; |
9238aa59 | 118 | np->n_size = 0; |
41f343df | 119 | np->n_mtime = 0; |
2c5b44a2 | 120 | if (VFSTONFS(mntp)->nm_flag & NFSMNT_NQNFS) { |
0f03391d KM |
121 | np->n_brev = 0; |
122 | np->n_lrev = 0; | |
2c5b44a2 KM |
123 | np->n_expiry = (time_t)0; |
124 | np->n_tnext = (struct nfsnode *)0; | |
41f343df | 125 | } |
a2907882 KM |
126 | *npp = np; |
127 | return (0); | |
128 | } | |
129 | ||
4416f512 KM |
130 | nfs_inactive(ap) |
131 | struct vop_inactive_args /* { | |
132 | struct vnode *a_vp; | |
133 | } */ *ap; | |
a2907882 KM |
134 | { |
135 | register struct nfsnode *np; | |
a2907882 | 136 | register struct sillyrename *sp; |
7efae46b | 137 | extern int prtactive; |
a2907882 | 138 | |
e1b76915 JH |
139 | np = VTONFS(ap->a_vp); |
140 | if (prtactive && ap->a_vp->v_usecount != 0) | |
141 | vprint("nfs_inactive: pushing active", ap->a_vp); | |
bfb2d643 KM |
142 | sp = np->n_sillyrename; |
143 | np->n_sillyrename = (struct sillyrename *)0; | |
144 | if (sp) { | |
a2907882 | 145 | /* |
bfb2d643 | 146 | * Remove the silly file that was rename'd earlier |
a2907882 | 147 | */ |
0f03391d | 148 | nfs_removeit(sp); |
a9b4ecb2 KM |
149 | crfree(sp->s_cred); |
150 | vrele(sp->s_dvp); | |
315f50fe | 151 | #ifdef SILLYSEPARATE |
a9b4ecb2 | 152 | free((caddr_t)sp, M_NFSREQ); |
315f50fe | 153 | #endif |
bfb2d643 | 154 | } |
f0f1cbaa | 155 | np->n_flag &= NMODIFIED; |
bfb2d643 KM |
156 | return (0); |
157 | } | |
158 | ||
159 | /* | |
160 | * Reclaim an nfsnode so that it can be used for other purposes. | |
161 | */ | |
4416f512 KM |
162 | nfs_reclaim(ap) |
163 | struct vop_reclaim_args /* { | |
164 | struct vnode *a_vp; | |
165 | } */ *ap; | |
bfb2d643 | 166 | { |
4416f512 KM |
167 | register struct vnode *vp = ap->a_vp; |
168 | register struct nfsnode *np = VTONFS(vp); | |
169 | register struct nfsmount *nmp = VFSTONFS(vp->v_mount); | |
96964be4 | 170 | register struct nfsnode *nq; |
7efae46b | 171 | extern int prtactive; |
bfb2d643 | 172 | |
4416f512 KM |
173 | if (prtactive && vp->v_usecount != 0) |
174 | vprint("nfs_reclaim: pushing active", vp); | |
bfb2d643 KM |
175 | /* |
176 | * Remove the nfsnode from its hash chain. | |
177 | */ | |
96964be4 KM |
178 | if (nq = np->n_forw) |
179 | nq->n_back = np->n_back; | |
180 | *np->n_back = nq; | |
2c5b44a2 KM |
181 | |
182 | /* | |
183 | * For nqnfs, take it off the timer queue as required. | |
184 | */ | |
185 | if ((nmp->nm_flag & NFSMNT_NQNFS) && np->n_tnext) { | |
186 | if (np->n_tnext == (struct nfsnode *)nmp) | |
187 | nmp->nm_tprev = np->n_tprev; | |
188 | else | |
189 | np->n_tnext->n_tprev = np->n_tprev; | |
190 | if (np->n_tprev == (struct nfsnode *)nmp) | |
191 | nmp->nm_tnext = np->n_tnext; | |
192 | else | |
193 | np->n_tprev->n_tnext = np->n_tnext; | |
194 | } | |
4416f512 KM |
195 | cache_purge(vp); |
196 | FREE(vp->v_data, M_NFSNODE); | |
197 | vp->v_data = (void *)0; | |
a2907882 KM |
198 | return (0); |
199 | } | |
200 | ||
a2907882 KM |
201 | /* |
202 | * Lock an nfsnode | |
203 | */ | |
4416f512 KM |
204 | nfs_lock(ap) |
205 | struct vop_lock_args /* { | |
206 | struct vnode *a_vp; | |
207 | } */ *ap; | |
a2907882 | 208 | { |
a2907882 | 209 | |
2c5b44a2 | 210 | return (0); |
a2907882 KM |
211 | } |
212 | ||
213 | /* | |
214 | * Unlock an nfsnode | |
215 | */ | |
4416f512 KM |
216 | nfs_unlock(ap) |
217 | struct vop_unlock_args /* { | |
218 | struct vnode *a_vp; | |
219 | } */ *ap; | |
a2907882 | 220 | { |
a2907882 | 221 | |
2c5b44a2 | 222 | return (0); |
a2907882 KM |
223 | } |
224 | ||
226812f6 KM |
225 | /* |
226 | * Check for a locked nfsnode | |
227 | */ | |
4416f512 KM |
228 | nfs_islocked(ap) |
229 | struct vop_islocked_args /* { | |
230 | struct vnode *a_vp; | |
231 | } */ *ap; | |
226812f6 KM |
232 | { |
233 | ||
226812f6 KM |
234 | return (0); |
235 | } | |
236 | ||
66955caf KM |
237 | /* |
238 | * Nfs abort op, called after namei() when a CREATE/DELETE isn't actually | |
239 | * done. Currently nothing to do. | |
240 | */ | |
241 | /* ARGSUSED */ | |
cfef4373 | 242 | int |
4416f512 KM |
243 | nfs_abortop(ap) |
244 | struct vop_abortop_args /* { | |
245 | struct vnode *a_dvp; | |
246 | struct componentname *a_cnp; | |
247 | } */ *ap; | |
a2907882 | 248 | { |
a2907882 | 249 | |
e1b76915 JH |
250 | if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF) |
251 | FREE(ap->a_cnp->cn_pnbuf, M_NAMEI); | |
66955caf | 252 | return (0); |
a2907882 | 253 | } |