xref: /titanic_44/usr/src/uts/common/sys/fs/cachefs_fs.h (revision d2ec54f7875f7e05edd56195adbeb593c947763f)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef _SYS_FS_CACHEFS_FS_H
28 #define	_SYS_FS_CACHEFS_FS_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #include <sys/vnode.h>
33 #include <sys/vfs.h>
34 #include <sys/types.h>
35 #include <sys/types32.h>
36 #include <sys/t_lock.h>
37 #include <sys/thread.h>
38 #include <sys/kmem.h>
39 #include <sys/inttypes.h>
40 #include <sys/time_impl.h>
41 #include <sys/systm.h>
42 
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 
47 #ifdef CFSDEBUG
48 #define	CFSDEBUG_ALL		0xffffffff
49 #define	CFSDEBUG_NONE		0x0
50 #define	CFSDEBUG_GENERAL	0x1
51 #define	CFSDEBUG_SUBR		0x2
52 #define	CFSDEBUG_CNODE		0x4
53 #define	CFSDEBUG_DIR		0x8
54 #define	CFSDEBUG_STRICT		0x10
55 #define	CFSDEBUG_VOPS		0x20
56 #define	CFSDEBUG_VFSOP		0x40
57 #define	CFSDEBUG_RESOURCE	0x80
58 #define	CFSDEBUG_CHEAT		0x100
59 #define	CFSDEBUG_INVALIDATE	0x200
60 #define	CFSDEBUG_DLOG		0x400
61 #define	CFSDEBUG_FILEGRP	0x800
62 #define	CFSDEBUG_IOCTL		0x1000
63 #define	CFSDEBUG_FRONT		0x2000
64 #define	CFSDEBUG_BACK		0x4000
65 #define	CFSDEBUG_ALLOCMAP	0x8000
66 #define	CFSDEBUG_ASYNCPOP	0x10000
67 #define	CFSDEBUG_VOPS_NFSV4	0x20000
68 
69 #define	CFSCLEANFLAG
70 
71 extern int cachefsdebug;
72 
73 #define	CFS_DEBUG(N)    if (cachefsdebug & (N))
74 #endif /* DEBUG */
75 
76 #if 0
77 #ifdef CFSDEBUG
78 	/*
79 	 * Testing usage of cd_access and friends.
80 	 * Note we steal an unused bit in t_flag.
81 	 * This will certainly bite us later.
82 	 */
83 #define	CFS_CD_DEBUG
84 #define	T_CD_HELD	0x01000
85 #endif
86 #endif
87 
88 /*
89  * Note: in an RL debugging kernel, CFSVERSION is augmented by 100
90  *
91  * Version History:
92  *
93  * Beginning -- Solaris 2.3 and 2.4: 1
94  *
95  * In Solaris 2.5 alpha, the size of fid_t changed: 2
96  *
97  * In 2.6: Chart, RL pointers/idents became rl_entry: 3
98  *	added which RL list to attrcache header: 4
99  *
100  * Large Files support made version to 6.
101  *
102  * Sequence numbers made version to 7.
103  *
104  * 64-bit on-disk cache will make version 8. Not yet supported.
105  */
106 
107 #if 0
108 #define	CFSRLDEBUG
109 #endif
110 
111 #ifdef CFSRLDEBUG
112 #define	CFSVERSION		110
113 #define	CFSVERSION64		111	/* 64-bit cache - not yet used */
114 #else /* CFSRLDEBUG */
115 #define	CFSVERSION		7
116 #define	CFSVERSION64		8	/* 64-bit cache - not yet used */
117 #endif /* CFSRLDEBUG */
118 
119 /* Some default values */
120 #define	DEF_FILEGRP_SIZE	256
121 #define	DEF_POP_SIZE		0x10000		/* 64K */
122 #define	CACHELABEL_NAME		".cfs_label"
123 #define	RESOURCE_NAME		".cfs_resource"
124 #define	CACHEFS_FSINFO		".cfs_fsinfo"
125 #define	ATTRCACHE_NAME		".cfs_attrcache"
126 #define	CACHEFS_LOSTFOUND_NAME	"lost+found"
127 #define	BACKMNT_NAME		".cfs_mnt_points"
128 #define	CACHEFS_LOCK_FILE	".cfs_lock"
129 #define	CACHEFS_DLOG_FILE	".cfs_dlog"
130 #define	CACHEFS_DMAP_FILE	".cfs_dmap"
131 #define	CACHEFS_MNT_FILE	".cfs_mnt"
132 #define	CACHEFS_UNMNT_FILE	".cfs_unmnt"
133 #define	LOG_STATUS_NAME		".cfs_logging"
134 #define	NOBACKUP_NAME		".nsr"
135 #define	CACHEFS_PREFIX		".cfs_"
136 #define	CACHEFS_PREFIX_LEN	5
137 #define	ROOTLINK_NAME		"root"
138 #define	CFS_FRONTFILE_NAME_SIZE	18
139 #define	CACHEFS_BASETYPE	"cachefs" /* used in statvfs() */
140 #define	CFS_MAXFREECNODES	20
141 #define	CACHEFSTAB		"/etc/cachefstab"
142 #define	CACHEFS_ROOTRUN		"/var/run"
143 #define	CACHEFS_LOCKDIR_PRE	".cachefs." /* used by mount(1M)/fsck(1M) */
144 
145 /*
146  * The options structure is passed in as part of the mount arguments.
147  * It is stored in the .options file and kept track of in the fscache
148  * structure.
149  */
150 struct cachefsoptions {
151 	uint_t		opt_flags;		/* mount flags */
152 	int		opt_popsize;		/* cache population size */
153 	int		opt_fgsize;		/* filegrp size, default 256 */
154 };
155 
156 typedef struct cachefscache cachefscache_t;
157 
158 /*
159  * all the stuff needed to manage a queue of requests to be processed
160  * by async threads.
161  */
162 struct cachefs_workq {
163 	struct cachefs_req	*wq_head;		/* head of work q */
164 	struct cachefs_req	*wq_tail;		/* tail of work q */
165 	int			wq_length;		/* # of requests on q */
166 	int			wq_thread_count;	/* # of threads */
167 	int			wq_max_len;		/* longest queue */
168 	int			wq_halt_request;	/* halt requested */
169 	unsigned int		wq_keepone:1;		/* keep one thread */
170 	unsigned int		wq_logwork:1;		/* write logfile */
171 	kcondvar_t		wq_req_cv;		/* wait on work to do */
172 	kcondvar_t		wq_halt_cv;		/* wait/signal halt */
173 	kmutex_t		wq_queue_lock;		/* protect queue */
174 	cachefscache_t		*wq_cachep;		/* sometimes NULL */
175 };
176 
177 /*
178  * cfs_cid is stored on disk, so it needs to be the same 32-bit vs. 64-bit.
179  */
180 
181 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
182 #pragma pack(4)
183 #endif
184 
185 /* identifies a file in the cache */
186 struct cfs_cid {
187 	ino64_t	cid_fileno;		/* fileno */
188 	int	cid_flags;		/* flags */
189 };
190 typedef struct cfs_cid cfs_cid_t;
191 #define	CFS_CID_LOCAL	1	/* local file */
192 
193 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
194 #pragma pack()
195 #endif
196 
197 /*
198  * XX64 - for now redefine	all time_t fields that are used by both kernel
199  * and user space apps as a 32-bit quantity,
200  */
201 
202 #if (defined(_SYSCALL32) && defined(_LP64))
203 
204 /*
205  * The cfs_* types are used to represent on-disk data, since its size is
206  * independent of the kernel memory model (in the LP64 case)
207  */
208 typedef time32_t		cfs_time_t;
209 typedef timestruc32_t		cfs_timestruc_t;
210 typedef vattr32_t		cfs_vattr_t;
211 typedef fid32_t			cfs_fid_t;
212 
213 #define	cfs_timespec		timespec32
214 #define	cfs_vattr		vattr32
215 #define	cfs_fid			fid32
216 
217 /*
218  * CACHEFS_DEV_COPY copies between two dev_t's. It expands or compresses
219  * them based on type changes (if needed).
220  */
221 #define	CACHEFS_DEV_TO_DEV32_COPY(in_dev, out_dev, error)		\
222 	if (cmpldev((dev32_t *)&(out_dev), in_dev) == 0)		\
223 		error = EOVERFLOW;
224 
225 #define	CACHEFS_DEV32_TO_DEV_COPY(in_dev, out_dev)			\
226 	out_dev = (dev_t)expldev(in_dev);
227 
228 #define	TIME_OVERFLOW(tval)						\
229 	((tval) < TIME32_MIN || (tval) > TIME32_MAX)
230 
231 /* Set the referred to time value. Set error if overflow */
232 #define	CACHEFS_TIME_TO_TIME32_COPY(in_tval, out_tval, error)		\
233 	out_tval = (in_tval);						\
234 	if (TIME_OVERFLOW(in_tval))					\
235 		error = EOVERFLOW;
236 
237 #define	CACHEFS_TIME32_TO_TIME_COPY(in_tval, out_tval)			\
238 	out_tval = (in_tval);
239 
240 /* Set the cfs_timestruc_t with values from input timestruc_t */
241 #define	CACHEFS_TS_TO_TS32_COPY(in_tsp, out_tsp, error)			\
242 	(out_tsp)->tv_nsec = (in_tsp)->tv_nsec;				\
243 	CACHEFS_TIME_TO_TIME32_COPY((in_tsp)->tv_sec, (out_tsp)->tv_sec, error)
244 
245 #define	CACHEFS_TS32_TO_TS_COPY(in_tsp, out_tsp)			\
246 	(out_tsp)->tv_nsec = (in_tsp)->tv_nsec;				\
247 	CACHEFS_TIME32_TO_TIME_COPY((in_tsp)->tv_sec, (out_tsp)->tv_sec)
248 
249 /* CACHEFS_FID_COPY copies between two fids */
250 #define	CACHEFS_FID_COPY(in_fidp, out_fidp)				\
251 	(out_fidp)->fid_len = (in_fidp)->fid_len;			\
252 	bcopy((in_fidp)->fid_data, (out_fidp)->fid_data, (in_fidp)->fid_len)
253 
254 #define	CACHEFS_VATTR_TO_VATTR32_COPY(in_vattrp, out_vattrp, error)	\
255 	(out_vattrp)->va_mask = (in_vattrp)->va_mask;			\
256 	(out_vattrp)->va_type = (in_vattrp)->va_type;			\
257 	(out_vattrp)->va_mode = (in_vattrp)->va_mode;			\
258 	(out_vattrp)->va_uid = (in_vattrp)->va_uid;			\
259 	(out_vattrp)->va_gid = (in_vattrp)->va_gid;			\
260 	CACHEFS_DEV_TO_DEV32_COPY((in_vattrp)->va_fsid,			\
261 		(out_vattrp)->va_fsid, error);				\
262 	(out_vattrp)->va_nodeid = (in_vattrp)->va_nodeid;		\
263 	(out_vattrp)->va_nlink = (in_vattrp)->va_nlink;			\
264 	(out_vattrp)->va_size = (in_vattrp)->va_size;			\
265 	CACHEFS_TS_TO_TS32_COPY(&(in_vattrp)->va_atime,			\
266 		&(out_vattrp)->va_atime, error);			\
267 	CACHEFS_TS_TO_TS32_COPY(&(in_vattrp)->va_mtime,			\
268 		&(out_vattrp)->va_mtime, error);			\
269 	CACHEFS_TS_TO_TS32_COPY(&(in_vattrp)->va_ctime, 		\
270 		&(out_vattrp)->va_ctime, error);			\
271 	CACHEFS_DEV_TO_DEV32_COPY((in_vattrp)->va_rdev,			\
272 		(out_vattrp)->va_rdev, error);				\
273 	(out_vattrp)->va_blksize = (in_vattrp)->va_blksize;		\
274 	(out_vattrp)->va_nblocks = (in_vattrp)->va_nblocks;		\
275 	(out_vattrp)->va_seq = 0
276 
277 #define	CACHEFS_VATTR32_TO_VATTR_COPY(in_vattrp, out_vattrp)		\
278 	(out_vattrp)->va_mask = (in_vattrp)->va_mask;			\
279 	(out_vattrp)->va_type = (in_vattrp)->va_type;			\
280 	(out_vattrp)->va_mode = (in_vattrp)->va_mode;			\
281 	(out_vattrp)->va_uid = (in_vattrp)->va_uid;			\
282 	(out_vattrp)->va_gid = (in_vattrp)->va_gid;			\
283 	CACHEFS_DEV32_TO_DEV_COPY((in_vattrp)->va_fsid,			\
284 		(out_vattrp)->va_fsid);					\
285 	(out_vattrp)->va_nodeid = (in_vattrp)->va_nodeid;		\
286 	(out_vattrp)->va_nlink = (in_vattrp)->va_nlink;			\
287 	(out_vattrp)->va_size = (in_vattrp)->va_size;			\
288 	CACHEFS_TS32_TO_TS_COPY(&(in_vattrp)->va_atime,			\
289 		&(out_vattrp)->va_atime);				\
290 	CACHEFS_TS32_TO_TS_COPY(&(in_vattrp)->va_mtime,			\
291 		&(out_vattrp)->va_mtime);				\
292 	CACHEFS_TS32_TO_TS_COPY(&(in_vattrp)->va_ctime,			\
293 		&(out_vattrp)->va_ctime);				\
294 	CACHEFS_DEV32_TO_DEV_COPY((in_vattrp)->va_rdev,			\
295 		(out_vattrp)->va_rdev);					\
296 	(out_vattrp)->va_blksize = (in_vattrp)->va_blksize;		\
297 	(out_vattrp)->va_nblocks = (in_vattrp)->va_nblocks;		\
298 	(out_vattrp)->va_seq = 0
299 
300 #else /* not _SYSCALL32 && _LP64 */
301 
302 /*
303  * The cfs_* types are used to represent on-disk data, since its size is
304  * independent of the kernel memory model (in the LP64 case)
305  */
306 typedef time_t			cfs_time_t;
307 typedef timestruc_t		cfs_timestruc_t;
308 typedef vattr_t			cfs_vattr_t;
309 typedef fid_t			cfs_fid_t;
310 
311 #define	cfs_timespec		timespec
312 #define	cfs_vattr		vattr
313 #define	cfs_fid			fid
314 
315 #define	TIME_OVERFLOW(tval)	FALSE
316 
317 #define	CACHEFS_DEV_TO_DEV32_COPY(in_dev, out_dev, error)		\
318 	out_dev = (in_dev)
319 
320 #define	CACHEFS_DEV32_TO_DEV_COPY(in_dev, out_dev)			\
321 	out_dev = (in_dev)
322 
323 #define	CACHEFS_TIME_TO_TIME32_COPY(in_tval, out_tval, error)		\
324 	out_tval = (in_tval)
325 
326 #define	CACHEFS_TIME32_TO_TIME_COPY(in_tval, out_tval)			\
327 	out_tval = (in_tval)
328 
329 #define	CACHEFS_TS_TO_TS32_COPY(in_tsp, out_tsp, error)			\
330 	*(out_tsp) = *(in_tsp)
331 
332 #define	CACHEFS_TS32_TO_TS_COPY(in_tsp, out_tsp)			\
333 	*(out_tsp) = *(in_tsp)
334 
335 #define	CACHEFS_FID_COPY(in_fidp, out_fidp)				\
336 	*(out_fidp) = *(in_fidp)
337 
338 #define	CACHEFS_VATTR_TO_VATTR32_COPY(in_vattrp, out_vattrp, error)	\
339 	*(out_vattrp) = *(in_vattrp);					\
340 	(out_vattrp)->va_seq = 0
341 
342 #define	CACHEFS_VATTR32_TO_VATTR_COPY(in_vattrp, out_vattrp)		\
343 	*(out_vattrp) = *(in_vattrp);					\
344 	(out_vattrp)->va_seq = 0
345 
346 #endif /* _SYSCALL32 && _LP64 */
347 
348 /*
349  * The "cfs_*" structs below refer to the on-disk structures. Presently
350  * they are 32-bit based. When they change to 64-bit, we'd have to modify the
351  * macros below accordingly.
352  */
353 #define	CACHEFS_DEV_TO_CFS_DEV_COPY(in_dev, out_dev, error)		\
354 	CACHEFS_DEV_TO_DEV32_COPY(in_dev, out_dev, error)
355 
356 #define	CACHEFS_CFS_DEV_TO_DEV_COPY(in_dev, out_dev)		\
357 	CACHEFS_DEV32_TO_DEV_COPY(in_dev, out_dev)
358 
359 #define	CACHEFS_TIME_TO_CFS_TIME_COPY(in_tval, out_tval, error)		\
360 	CACHEFS_TIME_TO_TIME32_COPY(in_tval, out_tval, error)
361 
362 #define	CACHEFS_CFS_TIME_TO_TIME_COPY(in_tval, out_tval)		\
363 	CACHEFS_TIME32_TO_TIME_COPY(in_tval, out_tval)
364 
365 #define	CACHEFS_TS_TO_CFS_TS_COPY(in_tsp, out_tsp, error)		\
366 	CACHEFS_TS_TO_TS32_COPY(in_tsp, out_tsp, error)
367 
368 #define	CACHEFS_CFS_TS_TO_TS_COPY(in_tsp, out_tsp)			\
369 	CACHEFS_TS32_TO_TS_COPY(in_tsp, out_tsp)
370 
371 #define	CACHEFS_VATTR_TO_CFS_VATTR_COPY(in_vattrp, out_vattrp, error)	\
372 	CACHEFS_VATTR_TO_VATTR32_COPY(in_vattrp, out_vattrp, error)
373 
374 #define	CACHEFS_CFS_VATTR_TO_VATTR_COPY(in_vattrp, out_vattrp)		\
375 	CACHEFS_VATTR32_TO_VATTR_COPY(in_vattrp, out_vattrp)
376 
377 #include <sys/fs/cachefs_fscache.h>
378 #include <sys/fs/cachefs_filegrp.h>
379 
380 /*
381  * One cache_label structure per cache. Contains mainly user defined or
382  * default values for cache resource management. Contents is static.
383  * The value cl_maxfiles is not used any where in cachefs code. If and when
384  * this is really used the cl_maxfiles should be declared as a 64bit value
385  * for large file support.
386  * The maxblks, blkhiwat, blklowat, blocktresh, blockmin, may need to be
387  * 64bit values when we actually start supporting file systems of size
388  * greater than 1 terabyte.
389  */
390 struct cache_label {
391 	int	cl_cfsversion;	/* cfs version number */
392 	int	cl_maxblks;	/* max blocks to be used by cache */
393 	int	cl_blkhiwat;	/* high water-mark for block usage */
394 	int	cl_blklowat;	/* low water-mark for block usage */
395 	int	cl_maxinodes;	/* max inodes to be used by cache */
396 	int	cl_filehiwat;	/* high water-mark for inode usage */
397 	int	cl_filelowat;	/* low water-mark for indoe usage */
398 	int	cl_blocktresh;	/* block max usage treshold */
399 	int	cl_blockmin;	/* block min usage treshold */
400 	int	cl_filetresh;	/* inode max usage treshold */
401 	int	cl_filemin;	/* inode min usage treshold */
402 	int	cl_maxfiles;	/* max cache file size */
403 };
404 
405 /*
406  * One cache_usage structure per cache. Keeps track of cache usage figures.
407  * Contents gets updated frequently.
408  */
409 struct cache_usage {
410 	int	cu_blksused;	/* actual number of blocks used */
411 	int	cu_filesused;	/* actual number of files used */
412 	uint_t	cu_flags;	/* Cache state flags */
413 	ushort_t cu_unique;	/* Fid persistent uniquifier */
414 };
415 
416 #define	CUSAGE_ACTIVE	1	/* Cache is active */
417 #define	CUSAGE_NEED_ADJUST 2	/* Adjust uniquifier before assigning new fid */
418 
419 /*
420  * RL list identifiers.
421  */
422 enum cachefs_rl_type {
423 	CACHEFS_RL_NONE = 0x101,
424 	CACHEFS_RL_FREE,
425 	CACHEFS_RL_GC,
426 	CACHEFS_RL_ACTIVE,
427 	CACHEFS_RL_ATTRFILE,
428 	CACHEFS_RL_MODIFIED,
429 	CACHEFS_RL_PACKED,
430 	CACHEFS_RL_PACKED_PENDING,
431 	CACHEFS_RL_MF
432 };
433 #define	CACHEFS_RL_START CACHEFS_RL_NONE
434 #define	CACHEFS_RL_END CACHEFS_RL_MF
435 #define	CACHEFS_RL_CNT	(CACHEFS_RL_END - CACHEFS_RL_START + 1)
436 #define	CACHEFS_RL_INDEX(X)	(X - CACHEFS_RL_START)
437 
438 struct cachefs_rl_listhead {
439 	uint_t		rli_front;		/* front of list */
440 	uint_t		rli_back;		/* back of list */
441 	int		rli_blkcnt;		/* number of 8k blocks */
442 	int		rli_itemcnt;		/* number of items on list */
443 };
444 typedef struct cachefs_rl_listhead cachefs_rl_listhead_t;
445 
446 /*
447  * Resource List information.  One per cache.
448  */
449 struct cachefs_rl_info {
450 	uint_t		rl_entries;	/* number of entries allocated in rl */
451 	cfs_time_t	rl_gctime;	/* time of item on front of gc list */
452 
453 	/* heads of the various lists */
454 	cachefs_rl_listhead_t	rl_items[CACHEFS_RL_CNT];
455 };
456 typedef struct cachefs_rl_info cachefs_rl_info_t;
457 
458 /*
459  * rl_debug and rl_entry are stored on disk, so they need to be
460  * the same 32-bit vs. 64-bit.
461  */
462 
463 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
464 #pragma pack(4)
465 #endif
466 
467 #ifdef CFSRLDEBUG
468 /*
469  * RL debugging thingy
470  */
471 
472 #define	CACHEFS_RLDB_STACKSIZE	16
473 #define	CACHEFS_RLDB_DEF_MAXCOUNT 5
474 
475 typedef struct rl_debug {
476 	hrtime_t db_hrtime;
477 
478 	uint_t db_attrc: 1;
479 	uint_t db_fsck: 1;
480 	ino64_t db_fsid;
481 	ino64_t db_fileno;
482 	enum cachefs_rl_type db_current;
483 
484 	int db_stackheight;
485 	pc_t db_stack[CACHEFS_RLDB_STACKSIZE];
486 
487 	struct rl_debug *db_next;
488 } rl_debug_t;
489 
490 extern time_t cachefs_dbvalid;
491 extern struct kmem_cache *cachefs_rl_debug_cache;
492 extern kmutex_t cachefs_rl_debug_mutex;
493 #endif /* CFSRLDEBUG */
494 
495 /*
496  * RL Entry type.
497  */
498 
499 typedef struct rl_entry {
500 	uint_t rl_attrc: 1;
501 	uint_t rl_fsck: 1; /* used by fsck; true => rl_current is correct */
502 	uint_t rl_local: 1; /* 1 means a local file */
503 
504 #ifdef CFSRLDEBUG
505 	cfs_time_t rl_dbvalid; /* this == cachefs_dbvalid => trust rl_debug */
506 	rl_debug_t *rl_debug;
507 #endif /* CFSRLDEBUG */
508 
509 	ino64_t rl_fsid;
510 	ino64_t rl_fileno;
511 
512 	enum cachefs_rl_type rl_current;
513 	uint_t rl_fwd_idx;
514 	uint_t rl_bkwd_idx;
515 } rl_entry_t;
516 
517 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
518 #pragma pack()
519 #endif
520 
521 /*
522  * rl entries per MAXBSIZE chunk.  rl_entry_t's size need not divide
523  * MAXBSIZE, as long as this constant is an integer (through integer
524  * division) (see cachefs_rl_entry_get()).
525  */
526 
527 #define	CACHEFS_RLPMBS	(MAXBSIZE / (uint_t)sizeof (rl_entry_t))
528 
529 /*
530  * struct cache contains cache-wide information, and provides access
531  * to lower level info. There is one cache structure per cache.
532  */
533 struct cachefscache {
534 	struct cachefscache	*c_next;	/* list of caches */
535 	uint_t			c_flags;	/* misc flags */
536 	struct cache_label	c_label;	/* cache resource info */
537 	struct cache_usage	c_usage;	/* cache usage info */
538 	struct cachefs_rl_info	c_rlinfo;	/* rl global pointers */
539 	struct vnode		*c_resfilevp;	/* resource file vp */
540 	uint_t			c_rl_window;	/* window mapped in */
541 	rl_entry_t		*c_rl_entries;	/* mapping for rl entries */
542 	struct vnode		*c_dirvp;	/* cache directory vp */
543 	struct vnode		*c_lockvp;	/* lock file vp */
544 	struct vnode		*c_lostfoundvp;	/* lost+found directory vp */
545 	int			c_refcnt;	/* active fs ref count */
546 	struct fscache		*c_fslist;	/* fscache list head */
547 	struct cachefs_workq	c_workq;	/* async work */
548 	kmutex_t		c_contentslock; /* protect cache struct */
549 	kmutex_t		c_fslistlock;	/* protect fscache list */
550 	kmutex_t		c_mflock;	/* protect modified fixes */
551 	ushort_t		c_unique;	/* In core fid uniquifier */
552 	kcondvar_t		c_cwcv;		/* gc wait on work to do */
553 	kcondvar_t		c_cwhaltcv;	/* wait on gc thread exit */
554 	uint_t			c_gc_count;	/* garbage collection count */
555 	time_t			c_gc_time;	/* last garbage collection */
556 	time_t			c_gc_before;	/* atime of front before gc */
557 	time_t			c_gc_after;	/* atime of front after gc */
558 	uint_t			c_apop_inqueue;	/* # async pops queued */
559 	pid_t			c_rootdaemonid;	/* pid of root cachefsd */
560 	struct cachefs_log_cookie
561 				*c_log;		/* in-core logging stuff */
562 	struct cachefs_log_control
563 				*c_log_ctl;	/* on-disk logging stuff */
564 	kmutex_t		c_log_mutex;	/* protects c_log* */
565 };
566 
567 extern struct kmem_cache *cachefs_cache_kmcache;
568 
569 #define	CACHEFS_MAX_APOP_INQUEUE	50	/* default value for below */
570 extern uint_t cachefs_max_apop_inqueue;		/* max populations pending */
571 
572 /*
573  * Various cache structure flags.
574  */
575 #define	CACHE_NOCACHE		0x1	/* all cache refs go to back fs */
576 #define	CACHE_ALLOC_PENDING	0x4	/* Allocation pending */
577 #define	CACHE_NOFILL		0x8	/* No fill mode */
578 #define	CACHE_GARBAGE_COLLECT	0x10	/* Garbage collect in progress */
579 #define	CACHE_CACHEW_THREADRUN	0x20	/* Cachep worker thread is alive */
580 #define	CACHE_CACHEW_THREADEXIT 0x40	/* cachew thread should exit */
581 #define	CACHE_DIRTY		0x80
582 #define	CACHE_PACKED_PENDING	0x100	/* Packed pending work to do */
583 #define	CACHE_CHECK_RLTYPE	0x200	/* double-check with resource lists */
584 
585 /*
586  * Values for the mount options flag, opt_flags.
587  */
588 /*
589  * Mount options
590  */
591 #define	CFS_WRITE_AROUND	0x01	/* write-around */
592 #define	CFS_NONSHARED		0x02	/* write to cache and back file */
593 #define	CFS_NOCONST_MODE	0x08	/* no-op consistency mode */
594 #define	CFS_ACCESS_BACKFS	0x10	/* pass VOP_ACCESS to backfs */
595 #define	CFS_CODCONST_MODE	0x80	/* cod consistency mode */
596 #define	CFS_DISCONNECTABLE	0x100	/* server not reponding option */
597 #define	CFS_SOFT		0x200	/* soft mounted */
598 #define	CFS_NOACL		0x400	/* ACLs are disabled in this fs */
599 #define	CFS_LLOCK		0x800	/* use local file/record locks */
600 #define	CFS_SLIDE		0x1000	/* slide backfs under cachefs */
601 #define	CFS_NOFILL		0x2000	/* start in nofill mode */
602 #define	CFS_BACKFS_NFSV4	0x4000	/* back filesystem is NFSv4 */
603 
604 #define	MAXCOOKIE_SIZE	36
605 
606 #define	C_BACK_CHECK	0x2
607 
608 /*
609  * Macro to determine if this is a snr error where we should do a
610  * state transition.
611  */
612 
613 #define	CFS_TIMEOUT(FSCP, ERROR) \
614 	(ERROR && CFS_ISFS_SNR(FSCP) && \
615 	(((ERROR) == ETIMEDOUT) || ((ERROR) == EIO)))
616 
617 /*
618  * Macros to assert that cachefs fscache and cnode are in
619  * sync with NFSv4. Note that NFSv4 always passes-through
620  * the vnode calls directly to the backfilesystem. For
621  * this to work:
622  * (1) cachefs is always setup for connected operation,
623  * (2) cachefs options (example disconnectable (snr), nonshared, etc)
624  *     are disabled, and
625  * (3) the back filesystem vnode pointer always exists
626  *      (except after a remove operation)
627  * (4) the front filesystem vnode pointer is always NULL.
628  */
629 #ifdef DEBUG
630 #define	CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp) \
631 	if (CFS_ISFS_BACKFS_NFSV4(fscp)) { \
632 		ASSERT((fscp)->fs_info.fi_mntflags == CFS_BACKFS_NFSV4); \
633 		ASSERT((fscp)->fs_cdconnected == CFS_CD_CONNECTED); \
634 	}
635 #define	CFS_BACKFS_NFSV4_ASSERT_CNODE(cp) \
636 	if (CFS_ISFS_BACKFS_NFSV4(fscp)) { \
637 		if (MUTEX_HELD(&cp->c_statelock)) { \
638 			ASSERT((cp)->c_backvp != NULL || \
639 				((cp)->c_flags & CN_DESTROY) != 0); \
640 			ASSERT((cp)->c_frontvp == NULL); \
641 		} else { \
642 			mutex_enter(&(cp)->c_statelock); \
643 			ASSERT((cp)->c_backvp != NULL || \
644 				((cp)->c_flags & CN_DESTROY) != 0); \
645 			ASSERT((cp)->c_frontvp == NULL); \
646 			mutex_exit(&cp->c_statelock); \
647 		} \
648 	}
649 #else
650 #define	CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp)
651 #define	CFS_BACKFS_NFSV4_ASSERT_CNODE(cp)
652 #endif	/* DEBUG */
653 
654 #ifdef CFSDEBUG
655 #define	CFS_DPRINT_BACKFS_NFSV4(fscp, x) \
656 	if (CFS_ISFS_BACKFS_NFSV4(fscp)) { \
657 		CFS_DEBUG(CFSDEBUG_VOPS_NFSV4) \
658 			printf x; \
659 	}
660 #else
661 #define	CFS_DPRINT_BACKFS_NFSV4(fscp, x)
662 #endif /* CFSDEBUG */
663 
664 /*
665  * cachefs_allocmap and cfs_cachefs_metadata are stored on disk,
666  * so they need to be the same 32-bit vs. 64-bit.
667  */
668 
669 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
670 #pragma pack(4)
671 #endif
672 
673 /*
674  * Large file support. The start offset of the cached file can be
675  * greater than 2GB and by coelescing the different chunks we may
676  * end up having a chunk of siz3 > 2GB.
677  */
678 
679 struct cachefs_allocmap {
680 	u_offset_t		am_start_off;	/* Start offset of this chunk */
681 	u_offset_t		am_size;	/* size of this chunk */
682 };
683 
684 #define	C_MAX_ALLOCINFO_SLOTS	32
685 
686 /*
687  * CFS fastsymlinks. For symlink of size < C_FSL_SIZE, the symlink
688  * is stored in the cnode allocmap array.
689  */
690 #define	C_FSL_SIZE	(sizeof (struct cachefs_allocmap) * \
691 			C_MAX_ALLOCINFO_SLOTS)
692 
693 /*
694  * Structure representing a cached object in memory.
695  */
696 struct cachefs_metadata {
697 	struct vattr		md_vattr;	/* attributes */
698 	o_mode_t		md_aclclass;	/* CLASS_OBJ perm for ACL */
699 	ushort_t		md_pad1;	/* compiler padding */
700 	fid_t			md_cookie;	/* back fid */
701 	int			md_flags;	/* various flags */
702 	uint_t			md_rlno;	/* rl entry */
703 	enum cachefs_rl_type	md_rltype;	/* rl type */
704 	int			md_consttype;	/* type of consistency */
705 	fid_t			md_fid;		/* fid of front file */
706 	uint_t			md_frontblks;	/* # blks used in frontfs */
707 	uint_t			md_gen;		/* fid uniquifier */
708 	struct cfs_cid		md_parent;	/* id of parent */
709 	timestruc_t		md_timestamp;	/* front file timestamp */
710 	timestruc_t		md_x_time;	/* see consistency routines */
711 	timestruc_t		md_localmtime;	/* persistent local mtime */
712 	timestruc_t		md_localctime;	/* persistent local ctime */
713 	uint_t			md_resettimes;	/* when to reset local times */
714 	ino64_t			md_localfileno;	/* persistent local inum */
715 	uint_t			md_resetfileno;	/* when to reset local fileno */
716 	uint_t			md_seq;		/* seq number for putpage */
717 	int			md_allocents;	/* nbr of entries in allocmap */
718 	struct cachefs_allocmap	md_allocinfo[C_MAX_ALLOCINFO_SLOTS];
719 };
720 typedef struct cachefs_metadata cachefs_metadata_t;
721 
722 #if (defined(_SYSCALL32) && defined(_LP64))
723 
724 /*
725  * fid_t is long aligned, so user fid could be only 4 byte aligned.
726  * Since vnode/vfs calls require fid_t (which would be 8 byte aligned in
727  * _LP64), we would have to copy the user's value (and on-disk data) in/out.
728  */
729 /* on-disk metadata structure - fid aligned to int, time is 32-bit */
730 
731 struct cfs_cachefs_metadata {
732 	struct cfs_vattr	md_vattr;	/* attributes */
733 	o_mode_t		md_aclclass;	/* CLASS_OBJ perm for ACL */
734 	cfs_fid_t		md_cookie;	/* back fid */
735 	int			md_flags;	/* various flags */
736 	uint_t			md_rlno;	/* rl entry */
737 	enum cachefs_rl_type	md_rltype;	/* rl type */
738 	int			md_consttype;	/* type of consistency */
739 	cfs_fid_t		md_fid;		/* fid of front file */
740 	uint_t			md_frontblks;	/* # blks used in frontfs */
741 	uint_t			md_gen;		/* fid uniquifier */
742 	struct cfs_cid		md_parent;	/* id of parent */
743 	cfs_timestruc_t		md_timestamp;	/* front file timestamp */
744 	cfs_timestruc_t		md_x_time;	/* see consistency routines */
745 	cfs_timestruc_t		md_localmtime;	/* persistent local mtime */
746 	cfs_timestruc_t		md_localctime;	/* persistent local ctime */
747 	uint_t			md_resettimes;	/* when to reset local times */
748 	ino64_t			md_localfileno;	/* persistent local inum */
749 	uint_t			md_resetfileno;	/* when to reset local fileno */
750 	uint_t			md_seq;		/* seq number for putpage */
751 	int			md_allocents;	/* nbr of entries in allocmap */
752 	struct cachefs_allocmap	md_allocinfo[C_MAX_ALLOCINFO_SLOTS];
753 };
754 typedef struct cfs_cachefs_metadata cfs_cachefs_metadata_t;
755 
756 #else /* not _SYSCALL32 && _LP64 */
757 
758 typedef cachefs_metadata_t	cfs_cachefs_metadata_t;
759 
760 #define	cfs_cachefs_metadata	cachefs_metadata
761 
762 #endif /* _SYSCALL32 && _LP64 */
763 
764 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
765 #pragma pack()
766 #endif
767 
768 /*
769  * Various flags to be stored in md_flags field of the metadata.
770  */
771 #define	MD_CREATEDONE	0x1		/* create was done to backfs */
772 #define	MD_POPULATED	0x2		/* front file or dir is populated */
773 #define	MD_FILE		0x4		/* front file or dir exists */
774 #define	MD_FASTSYMLNK	0x8		/* fast symbolic link */
775 #define	MD_PACKED	0x10		/* file is packed */
776 #define	MD_INVALREADDIR	0x40		/* repopulate on readdir */
777 #define	MD_PUTPAGE	0x200		/* we have already logged a putpage */
778 #define	MD_FREE		0x400		/* not used */
779 #define	MD_PUSHDONE	0x800		/* set if file pushed to back fs */
780 #define	MD_MAPPING	0x1000		/* set if cid mapping space written */
781 #define	MD_ACL		0x2000		/* file has a cached acl */
782 #define	MD_ACLDIR	0x4000		/* front `dir' exists for holding acl */
783 #define	MD_LOCALMTIME	0x8000		/* do not overwrite md_localmtime */
784 #define	MD_LOCALCTIME	0x10000		/* do not overwrite md_localctime */
785 #define	MD_LOCALFILENO	0x20000		/* do not overwrite md_localfileno */
786 #define	MD_NEEDATTRS	0x40000		/* new attrs needed at next check */
787 
788 #define	C_MAX_MOUNT_FSCDIRNAME		128
789 /*
790  * cachefs mount structure and related data
791  */
792 struct cachefs_mountargs {
793 	struct cachefsoptions	cfs_options;	/* consistency modes, etc. */
794 	char			*cfs_fsid;	/* CFS ID fpr file system */
795 	char			cfs_cacheid[C_MAX_MOUNT_FSCDIRNAME];
796 	/* CFS fscdir name */
797 	char			*cfs_cachedir;	/* path for this cache dir */
798 	char			*cfs_backfs;	/* back filesystem dir */
799 	uint_t			cfs_acregmin;	/* same as nfs values */
800 	uint_t			cfs_acregmax;
801 	uint_t			cfs_acdirmin;
802 	uint_t			cfs_acdirmax;
803 	char			*cfs_hostname;  /* server name */
804 	char			*cfs_backfsname; /* back filesystem name */
805 };
806 
807 #ifdef _SYSCALL32
808 struct cachefs_mountargs32 {
809 	struct cachefsoptions	cfs_options;	/* consistency modes, etc. */
810 	caddr32_t		cfs_fsid;	/* CFS ID fpr file system */
811 	char			cfs_cacheid[C_MAX_MOUNT_FSCDIRNAME];
812 	/* CFS fscdir name */
813 	caddr32_t		cfs_cachedir;	/* path for this cache dir */
814 	caddr32_t		cfs_backfs;	/* back filesystem dir */
815 	uint32_t		cfs_acregmin;	/* same as nfs values */
816 	uint32_t		cfs_acregmax;
817 	uint32_t		cfs_acdirmin;
818 	uint32_t		cfs_acdirmax;
819 	caddr32_t		cfs_hostname;  /* server name */
820 	caddr32_t		cfs_backfsname; /* back filesystem name */
821 };
822 #endif /* _SYSCALL32 */
823 
824 /*
825  * struct cachefsops - consistency modules.
826  */
827 struct cachefsops {
828 	int	(*co_init_cobject)();
829 	int	(*co_check_cobject)();
830 	void	(*co_modify_cobject)();
831 	void	(*co_invalidate_cobject)();
832 	void	(*co_convert_cobject)();
833 };
834 
835 
836 
837 /*
838  * The attrcache file consists of a attrcache_header structure and an
839  * array of attrcache_slot structures (one per front file).
840  */
841 
842 /*
843  * Attrcache file format
844  *
845  *	Header
846  *	Offset array (# of entries = file group size)
847  *	alloc list	(1 bit per entry, 0 = free) Note that the
848  *			file will be extended as needed
849  *	attrcache entries
850  *
851  */
852 struct attrcache_header {
853 	uint_t		ach_count;		/* number of entries */
854 	int		ach_nffs;		/* number of front files */
855 	int		ach_nblks;		/* number of allocated blocks */
856 	uint_t		ach_rlno;		/* rl entry for this file */
857 	enum cachefs_rl_type ach_rl_current;	/* which list we're on */
858 };
859 
860 /*
861  * We assume that the seek offset to metadata will never be > 2GB.
862  * The filegrp size is 256 and the current calculations of the sizes
863  * of the data structures show that the ach_offset value here will not
864  * be > 2GB.
865  */
866 
867 struct attrcache_index {
868 	uint_t	ach_written:1;		/* 1 if metadata written */
869 	uint_t	ach_offset:31;		/* seek offset to metadata */
870 };
871 
872 /*
873  * cnode structure, one per file.
874  */
875 #define	c_attr			c_metadata.md_vattr
876 #define	c_cookie		c_metadata.md_cookie
877 #define	c_fileno		c_id.cid_fileno
878 
879 /*
880  * LOCKS:	c_rwlock	Read / Write serialization
881  *		c_statelock	Protects most other fields in the cnode
882  *		c_popcv		Condvar used to prevent routines from nuking
883  *				a cnode which is currently being populated.
884  *				Threads blocked on it will be woken when the
885  *				populate completes.
886  *		c_iocv		broadcast, but never waited on - unused?
887  *		c_iomutex	c_nio and c_ioflags
888  *
889  * Fields protected by other locks:
890  *
891  *		c_next		fg_cnodelock in the filegrp struct
892  *		c_idleback	fs_idlelock in fscache struct
893  *		c_idlefront	fs_idlelock in fscache struct
894  *
895  * Large File support: c_size goes to u_offset_t and the apopoff type
896  * goes to offset_t.
897  */
898 struct cnode {
899 	int		c_flags;	/* see below */
900 	struct cnode	*c_next;	/* next cnode in fgp list */
901 	struct cnode	*c_idleback;	/* idle list back ptr */
902 	struct cnode	*c_idlefront;	/* idle list front ptr */
903 	struct vnode	*c_frontvp;	/* front vnode pointer */
904 	struct vnode	*c_backvp;	/* back vnode pointer */
905 	struct vnode	*c_acldirvp;	/* dir for storing dflt ACL */
906 	u_offset_t	c_size;		/* client view of the size */
907 	struct filegrp	*c_filegrp;	/* back pointer to filegrp */
908 	struct cfs_cid	c_id;		/* unique file number */
909 	int		c_invals;	/* # of recent dir invals */
910 	int		c_usage;	/* Usefulness of cache */
911 	struct vnode	*c_vnode;	/* pointer to vnode */
912 	struct cachefs_metadata	c_metadata;	/* cookie, ... */
913 	int		c_error;
914 	kmutex_t	c_statelock;	/* statelock */
915 	krwlock_t	c_rwlock;	/* serialize write/setattr requests */
916 	kcondvar_t	c_popcv;	/* cnode populate cond var. */
917 	kthread_id_t	c_popthrp;	/* threadp performing pop */
918 	vnode_t		*c_unldvp;	/* dir to unlink in */
919 	char		*c_unlname;	/* name to unlink */
920 	cred_t		*c_unlcred;	/* creds for unlink */
921 	int		c_nio;		/* Number of io's pending */
922 	uint_t		c_ioflags;
923 	kcondvar_t	c_iocv;		/* IO cond var. */
924 	kmutex_t	c_iomutex;
925 	cred_t		*c_cred;
926 	int		c_ipending;	/* 1 if inactive is pending */
927 	int		c_mapcnt;	/* number of mapped blocks */
928 	offset_t	c_apopoffset;	/* offset for async pop */
929 	uint_t		c_apoplen;	/* length for async pop */
930 	u_offset_t	c_modaddr;	/* writepage offset */
931 	int		c_rdcnt;	/* # of read opens for backvp */
932 	int		c_wrcnt;	/* # of write opens for backvp */
933 };
934 typedef struct cnode cnode_t;
935 
936 extern struct kmem_cache *cachefs_cnode_cache;
937 
938 /*
939  * Directory caching parameters - First cut...
940  */
941 #define	CFS_DIRCACHE_COST	3
942 #define	CFS_DIRCACHE_INVAL	3
943 #define	CFS_DIRCACHE_ENABLE	(CFS_DIRCACHE_INVAL * CFS_DIRCACHE_COST)
944 
945 /*
946  * Conversion macros
947  */
948 #define	VTOC(VP)		((struct cnode *)((void *)((VP)->v_data)))
949 #define	CTOV(CP)		((CP)->c_vnode)
950 #define	VFS_TO_FSCACHE(VFSP)	((struct fscache *)((void *)((VFSP)->vfs_data)))
951 #define	C_TO_FSCACHE(CP)	(VFS_TO_FSCACHE(CTOV(CP)->v_vfsp))
952 
953 /*
954  * Various flags stored in the flags field of the cnode structure.
955  */
956 #define	CN_NOCACHE	0x1		/* no-cache mode */
957 #define	CN_DESTROY	0x2		/* destroy when inactive */
958 #define	CN_ROOT		0x4		/* root of the file system */
959 #define	CN_IDLE		0x8		/* file is idle */
960 #define	CN_NEEDOPEN	0x10		/* need to open backvp */
961 #define	CN_UPDATED	0x40		/* Metadata was updated - needs sync */
962 #define	CDIRTY		0x80
963 #define	CN_NEED_FRONT_SYNC	0x100	/* front file needs to be sync'd */
964 #define	CN_ALLOC_PENDING	0x200	/* Need to alloc attr cache entry */
965 #define	CN_STALE	0x400		/* cnode is stale */
966 #define	CN_MODIFIED	0x800		/* Object has been written to */
967 #define	CN_POPULATION_PENDING	0x1000	/* Population data needs to be sync'd */
968 #define	CN_ASYNC_POPULATE	0x2000	/* async population pending */
969 #define	CN_ASYNC_POP_WORKING	0x4000	/* async population in progress */
970 #define	CN_PENDRM	0x8000		/* hold off unlink until reconnected */
971 #define	CN_MAPWRITE	0x100000	/* mmapped file that is being written */
972 #define	CN_CMODINPROG	0x200000	/* writepage() in progress */
973 
974 /*
975  * io flags (in c_ioflag)
976  */
977 #define	CIO_PUTPAGES	0x1		/* putpage pending: off==0, len==0 */
978 
979 #define	CFS_MAX_THREADS		5
980 #define	CFS_ASYNC_TIMEOUT	(60 * hz)
981 
982 enum cachefs_cmd {
983 	CFS_INVALID,
984 	CFS_CACHE_SYNC,
985 	CFS_PUTPAGE,
986 	CFS_IDLE,
987 	CFS_POPULATE,
988 	CFS_NOOP
989 };
990 
991 struct cachefs_fs_sync_req {
992 	struct cachefscache *cf_cachep;
993 };
994 
995 struct cachefs_idle_req {
996 	vnode_t *ci_vp;
997 };
998 
999 /*
1000  * Large File support the offset in the vnode for putpage request
1001  * can now be greater than 2GB.
1002  */
1003 
1004 struct cachefs_putpage_req {
1005 	vnode_t *cp_vp;
1006 	offset_t cp_off;
1007 	int cp_len;
1008 	int cp_flags;
1009 };
1010 
1011 /*
1012  * Large File support the offset in the vnode for populate request
1013  * can now be greater than 2GB.
1014  */
1015 
1016 struct cachefs_populate_req {
1017 	vnode_t *cpop_vp;
1018 	offset_t cpop_off;
1019 	size_t cpop_size;
1020 };
1021 
1022 struct cachefs_req {
1023 	struct cachefs_req	*cfs_next;
1024 	enum cachefs_cmd	cfs_cmd;	/* Command to execute */
1025 	cred_t *cfs_cr;
1026 	union {
1027 		struct cachefs_fs_sync_req cu_fs_sync;
1028 		struct cachefs_idle_req cu_idle;
1029 		struct cachefs_putpage_req cu_putpage;
1030 		struct cachefs_populate_req cu_populate;
1031 	} cfs_req_u;
1032 	kmutex_t cfs_req_lock;	/* Protects contents */
1033 };
1034 
1035 extern struct kmem_cache *cachefs_req_cache;
1036 
1037 /*
1038  * Large file support: We allow cachefs to understand the 64 bit inode type.
1039  */
1040 
1041 struct cachefs_fid {
1042 	ushort_t	cf_len;
1043 	ino64_t		cf_fileno;
1044 	uint_t		cf_gen;
1045 };
1046 #define	CFS_FID_SIZE	(sizeof (struct cachefs_fid) - sizeof (ushort_t))
1047 
1048 /*
1049  *
1050  * cachefs kstat stuff.  each time you mount a cachefs filesystem, it
1051  * gets a unique number.  it'll get that number again if you remount
1052  * the same thing.  the number is unique until reboot, but it doesn't
1053  * survive reboots.
1054  *
1055  * each cachefs kstat uses this per-filesystem identifier.  to get the
1056  * valid identifiers, the `cachefs.0.key' kstat has a mapping of all
1057  * the available filesystems.  its structure, cachefs_kstat_key, is
1058  * below.
1059  *
1060  */
1061 
1062 typedef struct cachefs_kstat_key {
1063 	int ks_id;
1064 	int ks_mounted;
1065 	uint64_t ks_vfsp;
1066 	uint64_t ks_mountpoint;
1067 	uint64_t ks_backfs;
1068 	uint64_t ks_cachedir;
1069 	uint64_t ks_cacheid;
1070 } cachefs_kstat_key_t;
1071 extern cachefs_kstat_key_t *cachefs_kstat_key;
1072 extern int cachefs_kstat_key_n;
1073 
1074 /*
1075  * cachefs debugging aid.  cachefs_debug_info_t is a cookie that we
1076  * can keep around to see what was happening at a certain time.
1077  *
1078  * for example, if we have a deadlock on the cnode's statelock
1079  * (i.e. someone is not letting go of it), we can add a
1080  * cachefs_debug_info_t * to the cnode structure, and call
1081  * cachefs_debug_save() whenever we grab the lock.  then, when we're
1082  * deadlocked, we can see what was going on when we grabbed the lock
1083  * in the first place, and (hopefully) why we didn't release it.
1084  */
1085 
1086 #define	CACHEFS_DEBUG_DEPTH		(16)
1087 typedef struct cachefs_debug_info {
1088 	char		*cdb_message;	/* arbitrary message */
1089 	uint_t		cdb_flags;	/* arbitrary flags */
1090 	int		cdb_int;	/* arbitrary int */
1091 	void		*cdb_pointer;	/* arbitrary pointer */
1092 	uint_t		cdb_count;	/* how many times called */
1093 
1094 	cachefscache_t	*cdb_cachep;	/* relevant cachep (maybe undefined) */
1095 	struct fscache	*cdb_fscp;	/* relevant fscache */
1096 	struct cnode	*cdb_cnode;	/* relevant cnode */
1097 	vnode_t		*cdb_frontvp;	/* relevant front vnode */
1098 	vnode_t		*cdb_backvp;	/* relevant back vnode */
1099 
1100 	kthread_id_t	cdb_thread;	/* thread who called */
1101 	hrtime_t	cdb_timestamp;	/* when */
1102 	int		cdb_depth;	/* depth of saved stack */
1103 	pc_t		cdb_stack[CACHEFS_DEBUG_DEPTH]; /* stack trace */
1104 	struct cachefs_debug_info *cdb_next; /* pointer to next */
1105 } cachefs_debug_info_t;
1106 
1107 /*
1108  * cachefs function prototypes
1109  */
1110 #if defined(_KERNEL) && defined(__STDC__)
1111 extern int cachefs_getcookie(vnode_t *, struct fid *, struct vattr *,
1112 		cred_t *, uint32_t);
1113 cachefscache_t *cachefs_cache_create(void);
1114 void cachefs_cache_destroy(cachefscache_t *cachep);
1115 int cachefs_cache_activate_ro(cachefscache_t *cachep, vnode_t *cdvp);
1116 void cachefs_cache_activate_rw(cachefscache_t *cachep);
1117 void cachefs_cache_dirty(struct cachefscache *cachep, int lockit);
1118 int cachefs_cache_rssync(struct cachefscache *cachep);
1119 void cachefs_cache_sync(struct cachefscache *cachep);
1120 uint_t cachefs_cache_unique(cachefscache_t *cachep);
1121 void cachefs_do_req(struct cachefs_req *);
1122 
1123 /* cachefs_cnode.c */
1124 void cachefs_cnode_idle(struct vnode *vp, cred_t *cr);
1125 void cachefs_cnode_idleclean(fscache_t *fscp, int unmount);
1126 int cachefs_cnode_inactive(register struct vnode *vp, cred_t *cr);
1127 void cachefs_cnode_listadd(struct cnode *cp);
1128 void cachefs_cnode_listrem(struct cnode *cp);
1129 void cachefs_cnode_free(struct cnode *cp);
1130 void cachefs_cnode_cleanfreelist();
1131 void cachefs_cnode_idleadd(struct cnode *cp);
1132 void cachefs_cnode_idlerem(struct cnode *cp);
1133 int cachefs_cnode_find(filegrp_t *fgp, cfs_cid_t *cidp, fid_t *cookiep,
1134     struct cnode **cpp, struct vnode *vp, vattr_t *vap);
1135 int cachefs_cnode_make(cfs_cid_t *cidp, fscache_t *fscp, fid_t *cookiep,
1136     vattr_t *vap, vnode_t *backvp, cred_t *cr, int flag, cnode_t **cpp);
1137 int cachefs_cid_inuse(filegrp_t *fgp, cfs_cid_t *cidp);
1138 int cachefs_fileno_inuse(fscache_t *fscp, ino64_t fileno);
1139 int cachefs_cnode_create(fscache_t *fscp, vattr_t *vap, int flag,
1140     cnode_t **cpp);
1141 void cachefs_cnode_move(cnode_t *cp);
1142 int cachefs_cnode_lostfound(cnode_t *cp, char *rname);
1143 void cachefs_cnode_sync(cnode_t *cp);
1144 void cachefs_cnode_traverse(fscache_t *fscp, void (*routinep)(cnode_t *));
1145 void cachefs_cnode_stale(cnode_t *cp);
1146 void cachefs_cnode_setlocalstats(cnode_t *cp);
1147 void cachefs_cnode_disable_caching(cnode_t *cp);
1148 
1149 void cachefs_enable_caching(struct fscache *);
1150 
1151 /* cachefs_fscache.c */
1152 void fscache_destroy(fscache_t *);
1153 
1154 /* cachefs_ioctl.h */
1155 int cachefs_pack_common(vnode_t *vp, cred_t *cr);
1156 void cachefs_inum_register(fscache_t *fscp, ino64_t real, ino64_t fake);
1157 ino64_t cachefs_inum_real2fake(fscache_t *fscp, ino64_t real);
1158 
1159 
1160 /* cachefs_subr.c */
1161 int cachefs_sync_metadata(cnode_t *);
1162 int cachefs_cnode_cnt(int);
1163 int cachefs_getbackvp(struct fscache *, struct cnode *);
1164 int cachefs_getfrontfile(cnode_t *);
1165 void cachefs_removefrontfile(cachefs_metadata_t *mdp, cfs_cid_t *cidp,
1166     filegrp_t *fgp);
1167 void cachefs_nocache(cnode_t *);
1168 void cachefs_inval_object(cnode_t *);
1169 void make_ascii_name(cfs_cid_t *cidp, char *strp);
1170 int cachefs_async_halt(struct cachefs_workq *, int);
1171 int cachefs_async_okay(void);
1172 int cachefs_check_allocmap(cnode_t *cp, u_offset_t off);
1173 void cachefs_update_allocmap(cnode_t *, u_offset_t, size_t);
1174 int cachefs_cachesymlink(struct cnode *cp, cred_t *cr);
1175 int cachefs_stuffsymlink(cnode_t *cp, caddr_t buf, int buflen);
1176 int cachefs_readlink_back(cnode_t *cp, cred_t *cr, caddr_t *bufp, int *buflenp);
1177 /*
1178  * void cachefs_cluster_allocmap(struct cnode *, u_offset_t, u_offset_t *,
1179  *	size_t *, size_t);
1180  */
1181 void cachefs_cluster_allocmap(u_offset_t, u_offset_t *, size_t *, size_t,
1182 		struct cnode *);
1183 int cachefs_populate(cnode_t *, u_offset_t, size_t, vnode_t *, vnode_t *,
1184 	u_offset_t, cred_t *);
1185 int cachefs_stats_kstat_snapshot(kstat_t *, void *, int);
1186 cachefs_debug_info_t *cachefs_debug_save(cachefs_debug_info_t *, int,
1187     char *, uint_t, int, void *, cachefscache_t *, struct fscache *,
1188     struct cnode *);
1189 void cachefs_debug_show(cachefs_debug_info_t *);
1190 uint32_t cachefs_cred_checksum(cred_t *cr);
1191 int cachefs_frontfile_size(cnode_t *cp, u_offset_t length);
1192 int cachefs_req_create(void *, void *, int);
1193 void cachefs_req_destroy(void *, void *);
1194 int cachefs_stop_cache(cnode_t *);
1195 
1196 
1197 /* cachefs_resource.c */
1198 void cachefs_rlent_moveto_nolock(cachefscache_t *cachep,
1199     enum cachefs_rl_type type, uint_t entno, size_t);
1200 void cachefs_rlent_moveto(cachefscache_t *, enum cachefs_rl_type, uint_t,
1201     size_t);
1202 void cachefs_rlent_verify(cachefscache_t *, enum cachefs_rl_type, uint_t);
1203 void cachefs_rl_changefileno(cachefscache_t *cachep, uint_t entno,
1204 	ino64_t fileno);
1205 int cachefs_rlent_data(cachefscache_t *cachep, rl_entry_t *valp,
1206     uint_t *entnop);
1207 void cachefs_move_modified_to_mf(cachefscache_t *cachep, fscache_t *fscp);
1208 int cachefs_allocblocks(cachefscache_t *, size_t, enum cachefs_rl_type);
1209 void cachefs_freeblocks(cachefscache_t *, size_t, enum cachefs_rl_type);
1210 void cachefs_freefile(cachefscache_t *);
1211 int cachefs_allocfile(cachefscache_t *);
1212 int cachefs_rl_alloc(struct cachefscache *cachep, rl_entry_t *valp,
1213     uint_t *entnop);
1214 int cachefs_rl_attrc(struct cachefscache *, int, int);
1215 void cachefs_cachep_worker_thread(cachefscache_t *);
1216 void cachefs_rl_cleanup(cachefscache_t *);
1217 int cachefs_rl_entry_get(cachefscache_t *, uint_t, rl_entry_t **);
1218 #ifdef CFSRLDEBUG
1219 void cachefs_rl_debug_save(rl_entry_t *);
1220 void cachefs_rl_debug_show(rl_entry_t *);
1221 void cachefs_rl_debug_destroy(rl_entry_t *);
1222 #endif /* CFSRLDEBUG */
1223 
1224 /* cachefs_log.c */
1225 int cachefs_log_kstat_snapshot(kstat_t *, void *, int);
1226 void cachefs_log_process_queue(cachefscache_t *, int);
1227 int cachefs_log_logfile_open(cachefscache_t *, char *);
1228 struct cachefs_log_cookie
1229 	*cachefs_log_create_cookie(struct cachefs_log_control *);
1230 void cachefs_log_error(cachefscache_t *, int, int);
1231 void cachefs_log_destroy_cookie(struct cachefs_log_cookie *);
1232 
1233 void cachefs_log_mount(cachefscache_t *, int, struct vfs *,
1234     fscache_t *, char *, enum uio_seg, char *);
1235 void cachefs_log_umount(cachefscache_t *, int, struct vfs *);
1236 void cachefs_log_getpage(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1237     uid_t, u_offset_t, size_t);
1238 void cachefs_log_readdir(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1239     uid_t, u_offset_t, int);
1240 void cachefs_log_readlink(cachefscache_t *, int, struct vfs *,
1241     fid_t *, ino64_t, uid_t, size_t);
1242 void cachefs_log_remove(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1243     uid_t);
1244 void cachefs_log_rmdir(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1245     uid_t);
1246 void cachefs_log_truncate(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1247     uid_t, u_offset_t);
1248 void cachefs_log_putpage(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1249     uid_t, u_offset_t, size_t);
1250 void cachefs_log_create(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1251     uid_t);
1252 void cachefs_log_mkdir(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1253     uid_t);
1254 void cachefs_log_rename(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1255     int, uid_t);
1256 void cachefs_log_symlink(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1257     uid_t, int);
1258 void cachefs_log_populate(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1259     u_offset_t, size_t);
1260 void cachefs_log_csymlink(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1261     int);
1262 void cachefs_log_filldir(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1263     u_offset_t);
1264 void cachefs_log_mdcreate(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1265     uint_t);
1266 void cachefs_log_gpfront(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1267     uid_t, u_offset_t, uint_t);
1268 void cachefs_log_rfdir(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1269     uid_t);
1270 void cachefs_log_ualloc(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1271     u_offset_t, size_t);
1272 void cachefs_log_calloc(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
1273     u_offset_t, size_t);
1274 void cachefs_log_nocache(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t);
1275 
1276 /* cachefs_vnops.c */
1277 struct vnodeops *cachefs_getvnodeops(void);
1278 int cachefs_lookup_common(vnode_t *dvp, char *nm, vnode_t **vpp,
1279     struct pathname *pnp, int flags, vnode_t *rdir, cred_t *cr);
1280 int cachefs_putpage_common(struct vnode *vp, offset_t off,
1281     size_t len, int flags, cred_t *cr);
1282 ino64_t cachefs_fileno_conflict(fscache_t *fscp, ino64_t old);
1283 int cachefs_remove_connected(vnode_t *dvp, char *nm, cred_t *cr,
1284     vnode_t *vp);
1285 int cachefs_remove_disconnected(vnode_t *dvp, char *nm, cred_t *cr,
1286     vnode_t *vp);
1287 int cachefs_cacheacl(cnode_t *, vsecattr_t *);
1288 void cachefs_purgeacl(cnode_t *);
1289 int cachefs_vtype_aclok(vnode_t *);
1290 
1291 /* cachefs_vfsops.c */
1292 int cachefs_init_vfsops(int);
1293 int cachefs_init_vnops(char *);
1294 void cachefs_kstat_mount(struct fscache *, char *, char *, char *, char *);
1295 void cachefs_kstat_umount(int);
1296 int cachefs_kstat_key_update(kstat_t *, int);
1297 int cachefs_kstat_key_snapshot(kstat_t *, void *, int);
1298 
1299 extern void cachefs_workq_init(struct cachefs_workq *);
1300 extern void cachefs_addqueue(struct cachefs_req *, struct cachefs_workq *);
1301 
1302 
1303 extern void *cachefs_kmem_alloc(size_t, int);
1304 extern void *cachefs_kmem_zalloc(size_t, int);
1305 extern void cachefs_kmem_free(void *, size_t);
1306 extern char *cachefs_strdup(char *);
1307 
1308 #endif /* defined (_KERNEL) && defined (__STDC__) */
1309 
1310 
1311 
1312 #define	C_RL_MAXENTS	0x4000		/* Whatever */
1313 
1314 /*
1315  * ioctls.
1316  */
1317 #include <sys/ioccom.h>
1318 #define	_FIOCOD		_IO('f', 78)		/* consistency on demand */
1319 #define	_FIOSTOPCACHE	_IO('f', 86)		/* stop using cache */
1320 
1321 #define	CACHEFSIO_PACK		_IO('f', 81)
1322 #define	CACHEFSIO_UNPACK	_IO('f', 82)
1323 #define	CACHEFSIO_UNPACKALL	_IO('f', 83)
1324 #define	CACHEFSIO_PACKINFO	_IO('f', 84)
1325 #define	CACHEFSIO_DCMD		_IO('f', 85)
1326 
1327 #ifdef __cplusplus
1328 }
1329 #endif
1330 
1331 #endif /* _SYS_FS_CACHEFS_FS_H */
1332