disallow creation of files in removed directories
[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 *
cfef4373 10 * @(#)nfs_node.c 7.37 (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;
7f79aa94 97 extern struct vnodeops nfsv2_vnodeops;
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 }
bfb2d643 114 if (error = getnewvnode(VT_NFS, mntp, &nfsv2_vnodeops, &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
fd46fb76 143nfs_inactive(vp, p)
a2907882 144 struct vnode *vp;
fd46fb76 145 struct proc *p;
a2907882
KM
146{
147 register struct nfsnode *np;
a2907882 148 register struct sillyrename *sp;
7efae46b 149 extern int prtactive;
a2907882 150
bfb2d643 151 np = VTONFS(vp);
1f7e9641 152 if (prtactive && vp->v_usecount != 0)
b2870bc0 153 vprint("nfs_inactive: pushing active", vp);
bfb2d643
KM
154 sp = np->n_sillyrename;
155 np->n_sillyrename = (struct sillyrename *)0;
156 if (sp) {
a2907882 157 /*
bfb2d643 158 * Remove the silly file that was rename'd earlier
a2907882 159 */
2c5b44a2 160 nfs_removeit(sp, p);
a9b4ecb2
KM
161 crfree(sp->s_cred);
162 vrele(sp->s_dvp);
315f50fe 163#ifdef SILLYSEPARATE
a9b4ecb2 164 free((caddr_t)sp, M_NFSREQ);
315f50fe 165#endif
bfb2d643 166 }
f0f1cbaa 167 np->n_flag &= NMODIFIED;
bfb2d643
KM
168 return (0);
169}
170
171/*
172 * Reclaim an nfsnode so that it can be used for other purposes.
173 */
174nfs_reclaim(vp)
175 register struct vnode *vp;
176{
177 register struct nfsnode *np = VTONFS(vp);
2c5b44a2 178 register struct nfsmount *nmp = VFSTONFS(vp->v_mount);
7efae46b 179 extern int prtactive;
bfb2d643 180
1f7e9641 181 if (prtactive && vp->v_usecount != 0)
b2870bc0 182 vprint("nfs_reclaim: pushing active", vp);
bfb2d643
KM
183 /*
184 * Remove the nfsnode from its hash chain.
185 */
186 remque(np);
2c5b44a2
KM
187
188 /*
189 * For nqnfs, take it off the timer queue as required.
190 */
191 if ((nmp->nm_flag & NFSMNT_NQNFS) && np->n_tnext) {
192 if (np->n_tnext == (struct nfsnode *)nmp)
193 nmp->nm_tprev = np->n_tprev;
194 else
195 np->n_tnext->n_tprev = np->n_tprev;
196 if (np->n_tprev == (struct nfsnode *)nmp)
197 nmp->nm_tnext = np->n_tnext;
198 else
199 np->n_tprev->n_tnext = np->n_tnext;
200 }
bfb2d643 201 cache_purge(vp);
315f50fe 202 FREE(vp->v_data, M_NFSNODE);
2c5b44a2 203 vp->v_data = (void *)0;
a2907882
KM
204 return (0);
205}
206
a2907882
KM
207/*
208 * Lock an nfsnode
209 */
210nfs_lock(vp)
211 struct vnode *vp;
212{
a2907882 213
2c5b44a2 214 return (0);
a2907882
KM
215}
216
217/*
218 * Unlock an nfsnode
219 */
220nfs_unlock(vp)
221 struct vnode *vp;
222{
a2907882 223
2c5b44a2 224 return (0);
a2907882
KM
225}
226
226812f6
KM
227/*
228 * Check for a locked nfsnode
229 */
230nfs_islocked(vp)
231 struct vnode *vp;
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
JH
242int
243nfs_abortop(dvp, cnp)
244 struct vnode *dvp;
245 struct componentname *cnp;
a2907882 246{
a2907882 247
cfef4373
JH
248 if ((cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
249 FREE(cnp->cn_pnbuf, M_NAMEI);
66955caf 250 return (0);
a2907882 251}