1193326Sed/*	 $NetBSD: nfsnode.h,v 1.71 2009/03/14 14:46:11 dsl Exp $	*/
2193326Sed
3193326Sed/*
4193326Sed * Copyright (c) 1989, 1993
5193326Sed *	The Regents of the University of California.  All rights reserved.
6193326Sed *
7193326Sed * This code is derived from software contributed to Berkeley by
8193326Sed * Rick Macklem at The University of Guelph.
9193326Sed *
10193326Sed * Redistribution and use in source and binary forms, with or without
11193326Sed * modification, are permitted provided that the following conditions
12193326Sed * are met:
13193326Sed * 1. Redistributions of source code must retain the above copyright
14212904Sdim *    notice, this list of conditions and the following disclaimer.
15221345Sdim * 2. Redistributions in binary form must reproduce the above copyright
16193326Sed *    notice, this list of conditions and the following disclaimer in the
17193326Sed *    documentation and/or other materials provided with the distribution.
18263508Sdim * 3. Neither the name of the University nor the names of its contributors
19198092Srdivacky *    may be used to endorse or promote products derived from this software
20249423Sdim *    without specific prior written permission.
21239462Sdim *
22212904Sdim * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23212904Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24193326Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25221345Sdim * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26193326Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27193326Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28198092Srdivacky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29198092Srdivacky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30193326Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31249423Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32249423Sdim * SUCH DAMAGE.
33249423Sdim *
34249423Sdim *	@(#)nfsnode.h	8.9 (Berkeley) 5/14/95
35249423Sdim */
36249423Sdim
37249423Sdim
38249423Sdim#ifndef _NFS_NFSNODE_H_
39249423Sdim#define _NFS_NFSNODE_H_
40249423Sdim
41249423Sdim#include <sys/condvar.h>
42249423Sdim#include <sys/mutex.h>
43263508Sdim#include <sys/rbtree.h>
44234353Sdim
45201361Srdivacky#ifndef _NFS_NFS_H_
46193326Sed#include <nfs/nfs.h>
47198092Srdivacky#endif
48193326Sed#include <miscfs/genfs/genfs.h>
49193326Sed#include <miscfs/genfs/genfs_node.h>
50212904Sdim
51193326Sed/*
52224145Sdim * Definitions for the directory cache. Because directory cookies
53224145Sdim * are an opaque 64 bit entity, we need to provide some sort of
54224145Sdim * mapping between cookies and logical blocknumbers. Also,
55224145Sdim * we should store the cookies from the server somewhere,
56224145Sdim * to be able to satisfy VOP_READDIR requests for cookies.
57224145Sdim * We can't store the cookies in the dirent structure, as some
58212904Sdim * other systems.
59193326Sed *
60193326Sed * Each offset is hashed into a per-nfsnode hashtable. An entry
61234353Sdim * found therein contains information about the (faked up)
62234353Sdim * logical blocknumber, and also a pointer to a buffer where
63234353Sdim * the cookies are stored.
64234353Sdim */
65239462Sdim
66239462Sdim
67234353SdimLIST_HEAD(nfsdirhashhead, nfsdircache);
68234353SdimTAILQ_HEAD(nfsdirchainhead, nfsdircache);
69234353Sdim
70234353Sdimstruct nfsdircache {
71234353Sdim	off_t		dc_cookie;		/* Own offset (key) */
72234353Sdim	off_t		dc_blkcookie;		/* Offset of block we're in */
73234353Sdim	LIST_ENTRY(nfsdircache) dc_hash;	/* Hash chain */
74234353Sdim	TAILQ_ENTRY(nfsdircache) dc_chain;	/* Least recently entered chn */
75234353Sdim	u_int32_t	dc_cookie32;		/* Key for 64<->32 xlate case */
76234353Sdim	int		dc_entry;		/* Entry number within block */
77239462Sdim	int		dc_refcnt;		/* Reference count */
78234353Sdim	int		dc_flags;		/* NFSDC_ flags */
79234353Sdim};
80234353Sdim
81234353Sdim#define	NFSDC_INVALID	1
82239462Sdim
83234353Sdim/*
84234353Sdim * NFSDC_BLKNO: get buffer cache index
85234353Sdim */
86234353Sdim#define	NFSDC_BLKNO(ndp)	((daddr_t)(ndp)->dc_blkcookie)
87239462Sdim
88239462Sdim/*
89239462Sdim * The nfsnode is the nfs equivalent to ufs's inode. Any similarity
90239462Sdim * is purely coincidental.
91239462Sdim * There is a unique nfsnode allocated for each active file,
92239462Sdim * each current directory, each mounted-on file, text file, and the root.
93239462Sdim * An nfsnode is 'named' by its file handle. (nget/nfs_node.c)
94239462Sdim */
95239462Sdim
96239462Sdimstruct nfsnode_spec {
97239462Sdim	struct timespec	nspec_mtim;	/* local mtime */
98239462Sdim	struct timespec	nspec_atim;	/* local atime */
99239462Sdim};
100239462Sdim
101239462Sdimstruct nfsnode_reg {
102239462Sdim	off_t nreg_pushedlo;		/* 1st blk in commited range */
103239462Sdim	off_t nreg_pushedhi;		/* Last block in range */
104239462Sdim	off_t nreg_pushlo;		/* 1st block in commit range */
105239462Sdim	off_t nreg_pushhi;		/* Last block in range */
106239462Sdim	kmutex_t nreg_commitlock;	/* Serialize commits XXX */
107239462Sdim	int nreg_commitflags;
108239462Sdim	int nreg_error;			/* Save write error value */
109239462Sdim};
110239462Sdim
111239462Sdimstruct nfsnode_dir {
112239462Sdim	off_t ndir_direof;		/* EOF offset cache */
113263508Sdim	nfsuint64 ndir_cookieverf;	/* Cookie verifier */
114239462Sdim	struct nfsdirhashhead *ndir_dircache; /* offset -> cache hash heads */
115239462Sdim	struct nfsdirchainhead ndir_dirchain; /* Chain of dir cookies */
116239462Sdim	struct timespec ndir_nctime;	/* Last name cache entry */
117239462Sdim	unsigned ndir_dircachesize;	/* Size of dir cookie cache */
118239462Sdim};
119239462Sdim
120239462Sdimstruct nfsnode {
121239462Sdim	struct genfs_node	n_gnode;
122239462Sdim	u_quad_t		n_size;		/* Current size of file */
123239462Sdim
124193326Sed	union {
125193326Sed		struct nfsnode_spec	nu_spec;
126193326Sed		struct nfsnode_reg	nu_reg;
127193326Sed		struct nfsnode_dir	nu_dir;
128193326Sed	} n_un1;
129193326Sed
130193326Sed#define n_mtim		n_un1.nu_spec.nspec_mtim
131193326Sed#define n_atim		n_un1.nu_spec.nspec_atim
132251662Sdim
133212904Sdim#define	n_pushedlo	n_un1.nu_reg.nreg_pushedlo
134218893Sdim#define	n_pushedhi	n_un1.nu_reg.nreg_pushedhi
135221345Sdim#define	n_pushlo	n_un1.nu_reg.nreg_pushlo
136234353Sdim#define	n_pushhi	n_un1.nu_reg.nreg_pushhi
137226633Sdim#define n_commitlock	n_un1.nu_reg.nreg_commitlock
138226633Sdim#define n_commitflags	n_un1.nu_reg.nreg_commitflags
139199990Srdivacky#define n_error		n_un1.nu_reg.nreg_error
140199990Srdivacky
141199990Srdivacky#define n_direofoffset	n_un1.nu_dir.ndir_direof
142212904Sdim#define n_cookieverf	n_un1.nu_dir.ndir_cookieverf
143199990Srdivacky#define n_dircache	n_un1.nu_dir.ndir_dircache
144199990Srdivacky#define	n_dirchain	n_un1.nu_dir.ndir_dirchain
145207619Srdivacky#define	n_nctime	n_un1.nu_dir.ndir_nctime
146199990Srdivacky#define	n_dircachesize	n_un1.nu_dir.ndir_dircachesize
147199990Srdivacky
148199990Srdivacky	union {
149199990Srdivacky		struct sillyrename *nf_silly;	/* !VDIR: silly rename struct */
150199990Srdivacky		unsigned *ndir_dirgens;		/* 32<->64bit xlate gen. no. */
151199990Srdivacky	} n_un2;
152199990Srdivacky
153199990Srdivacky#define n_sillyrename	n_un2.nf_silly
154199990Srdivacky#define n_dirgens	n_un2.ndir_dirgens
155199990Srdivacky
156199990Srdivacky	struct rb_node		n_rbnode;	/* red/black node */
157199990Srdivacky	nfsfh_t			*n_fhp;		/* NFS File Handle */
158199990Srdivacky	struct vattr		*n_vattr;	/* Vnode attribute cache */
159234353Sdim	struct vnode		*n_vnode;	/* associated vnode */
160212904Sdim	struct lockf		*n_lockf;	/* Locking record of file */
161199990Srdivacky	time_t			n_attrstamp;	/* Attr. cache timestamp */
162210299Sed	struct timespec		n_mtime;	/* Prev modify time. */
163210299Sed	time_t			n_ctime;	/* Prev create time. */
164221345Sdim	short			n_fhsize;	/* size in bytes, of fh */
165221345Sdim	short			n_flag;		/* Flag for locking.. */
166221345Sdim	nfsfh_t			n_fh;		/* Small File Handle */
167221345Sdim	time_t			n_accstamp;	/* Access cache timestamp */
168212904Sdim	uid_t			n_accuid;	/* Last access requester */
169221345Sdim	int			n_accmode;	/* Mode last requested */
170221345Sdim	int			n_accerror;	/* Error last returned */
171221345Sdim	kauth_cred_t		n_rcred;
172221345Sdim	kauth_cred_t		n_wcred;
173199990Srdivacky};
174199990Srdivacky
175212904Sdim/*
176199990Srdivacky * Values for n_commitflags
177199990Srdivacky */
178207619Srdivacky#define NFS_COMMIT_PUSH_VALID	0x0001		/* push range valid */
179207619Srdivacky#define NFS_COMMIT_PUSHED_VALID	0x0002		/* pushed range valid */
180212904Sdim
181198092Srdivacky/*
182201361Srdivacky * Flags for n_flag
183201361Srdivacky */
184201361Srdivacky#define	NFLUSHWANT	0x0001	/* Want wakeup from a flush in prog. */
185201361Srdivacky#define	NFLUSHINPROG	0x0002	/* Avoid multiple calls to vinvalbuf() */
186201361Srdivacky#define	NMODIFIED	0x0004	/* Might have a modified buffer in bio */
187201361Srdivacky#define	NWRITEERR	0x0008	/* Flag write errors so close will know */
188199990Srdivacky#define	NACC		0x0100	/* Special file accessed */
189199990Srdivacky#define	NUPD		0x0200	/* Special file updated */
190199990Srdivacky#define	NCHG		0x0400	/* Special file times changed */
191199990Srdivacky#define	NTRUNCDELAYED	0x1000	/* Should be truncated later;
192199990Srdivacky				   implies stale cache */
193199990Srdivacky#define	NREMOVED	0x2000	/* Has been removed */
194198092Srdivacky#define	NUSEOPENCRED	0x4000	/* Try open cred first rather than owner's */
195199990Srdivacky#define	NEOFVALID	0x8000	/* dir: n_direofoffset is valid */
196199990Srdivacky
197199990Srdivacky#define	NFS_EOFVALID(ndp)	((ndp)->n_flag & NEOFVALID)
198199990Srdivacky
199199990Srdivacky/*
200199990Srdivacky * Convert between nfsnode pointers and vnode pointers
201199990Srdivacky */
202199990Srdivacky#define VTONFS(vp)	((struct nfsnode *)(vp)->v_data)
203199990Srdivacky#define NFSTOV(np)	((np)->n_vnode)
204199990Srdivacky
205199990Srdivacky#ifdef _KERNEL
206199990Srdivacky
207199990Srdivacky#include <sys/workqueue.h>
208199990Srdivacky/*
209193326Sed * Silly rename structure that hangs off the nfsnode until the name
210199482Srdivacky * can be removed by nfs_inactive()
211193326Sed */
212202379Srdivackystruct sillyrename {
213226633Sdim	struct work	s_work;
214239462Sdim	kauth_cred_t	s_cred;
215226633Sdim	struct	vnode *s_dvp;
216234353Sdim	long	s_namlen;
217226633Sdim	char	s_name[20];
218226633Sdim};
219226633Sdim
220226633Sdim/*
221226633Sdim * Per-nfsiod datas
222226633Sdim */
223226633Sdimstruct nfs_iod {
224226633Sdim	kmutex_t nid_lock;
225226633Sdim	kcondvar_t nid_cv;
226226633Sdim	LIST_ENTRY(nfs_iod) nid_idle;
227226633Sdim	struct nfsmount *nid_mount;
228226633Sdim	bool nid_exiting;
229226633Sdim
230226633Sdim	LIST_ENTRY(nfs_iod) nid_all;
231226633Sdim};
232234353Sdim
233226633SdimLIST_HEAD(nfs_iodlist, nfs_iod);
234226633Sdimextern kmutex_t nfs_iodlist_lock;
235226633Sdimextern struct nfs_iodlist nfs_iodlist_idle;
236226633Sdimextern struct nfs_iodlist nfs_iodlist_all;
237234353Sdimextern u_long nfsdirhashmask;
238226633Sdim
239226633Sdim/*
240263508Sdim * Prototypes for NFS vnode operations
241263508Sdim */
242263508Sdimint	nfs_lookup(void *);
243226633Sdimint	nfs_create(void *);
244226633Sdimint	nfs_mknod(void *);
245226633Sdimint	nfs_open(void *);
246226633Sdimint	nfs_close(void *);
247226633Sdimint	nfsspec_close(void *);
248226633Sdimint	nfsfifo_close(void *);
249226633Sdimint	nfs_access(void *);
250226633Sdimint	nfsspec_access(void *);
251193326Sedint	nfs_getattr(void *);
252199482Srdivackyint	nfs_setattr(void *);
253203955Srdivackyint	nfs_read(void *);
254212904Sdimint	nfs_write(void *);
255193326Sedint	nfsspec_read(void *);
256198893Srdivackyint	nfsspec_write(void *);
257198092Srdivackyint	nfsfifo_read(void *);
258198092Srdivackyint	nfsfifo_write(void *);
259198092Srdivacky#define	nfs_ioctl	genfs_enoioctl
260198092Srdivacky#define	nfs_poll	genfs_poll
261198092Srdivacky#define nfs_revoke	genfs_revoke
262199482Srdivacky#define	nfs_mmap	genfs_mmap
263199482Srdivackyint	nfs_fsync(void *);
264212904Sdim#define nfs_seek	genfs_seek
265199482Srdivackyint	nfs_remove(void *);
266198092Srdivackyint	nfs_link(void *);
267193326Sedint	nfs_rename(void *);
268193326Sedint	nfs_mkdir(void *);
269193326Sedint	nfs_rmdir(void *);
270193326Sedint	nfs_symlink(void *);
271198092Srdivackyint	nfs_readdir(void *);
272198092Srdivackyint	nfs_readlink(void *);
273193326Sed#define	nfs_abortop	genfs_abortop
274193326Sedint	nfs_inactive(void *);
275193326Sedint	nfs_reclaim(void *);
276193326Sed#define nfs_lock	genfs_lock
277193326Sedint	nfs_unlock(void *);
278193326Sed#define nfs_islocked	genfs_islocked
279193326Sedint	nfs_bmap(void *);
280193326Sedint	nfs_strategy(void *);
281193326Sedint	nfs_print(void *);
282193326Sedint	nfs_pathconf(void *);
283193326Sedint	nfs_advlock(void *);
284193326Sedint	nfs_getpages(void *);
285199482Srdivackyint	nfs_putpages(void *);
286212904Sdimint	nfs_kqfilter(void *);
287193326Sed
288193326Sedextern int (**nfsv2_vnodeop_p)(void *);
289193326Sed
290193326Sed#define	NFS_INVALIDATE_ATTRCACHE(np)	(np)->n_attrstamp = 0
291193326Sed
292193326Sed#endif /* _KERNEL */
293193326Sed
294193326Sed#endif
295193326Sed