bwrite->vn_bwrite and vfree returns error for vn_if
[unix-history] / usr / src / sys / nfs / nfs_node.c
CommitLineData
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 */
30extern 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 39union 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 */
51nfs_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 */
69union nhead *
70nfs_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 */
90nfs_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 103loop:
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
143nfs_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
177nfs_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
215nfs_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
227nfs_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
239nfs_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 253int
9342689a
JH
254nfs_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