xref: /original-bsd/sys/nfs/nfs_node.c (revision 77040245)
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  *
8  * %sccs.include.redist.c%
9  *
10  *	@(#)nfs_node.c	7.42 (Berkeley) 07/22/92
11  */
12 
13 #include "param.h"
14 #include "systm.h"
15 #include "proc.h"
16 #include "mount.h"
17 #include "namei.h"
18 #include "vnode.h"
19 #include "kernel.h"
20 #include "malloc.h"
21 
22 #include "rpcv2.h"
23 #include "nfsv2.h"
24 #include "nfs.h"
25 #include "nfsnode.h"
26 #include "nfsmount.h"
27 #include "nqnfs.h"
28 
29 struct nfsnode **nheadhashtbl;
30 u_long nheadhash;
31 #define	NFSNOHASH(fhsum)	((fhsum)&nheadhash)
32 
33 #define TRUE	1
34 #define	FALSE	0
35 
36 /*
37  * Initialize hash links for nfsnodes
38  * and build nfsnode free list.
39  */
40 nfs_nhinit()
41 {
42 
43 #ifndef lint
44 	if ((sizeof(struct nfsnode) - 1) & sizeof(struct nfsnode))
45 		printf("nfs_nhinit: bad size %d\n", sizeof(struct nfsnode));
46 #endif /* not lint */
47 	nheadhashtbl = hashinit(desiredvnodes, M_NFSNODE, &nheadhash);
48 }
49 
50 /*
51  * Compute an entry in the NFS hash table structure
52  */
53 struct nfsnode **
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++;
65 	return (&nheadhashtbl[NFSNOHASH(fhsum)]);
66 }
67 
68 /*
69  * Look up a vnode/nfsnode by file handle.
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 {
79 	register struct nfsnode *np, *nq, **nhpp;
80 	register struct vnode *vp;
81 	extern int (**nfsv2_vnodeop_p)();
82 	struct vnode *nvp;
83 	int error;
84 
85 	nhpp = nfs_hash(fhp);
86 loop:
87 	for (np = *nhpp; np; np = np->n_forw) {
88 		if (mntp != NFSTOV(np)->v_mount ||
89 		    bcmp((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH))
90 			continue;
91 		vp = NFSTOV(np);
92 		if (vget(vp))
93 			goto loop;
94 		*npp = np;
95 		return(0);
96 	}
97 	if (error = getnewvnode(VT_NFS, mntp, nfsv2_vnodeop_p, &nvp)) {
98 		*npp = 0;
99 		return (error);
100 	}
101 	vp = nvp;
102 	MALLOC(np, struct nfsnode *, sizeof *np, M_NFSNODE, M_WAITOK);
103 	vp->v_data = np;
104 	np->n_vnode = vp;
105 	/*
106 	 * Insert the nfsnode in the hash queue for its new file handle
107 	 */
108 	np->n_flag = 0;
109 	if (nq = *nhpp)
110 		nq->n_back = &np->n_forw;
111 	np->n_forw = nq;
112 	np->n_back = nhpp;
113 	*nhpp = np;
114 	bcopy((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH);
115 	np->n_attrstamp = 0;
116 	np->n_direofoffset = 0;
117 	np->n_sillyrename = (struct sillyrename *)0;
118 	np->n_size = 0;
119 	if (VFSTONFS(mntp)->nm_flag & NFSMNT_NQNFS) {
120 		np->n_brev = 0;
121 		np->n_lrev = 0;
122 		np->n_expiry = (time_t)0;
123 		np->n_tnext = (struct nfsnode *)0;
124 	} else
125 		np->n_mtime = 0;
126 	*npp = np;
127 	return (0);
128 }
129 
130 nfs_inactive(ap)
131 	struct vop_inactive_args /* {
132 		struct vnode *a_vp;
133 	} */ *ap;
134 {
135 	register struct nfsnode *np;
136 	register struct sillyrename *sp;
137 	extern int prtactive;
138 
139 	np = VTONFS(ap->a_vp);
140 	if (prtactive && ap->a_vp->v_usecount != 0)
141 		vprint("nfs_inactive: pushing active", ap->a_vp);
142 	sp = np->n_sillyrename;
143 	np->n_sillyrename = (struct sillyrename *)0;
144 	if (sp) {
145 		/*
146 		 * Remove the silly file that was rename'd earlier
147 		 */
148 		nfs_removeit(sp);
149 		crfree(sp->s_cred);
150 		vrele(sp->s_dvp);
151 #ifdef SILLYSEPARATE
152 		free((caddr_t)sp, M_NFSREQ);
153 #endif
154 	}
155 	np->n_flag &= NMODIFIED;
156 	return (0);
157 }
158 
159 /*
160  * Reclaim an nfsnode so that it can be used for other purposes.
161  */
162 nfs_reclaim(ap)
163 	struct vop_reclaim_args /* {
164 		struct vnode *a_vp;
165 	} */ *ap;
166 {
167 	register struct vnode *vp = ap->a_vp;
168 	register struct nfsnode *np = VTONFS(vp);
169 	register struct nfsmount *nmp = VFSTONFS(vp->v_mount);
170 	register struct nfsnode *nq;
171 	extern int prtactive;
172 
173 	if (prtactive && vp->v_usecount != 0)
174 		vprint("nfs_reclaim: pushing active", vp);
175 	/*
176 	 * Remove the nfsnode from its hash chain.
177 	 */
178 	if (nq = np->n_forw)
179 		nq->n_back = np->n_back;
180 	*np->n_back = nq;
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 	}
195 	cache_purge(vp);
196 	FREE(vp->v_data, M_NFSNODE);
197 	vp->v_data = (void *)0;
198 	return (0);
199 }
200 
201 /*
202  * Lock an nfsnode
203  */
204 nfs_lock(ap)
205 	struct vop_lock_args /* {
206 		struct vnode *a_vp;
207 	} */ *ap;
208 {
209 
210 	return (0);
211 }
212 
213 /*
214  * Unlock an nfsnode
215  */
216 nfs_unlock(ap)
217 	struct vop_unlock_args /* {
218 		struct vnode *a_vp;
219 	} */ *ap;
220 {
221 
222 	return (0);
223 }
224 
225 /*
226  * Check for a locked nfsnode
227  */
228 nfs_islocked(ap)
229 	struct vop_islocked_args /* {
230 		struct vnode *a_vp;
231 	} */ *ap;
232 {
233 
234 	return (0);
235 }
236 
237 /*
238  * Nfs abort op, called after namei() when a CREATE/DELETE isn't actually
239  * done. Currently nothing to do.
240  */
241 /* ARGSUSED */
242 int
243 nfs_abortop(ap)
244 	struct vop_abortop_args /* {
245 		struct vnode *a_dvp;
246 		struct componentname *a_cnp;
247 	} */ *ap;
248 {
249 
250 	if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
251 		FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
252 	return (0);
253 }
254