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