xref: /csrg-svn/sys/nfs/nfs_node.c (revision 53550)
138415Smckusick /*
238415Smckusick  * Copyright (c) 1989 The Regents of the University of California.
338415Smckusick  * All rights reserved.
438415Smckusick  *
538415Smckusick  * This code is derived from software contributed to Berkeley by
638415Smckusick  * Rick Macklem at The University of Guelph.
738415Smckusick  *
844509Sbostic  * %sccs.include.redist.c%
938415Smckusick  *
10*53550Sheideman  *	@(#)nfs_node.c	7.38 (Berkeley) 05/14/92
1138415Smckusick  */
1238415Smckusick 
1338415Smckusick #include "param.h"
1438415Smckusick #include "systm.h"
1538415Smckusick #include "proc.h"
1638415Smckusick #include "mount.h"
1748052Smckusick #include "namei.h"
1838415Smckusick #include "vnode.h"
1947573Skarels #include "kernel.h"
2047573Skarels #include "malloc.h"
2147573Skarels 
2252196Smckusick #include "rpcv2.h"
2338415Smckusick #include "nfsv2.h"
2438415Smckusick #include "nfs.h"
2538415Smckusick #include "nfsnode.h"
2638415Smckusick #include "nfsmount.h"
2752196Smckusick #include "nqnfs.h"
2838415Smckusick 
2938415Smckusick /* The request list head */
3038415Smckusick extern struct nfsreq nfsreqh;
3138415Smckusick 
3238415Smckusick #define	NFSNOHSZ	512
3338415Smckusick #if	((NFSNOHSZ&(NFSNOHSZ-1)) == 0)
3438415Smckusick #define	NFSNOHASH(fhsum)	((fhsum)&(NFSNOHSZ-1))
3538415Smckusick #else
3638415Smckusick #define	NFSNOHASH(fhsum)	(((unsigned)(fhsum))%NFSNOHSZ)
3738415Smckusick #endif
3838415Smckusick 
3939395Smckusick union nhead {
4038415Smckusick 	union  nhead *nh_head[2];
4138415Smckusick 	struct nfsnode *nh_chain[2];
4238415Smckusick } nhead[NFSNOHSZ];
4338415Smckusick 
4438884Smacklem #define TRUE	1
4538884Smacklem #define	FALSE	0
4638884Smacklem 
4738415Smckusick /*
4838415Smckusick  * Initialize hash links for nfsnodes
4938415Smckusick  * and build nfsnode free list.
5038415Smckusick  */
5138415Smckusick nfs_nhinit()
5238415Smckusick {
5338415Smckusick 	register int i;
5438415Smckusick 	register union  nhead *nh = nhead;
5538415Smckusick 
5639494Smckusick #ifndef lint
5751985Smckusick 	if ((sizeof(struct nfsnode) - 1) & sizeof(struct nfsnode))
5851985Smckusick 		printf("nfs_nhinit: bad size %d\n", sizeof(struct nfsnode));
5939494Smckusick #endif /* not lint */
6038415Smckusick 	for (i = NFSNOHSZ; --i >= 0; nh++) {
6138415Smckusick 		nh->nh_head[0] = nh;
6238415Smckusick 		nh->nh_head[1] = nh;
6338415Smckusick 	}
6438415Smckusick }
6538415Smckusick 
6638415Smckusick /*
6739445Smckusick  * Compute an entry in the NFS hash table structure
6839445Smckusick  */
6939445Smckusick union nhead *
7039445Smckusick nfs_hash(fhp)
7139445Smckusick 	register nfsv2fh_t *fhp;
7239445Smckusick {
7339445Smckusick 	register u_char *fhpp;
7439445Smckusick 	register u_long fhsum;
7539445Smckusick 	int i;
7639445Smckusick 
7739445Smckusick 	fhpp = &fhp->fh_bytes[0];
7839445Smckusick 	fhsum = 0;
7939445Smckusick 	for (i = 0; i < NFSX_FH; i++)
8039445Smckusick 		fhsum += *fhpp++;
8139445Smckusick 	return (&nhead[NFSNOHASH(fhsum)]);
8239445Smckusick }
8339445Smckusick 
8439445Smckusick /*
8539395Smckusick  * Look up a vnode/nfsnode by file handle.
8638415Smckusick  * Callers must check for mount points!!
8738415Smckusick  * In all cases, a pointer to a
8838415Smckusick  * nfsnode structure is returned.
8938415Smckusick  */
9038415Smckusick nfs_nget(mntp, fhp, npp)
9138415Smckusick 	struct mount *mntp;
9238415Smckusick 	register nfsv2fh_t *fhp;
9338415Smckusick 	struct nfsnode **npp;
9438415Smckusick {
9538415Smckusick 	register struct nfsnode *np;
9638415Smckusick 	register struct vnode *vp;
97*53550Sheideman 	extern int (**nfsv2_vnodeop_p)();
9839395Smckusick 	struct vnode *nvp;
9939395Smckusick 	union nhead *nh;
10039445Smckusick 	int error;
10138415Smckusick 
10239445Smckusick 	nh = nfs_hash(fhp);
10338415Smckusick loop:
10438884Smacklem 	for (np = nh->nh_chain[0]; np != (struct nfsnode *)nh; np = np->n_forw) {
10539395Smckusick 		if (mntp != NFSTOV(np)->v_mount ||
10639395Smckusick 		    bcmp((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH))
10739395Smckusick 			continue;
10839395Smckusick 		vp = NFSTOV(np);
10939445Smckusick 		if (vget(vp))
11039445Smckusick 			goto loop;
11139395Smckusick 		*npp = np;
11239395Smckusick 		return(0);
11338884Smacklem 	}
114*53550Sheideman 	if (error = getnewvnode(VT_NFS, mntp, nfsv2_vnodeop_p, &nvp)) {
11538415Smckusick 		*npp = 0;
11639395Smckusick 		return (error);
11738415Smckusick 	}
11839395Smckusick 	vp = nvp;
11951985Smckusick 	MALLOC(np, struct nfsnode *, sizeof *np, M_NFSNODE, M_WAITOK);
12051985Smckusick 	vp->v_data = np;
12139395Smckusick 	np->n_vnode = vp;
12238415Smckusick 	/*
12338884Smacklem 	 * Insert the nfsnode in the hash queue for its new file handle
12438884Smacklem 	 */
12539908Smckusick 	np->n_flag = 0;
12638415Smckusick 	insque(np, nh);
12738415Smckusick 	bcopy((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH);
12838415Smckusick 	np->n_attrstamp = 0;
12941898Smckusick 	np->n_direofoffset = 0;
13038415Smckusick 	np->n_sillyrename = (struct sillyrename *)0;
13138884Smacklem 	np->n_size = 0;
13252196Smckusick 	if (VFSTONFS(mntp)->nm_flag & NFSMNT_NQNFS) {
13352196Smckusick 		ZEROQUAD(np->n_brev);
13452196Smckusick 		ZEROQUAD(np->n_lrev);
13552196Smckusick 		np->n_expiry = (time_t)0;
13652196Smckusick 		np->n_tnext = (struct nfsnode *)0;
13752196Smckusick 	} else
13852196Smckusick 		np->n_mtime = 0;
13938415Smckusick 	*npp = np;
14038415Smckusick 	return (0);
14138415Smckusick }
14238415Smckusick 
143*53550Sheideman nfs_inactive (ap)
144*53550Sheideman 	struct vop_inactive_args *ap;
145*53550Sheideman #define vp (ap->a_vp)
146*53550Sheideman #define p (ap->a_p)
14738415Smckusick {
14838415Smckusick 	register struct nfsnode *np;
14938415Smckusick 	register struct sillyrename *sp;
15039575Smckusick 	extern int prtactive;
15138415Smckusick 
15239395Smckusick 	np = VTONFS(vp);
15339810Smckusick 	if (prtactive && vp->v_usecount != 0)
15439671Smckusick 		vprint("nfs_inactive: pushing active", vp);
15539395Smckusick 	sp = np->n_sillyrename;
15639395Smckusick 	np->n_sillyrename = (struct sillyrename *)0;
15739395Smckusick 	if (sp) {
15838415Smckusick 		/*
15939395Smckusick 		 * Remove the silly file that was rename'd earlier
16038415Smckusick 		 */
16152196Smckusick 		nfs_removeit(sp, p);
16248364Smckusick 		crfree(sp->s_cred);
16348364Smckusick 		vrele(sp->s_dvp);
16451985Smckusick #ifdef SILLYSEPARATE
16548364Smckusick 		free((caddr_t)sp, M_NFSREQ);
16651985Smckusick #endif
16739395Smckusick 	}
16841898Smckusick 	np->n_flag &= NMODIFIED;
16939395Smckusick 	return (0);
17039395Smckusick }
171*53550Sheideman #undef vp
172*53550Sheideman #undef p
17339395Smckusick 
17439395Smckusick /*
17539395Smckusick  * Reclaim an nfsnode so that it can be used for other purposes.
17639395Smckusick  */
177*53550Sheideman nfs_reclaim (ap)
178*53550Sheideman 	struct vop_reclaim_args *ap;
179*53550Sheideman #define vp (ap->a_vp)
18039395Smckusick {
18139395Smckusick 	register struct nfsnode *np = VTONFS(vp);
18252196Smckusick 	register struct nfsmount *nmp = VFSTONFS(vp->v_mount);
18339575Smckusick 	extern int prtactive;
18439395Smckusick 
18539810Smckusick 	if (prtactive && vp->v_usecount != 0)
18639671Smckusick 		vprint("nfs_reclaim: pushing active", vp);
18739395Smckusick 	/*
18839395Smckusick 	 * Remove the nfsnode from its hash chain.
18939395Smckusick 	 */
19039395Smckusick 	remque(np);
19152196Smckusick 
19252196Smckusick 	/*
19352196Smckusick 	 * For nqnfs, take it off the timer queue as required.
19452196Smckusick 	 */
19552196Smckusick 	if ((nmp->nm_flag & NFSMNT_NQNFS) && np->n_tnext) {
19652196Smckusick 		if (np->n_tnext == (struct nfsnode *)nmp)
19752196Smckusick 			nmp->nm_tprev = np->n_tprev;
19852196Smckusick 		else
19952196Smckusick 			np->n_tnext->n_tprev = np->n_tprev;
20052196Smckusick 		if (np->n_tprev == (struct nfsnode *)nmp)
20152196Smckusick 			nmp->nm_tnext = np->n_tnext;
20252196Smckusick 		else
20352196Smckusick 			np->n_tprev->n_tnext = np->n_tnext;
20452196Smckusick 	}
20539395Smckusick 	cache_purge(vp);
20651985Smckusick 	FREE(vp->v_data, M_NFSNODE);
20752196Smckusick 	vp->v_data = (void *)0;
20838415Smckusick 	return (0);
20938415Smckusick }
210*53550Sheideman #undef vp
21138415Smckusick 
21238415Smckusick /*
21338415Smckusick  * Lock an nfsnode
21438415Smckusick  */
215*53550Sheideman nfs_lock (ap)
216*53550Sheideman 	struct vop_lock_args *ap;
217*53550Sheideman #define vp (ap->a_vp)
21838415Smckusick {
21938415Smckusick 
22052196Smckusick 	return (0);
22138415Smckusick }
222*53550Sheideman #undef vp
22338415Smckusick 
22438415Smckusick /*
22538415Smckusick  * Unlock an nfsnode
22638415Smckusick  */
227*53550Sheideman nfs_unlock (ap)
228*53550Sheideman 	struct vop_unlock_args *ap;
229*53550Sheideman #define vp (ap->a_vp)
23038415Smckusick {
23138415Smckusick 
23252196Smckusick 	return (0);
23338415Smckusick }
234*53550Sheideman #undef vp
23538415Smckusick 
23638415Smckusick /*
23739908Smckusick  * Check for a locked nfsnode
23839908Smckusick  */
239*53550Sheideman nfs_islocked (ap)
240*53550Sheideman 	struct vop_islocked_args *ap;
241*53550Sheideman #define vp (ap->a_vp)
24239908Smckusick {
24339908Smckusick 
24439908Smckusick 	return (0);
24539908Smckusick }
246*53550Sheideman #undef vp
24739908Smckusick 
24839908Smckusick /*
24942467Smckusick  * Nfs abort op, called after namei() when a CREATE/DELETE isn't actually
25042467Smckusick  * done. Currently nothing to do.
25142467Smckusick  */
25242467Smckusick /* ARGSUSED */
25352234Sheideman int
254*53550Sheideman nfs_abortop (ap)
255*53550Sheideman 	struct vop_abortop_args *ap;
256*53550Sheideman #define dvp (ap->a_dvp)
257*53550Sheideman #define cnp (ap->a_cnp)
25838415Smckusick {
25938415Smckusick 
26052234Sheideman 	if ((cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
26152234Sheideman 		FREE(cnp->cn_pnbuf, M_NAMEI);
26242467Smckusick 	return (0);
26338415Smckusick }
264*53550Sheideman #undef dvp
265*53550Sheideman #undef cnp
266