xref: /titanic_44/usr/src/uts/common/sys/fs/cachefs_fs.h (revision ba3594ba9b5dd4c846c472a8d657edcb7c8109ac)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
23*ba3594baSGarrett D'Amore  * Copyright 2014 Garrett D'Amore <garrett@damore.org>
24*ba3594baSGarrett D'Amore  *
257c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
267c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
277c478bd9Sstevel@tonic-gate  */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #ifndef _SYS_FS_CACHEFS_FS_H
307c478bd9Sstevel@tonic-gate #define	_SYS_FS_CACHEFS_FS_H
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include <sys/vnode.h>
337c478bd9Sstevel@tonic-gate #include <sys/vfs.h>
347c478bd9Sstevel@tonic-gate #include <sys/types.h>
357c478bd9Sstevel@tonic-gate #include <sys/types32.h>
367c478bd9Sstevel@tonic-gate #include <sys/t_lock.h>
377c478bd9Sstevel@tonic-gate #include <sys/thread.h>
387c478bd9Sstevel@tonic-gate #include <sys/kmem.h>
397c478bd9Sstevel@tonic-gate #include <sys/inttypes.h>
407c478bd9Sstevel@tonic-gate #include <sys/time_impl.h>
417c478bd9Sstevel@tonic-gate #include <sys/systm.h>
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #ifdef __cplusplus
447c478bd9Sstevel@tonic-gate extern "C" {
457c478bd9Sstevel@tonic-gate #endif
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate #ifdef CFSDEBUG
487c478bd9Sstevel@tonic-gate #define	CFSDEBUG_ALL		0xffffffff
497c478bd9Sstevel@tonic-gate #define	CFSDEBUG_NONE		0x0
507c478bd9Sstevel@tonic-gate #define	CFSDEBUG_GENERAL	0x1
517c478bd9Sstevel@tonic-gate #define	CFSDEBUG_SUBR		0x2
527c478bd9Sstevel@tonic-gate #define	CFSDEBUG_CNODE		0x4
537c478bd9Sstevel@tonic-gate #define	CFSDEBUG_DIR		0x8
547c478bd9Sstevel@tonic-gate #define	CFSDEBUG_STRICT		0x10
557c478bd9Sstevel@tonic-gate #define	CFSDEBUG_VOPS		0x20
567c478bd9Sstevel@tonic-gate #define	CFSDEBUG_VFSOP		0x40
577c478bd9Sstevel@tonic-gate #define	CFSDEBUG_RESOURCE	0x80
587c478bd9Sstevel@tonic-gate #define	CFSDEBUG_CHEAT		0x100
597c478bd9Sstevel@tonic-gate #define	CFSDEBUG_INVALIDATE	0x200
607c478bd9Sstevel@tonic-gate #define	CFSDEBUG_DLOG		0x400
617c478bd9Sstevel@tonic-gate #define	CFSDEBUG_FILEGRP	0x800
627c478bd9Sstevel@tonic-gate #define	CFSDEBUG_IOCTL		0x1000
637c478bd9Sstevel@tonic-gate #define	CFSDEBUG_FRONT		0x2000
647c478bd9Sstevel@tonic-gate #define	CFSDEBUG_BACK		0x4000
657c478bd9Sstevel@tonic-gate #define	CFSDEBUG_ALLOCMAP	0x8000
667c478bd9Sstevel@tonic-gate #define	CFSDEBUG_ASYNCPOP	0x10000
677c478bd9Sstevel@tonic-gate #define	CFSDEBUG_VOPS_NFSV4	0x20000
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate #define	CFSCLEANFLAG
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate extern int cachefsdebug;
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate #define	CFS_DEBUG(N)    if (cachefsdebug & (N))
747c478bd9Sstevel@tonic-gate #endif /* DEBUG */
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate #if 0
777c478bd9Sstevel@tonic-gate #ifdef CFSDEBUG
787c478bd9Sstevel@tonic-gate 	/*
797c478bd9Sstevel@tonic-gate 	 * Testing usage of cd_access and friends.
807c478bd9Sstevel@tonic-gate 	 * Note we steal an unused bit in t_flag.
817c478bd9Sstevel@tonic-gate 	 * This will certainly bite us later.
827c478bd9Sstevel@tonic-gate 	 */
837c478bd9Sstevel@tonic-gate #define	CFS_CD_DEBUG
847c478bd9Sstevel@tonic-gate #define	T_CD_HELD	0x01000
857c478bd9Sstevel@tonic-gate #endif
867c478bd9Sstevel@tonic-gate #endif
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate /*
897c478bd9Sstevel@tonic-gate  * Note: in an RL debugging kernel, CFSVERSION is augmented by 100
907c478bd9Sstevel@tonic-gate  *
917c478bd9Sstevel@tonic-gate  * Version History:
927c478bd9Sstevel@tonic-gate  *
937c478bd9Sstevel@tonic-gate  * Beginning -- Solaris 2.3 and 2.4: 1
947c478bd9Sstevel@tonic-gate  *
957c478bd9Sstevel@tonic-gate  * In Solaris 2.5 alpha, the size of fid_t changed: 2
967c478bd9Sstevel@tonic-gate  *
977c478bd9Sstevel@tonic-gate  * In 2.6: Chart, RL pointers/idents became rl_entry: 3
987c478bd9Sstevel@tonic-gate  *	added which RL list to attrcache header: 4
997c478bd9Sstevel@tonic-gate  *
1007c478bd9Sstevel@tonic-gate  * Large Files support made version to 6.
1017c478bd9Sstevel@tonic-gate  *
1027c478bd9Sstevel@tonic-gate  * Sequence numbers made version to 7.
1037c478bd9Sstevel@tonic-gate  *
1047c478bd9Sstevel@tonic-gate  * 64-bit on-disk cache will make version 8. Not yet supported.
1057c478bd9Sstevel@tonic-gate  */
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate #if 0
1087c478bd9Sstevel@tonic-gate #define	CFSRLDEBUG
1097c478bd9Sstevel@tonic-gate #endif
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate #ifdef CFSRLDEBUG
1127c478bd9Sstevel@tonic-gate #define	CFSVERSION		110
1137c478bd9Sstevel@tonic-gate #define	CFSVERSION64		111	/* 64-bit cache - not yet used */
1147c478bd9Sstevel@tonic-gate #else /* CFSRLDEBUG */
1157c478bd9Sstevel@tonic-gate #define	CFSVERSION		7
1167c478bd9Sstevel@tonic-gate #define	CFSVERSION64		8	/* 64-bit cache - not yet used */
1177c478bd9Sstevel@tonic-gate #endif /* CFSRLDEBUG */
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate /* Some default values */
1207c478bd9Sstevel@tonic-gate #define	DEF_FILEGRP_SIZE	256
1217c478bd9Sstevel@tonic-gate #define	DEF_POP_SIZE		0x10000		/* 64K */
1227c478bd9Sstevel@tonic-gate #define	CACHELABEL_NAME		".cfs_label"
1237c478bd9Sstevel@tonic-gate #define	RESOURCE_NAME		".cfs_resource"
1247c478bd9Sstevel@tonic-gate #define	CACHEFS_FSINFO		".cfs_fsinfo"
1257c478bd9Sstevel@tonic-gate #define	ATTRCACHE_NAME		".cfs_attrcache"
1267c478bd9Sstevel@tonic-gate #define	CACHEFS_LOSTFOUND_NAME	"lost+found"
1277c478bd9Sstevel@tonic-gate #define	BACKMNT_NAME		".cfs_mnt_points"
1287c478bd9Sstevel@tonic-gate #define	CACHEFS_LOCK_FILE	".cfs_lock"
1297c478bd9Sstevel@tonic-gate #define	CACHEFS_DLOG_FILE	".cfs_dlog"
1307c478bd9Sstevel@tonic-gate #define	CACHEFS_DMAP_FILE	".cfs_dmap"
1317c478bd9Sstevel@tonic-gate #define	CACHEFS_MNT_FILE	".cfs_mnt"
1327c478bd9Sstevel@tonic-gate #define	CACHEFS_UNMNT_FILE	".cfs_unmnt"
1337c478bd9Sstevel@tonic-gate #define	LOG_STATUS_NAME		".cfs_logging"
1347c478bd9Sstevel@tonic-gate #define	NOBACKUP_NAME		".nsr"
1357c478bd9Sstevel@tonic-gate #define	CACHEFS_PREFIX		".cfs_"
1367c478bd9Sstevel@tonic-gate #define	CACHEFS_PREFIX_LEN	5
1377c478bd9Sstevel@tonic-gate #define	ROOTLINK_NAME		"root"
1387c478bd9Sstevel@tonic-gate #define	CFS_FRONTFILE_NAME_SIZE	18
1397c478bd9Sstevel@tonic-gate #define	CACHEFS_BASETYPE	"cachefs" /* used in statvfs() */
1407c478bd9Sstevel@tonic-gate #define	CFS_MAXFREECNODES	20
1417c478bd9Sstevel@tonic-gate #define	CACHEFSTAB		"/etc/cachefstab"
1427c478bd9Sstevel@tonic-gate #define	CACHEFS_ROOTRUN		"/var/run"
1437c478bd9Sstevel@tonic-gate #define	CACHEFS_LOCKDIR_PRE	".cachefs." /* used by mount(1M)/fsck(1M) */
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate /*
1467c478bd9Sstevel@tonic-gate  * The options structure is passed in as part of the mount arguments.
1477c478bd9Sstevel@tonic-gate  * It is stored in the .options file and kept track of in the fscache
1487c478bd9Sstevel@tonic-gate  * structure.
1497c478bd9Sstevel@tonic-gate  */
1507c478bd9Sstevel@tonic-gate struct cachefsoptions {
1517c478bd9Sstevel@tonic-gate 	uint_t		opt_flags;		/* mount flags */
1527c478bd9Sstevel@tonic-gate 	int		opt_popsize;		/* cache population size */
1537c478bd9Sstevel@tonic-gate 	int		opt_fgsize;		/* filegrp size, default 256 */
1547c478bd9Sstevel@tonic-gate };
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate typedef struct cachefscache cachefscache_t;
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate /*
1597c478bd9Sstevel@tonic-gate  * all the stuff needed to manage a queue of requests to be processed
1607c478bd9Sstevel@tonic-gate  * by async threads.
1617c478bd9Sstevel@tonic-gate  */
1627c478bd9Sstevel@tonic-gate struct cachefs_workq {
1637c478bd9Sstevel@tonic-gate 	struct cachefs_req	*wq_head;		/* head of work q */
1647c478bd9Sstevel@tonic-gate 	struct cachefs_req	*wq_tail;		/* tail of work q */
1657c478bd9Sstevel@tonic-gate 	int			wq_length;		/* # of requests on q */
1667c478bd9Sstevel@tonic-gate 	int			wq_thread_count;	/* # of threads */
1677c478bd9Sstevel@tonic-gate 	int			wq_max_len;		/* longest queue */
1687c478bd9Sstevel@tonic-gate 	int			wq_halt_request;	/* halt requested */
1697c478bd9Sstevel@tonic-gate 	unsigned int		wq_keepone:1;		/* keep one thread */
1707c478bd9Sstevel@tonic-gate 	unsigned int		wq_logwork:1;		/* write logfile */
1717c478bd9Sstevel@tonic-gate 	kcondvar_t		wq_req_cv;		/* wait on work to do */
1727c478bd9Sstevel@tonic-gate 	kcondvar_t		wq_halt_cv;		/* wait/signal halt */
1737c478bd9Sstevel@tonic-gate 	kmutex_t		wq_queue_lock;		/* protect queue */
1747c478bd9Sstevel@tonic-gate 	cachefscache_t		*wq_cachep;		/* sometimes NULL */
1757c478bd9Sstevel@tonic-gate };
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate /*
1787c478bd9Sstevel@tonic-gate  * cfs_cid is stored on disk, so it needs to be the same 32-bit vs. 64-bit.
1797c478bd9Sstevel@tonic-gate  */
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
1827c478bd9Sstevel@tonic-gate #pragma pack(4)
1837c478bd9Sstevel@tonic-gate #endif
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate /* identifies a file in the cache */
1867c478bd9Sstevel@tonic-gate struct cfs_cid {
1877c478bd9Sstevel@tonic-gate 	ino64_t	cid_fileno;		/* fileno */
1887c478bd9Sstevel@tonic-gate 	int	cid_flags;		/* flags */
1897c478bd9Sstevel@tonic-gate };
1907c478bd9Sstevel@tonic-gate typedef struct cfs_cid cfs_cid_t;
1917c478bd9Sstevel@tonic-gate #define	CFS_CID_LOCAL	1	/* local file */
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
1947c478bd9Sstevel@tonic-gate #pragma pack()
1957c478bd9Sstevel@tonic-gate #endif
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate /*
1987c478bd9Sstevel@tonic-gate  * XX64 - for now redefine	all time_t fields that are used by both kernel
1997c478bd9Sstevel@tonic-gate  * and user space apps as a 32-bit quantity,
2007c478bd9Sstevel@tonic-gate  */
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate #if (defined(_SYSCALL32) && defined(_LP64))
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate /*
2057c478bd9Sstevel@tonic-gate  * The cfs_* types are used to represent on-disk data, since its size is
2067c478bd9Sstevel@tonic-gate  * independent of the kernel memory model (in the LP64 case)
2077c478bd9Sstevel@tonic-gate  */
2087c478bd9Sstevel@tonic-gate typedef time32_t		cfs_time_t;
2097c478bd9Sstevel@tonic-gate typedef timestruc32_t		cfs_timestruc_t;
2107c478bd9Sstevel@tonic-gate typedef vattr32_t		cfs_vattr_t;
2117c478bd9Sstevel@tonic-gate typedef fid32_t			cfs_fid_t;
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate #define	cfs_timespec		timespec32
2147c478bd9Sstevel@tonic-gate #define	cfs_vattr		vattr32
2157c478bd9Sstevel@tonic-gate #define	cfs_fid			fid32
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate /*
2187c478bd9Sstevel@tonic-gate  * CACHEFS_DEV_COPY copies between two dev_t's. It expands or compresses
2197c478bd9Sstevel@tonic-gate  * them based on type changes (if needed).
2207c478bd9Sstevel@tonic-gate  */
2217c478bd9Sstevel@tonic-gate #define	CACHEFS_DEV_TO_DEV32_COPY(in_dev, out_dev, error)		\
2227c478bd9Sstevel@tonic-gate 	if (cmpldev((dev32_t *)&(out_dev), in_dev) == 0)		\
2237c478bd9Sstevel@tonic-gate 		error = EOVERFLOW;
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate #define	CACHEFS_DEV32_TO_DEV_COPY(in_dev, out_dev)			\
2267c478bd9Sstevel@tonic-gate 	out_dev = (dev_t)expldev(in_dev);
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate #define	TIME_OVERFLOW(tval)						\
2297c478bd9Sstevel@tonic-gate 	((tval) < TIME32_MIN || (tval) > TIME32_MAX)
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate /* Set the referred to time value. Set error if overflow */
2327c478bd9Sstevel@tonic-gate #define	CACHEFS_TIME_TO_TIME32_COPY(in_tval, out_tval, error)		\
2337c478bd9Sstevel@tonic-gate 	out_tval = (in_tval);						\
2347c478bd9Sstevel@tonic-gate 	if (TIME_OVERFLOW(in_tval))					\
2357c478bd9Sstevel@tonic-gate 		error = EOVERFLOW;
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate #define	CACHEFS_TIME32_TO_TIME_COPY(in_tval, out_tval)			\
2387c478bd9Sstevel@tonic-gate 	out_tval = (in_tval);
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate /* Set the cfs_timestruc_t with values from input timestruc_t */
2417c478bd9Sstevel@tonic-gate #define	CACHEFS_TS_TO_TS32_COPY(in_tsp, out_tsp, error)			\
2427c478bd9Sstevel@tonic-gate 	(out_tsp)->tv_nsec = (in_tsp)->tv_nsec;				\
2437c478bd9Sstevel@tonic-gate 	CACHEFS_TIME_TO_TIME32_COPY((in_tsp)->tv_sec, (out_tsp)->tv_sec, error)
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate #define	CACHEFS_TS32_TO_TS_COPY(in_tsp, out_tsp)			\
2467c478bd9Sstevel@tonic-gate 	(out_tsp)->tv_nsec = (in_tsp)->tv_nsec;				\
2477c478bd9Sstevel@tonic-gate 	CACHEFS_TIME32_TO_TIME_COPY((in_tsp)->tv_sec, (out_tsp)->tv_sec)
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate /* CACHEFS_FID_COPY copies between two fids */
2507c478bd9Sstevel@tonic-gate #define	CACHEFS_FID_COPY(in_fidp, out_fidp)				\
2517c478bd9Sstevel@tonic-gate 	(out_fidp)->fid_len = (in_fidp)->fid_len;			\
2527c478bd9Sstevel@tonic-gate 	bcopy((in_fidp)->fid_data, (out_fidp)->fid_data, (in_fidp)->fid_len)
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate #define	CACHEFS_VATTR_TO_VATTR32_COPY(in_vattrp, out_vattrp, error)	\
2557c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_mask = (in_vattrp)->va_mask;			\
2567c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_type = (in_vattrp)->va_type;			\
2577c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_mode = (in_vattrp)->va_mode;			\
2587c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_uid = (in_vattrp)->va_uid;			\
2597c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_gid = (in_vattrp)->va_gid;			\
2607c478bd9Sstevel@tonic-gate 	CACHEFS_DEV_TO_DEV32_COPY((in_vattrp)->va_fsid,			\
2617c478bd9Sstevel@tonic-gate 		(out_vattrp)->va_fsid, error);				\
2627c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_nodeid = (in_vattrp)->va_nodeid;		\
2637c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_nlink = (in_vattrp)->va_nlink;			\
2647c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_size = (in_vattrp)->va_size;			\
2657c478bd9Sstevel@tonic-gate 	CACHEFS_TS_TO_TS32_COPY(&(in_vattrp)->va_atime,			\
2667c478bd9Sstevel@tonic-gate 		&(out_vattrp)->va_atime, error);			\
2677c478bd9Sstevel@tonic-gate 	CACHEFS_TS_TO_TS32_COPY(&(in_vattrp)->va_mtime,			\
2687c478bd9Sstevel@tonic-gate 		&(out_vattrp)->va_mtime, error);			\
2697c478bd9Sstevel@tonic-gate 	CACHEFS_TS_TO_TS32_COPY(&(in_vattrp)->va_ctime, 		\
2707c478bd9Sstevel@tonic-gate 		&(out_vattrp)->va_ctime, error);			\
2717c478bd9Sstevel@tonic-gate 	CACHEFS_DEV_TO_DEV32_COPY((in_vattrp)->va_rdev,			\
2727c478bd9Sstevel@tonic-gate 		(out_vattrp)->va_rdev, error);				\
2737c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_blksize = (in_vattrp)->va_blksize;		\
2747c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_nblocks = (in_vattrp)->va_nblocks;		\
2757c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_seq = 0
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate #define	CACHEFS_VATTR32_TO_VATTR_COPY(in_vattrp, out_vattrp)		\
2787c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_mask = (in_vattrp)->va_mask;			\
2797c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_type = (in_vattrp)->va_type;			\
2807c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_mode = (in_vattrp)->va_mode;			\
2817c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_uid = (in_vattrp)->va_uid;			\
2827c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_gid = (in_vattrp)->va_gid;			\
2837c478bd9Sstevel@tonic-gate 	CACHEFS_DEV32_TO_DEV_COPY((in_vattrp)->va_fsid,			\
2847c478bd9Sstevel@tonic-gate 		(out_vattrp)->va_fsid);					\
2857c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_nodeid = (in_vattrp)->va_nodeid;		\
2867c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_nlink = (in_vattrp)->va_nlink;			\
2877c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_size = (in_vattrp)->va_size;			\
2887c478bd9Sstevel@tonic-gate 	CACHEFS_TS32_TO_TS_COPY(&(in_vattrp)->va_atime,			\
2897c478bd9Sstevel@tonic-gate 		&(out_vattrp)->va_atime);				\
2907c478bd9Sstevel@tonic-gate 	CACHEFS_TS32_TO_TS_COPY(&(in_vattrp)->va_mtime,			\
2917c478bd9Sstevel@tonic-gate 		&(out_vattrp)->va_mtime);				\
2927c478bd9Sstevel@tonic-gate 	CACHEFS_TS32_TO_TS_COPY(&(in_vattrp)->va_ctime,			\
2937c478bd9Sstevel@tonic-gate 		&(out_vattrp)->va_ctime);				\
2947c478bd9Sstevel@tonic-gate 	CACHEFS_DEV32_TO_DEV_COPY((in_vattrp)->va_rdev,			\
2957c478bd9Sstevel@tonic-gate 		(out_vattrp)->va_rdev);					\
2967c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_blksize = (in_vattrp)->va_blksize;		\
2977c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_nblocks = (in_vattrp)->va_nblocks;		\
2987c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_seq = 0
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate #else /* not _SYSCALL32 && _LP64 */
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate /*
3037c478bd9Sstevel@tonic-gate  * The cfs_* types are used to represent on-disk data, since its size is
3047c478bd9Sstevel@tonic-gate  * independent of the kernel memory model (in the LP64 case)
3057c478bd9Sstevel@tonic-gate  */
3067c478bd9Sstevel@tonic-gate typedef time_t			cfs_time_t;
3077c478bd9Sstevel@tonic-gate typedef timestruc_t		cfs_timestruc_t;
3087c478bd9Sstevel@tonic-gate typedef vattr_t			cfs_vattr_t;
3097c478bd9Sstevel@tonic-gate typedef fid_t			cfs_fid_t;
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate #define	cfs_timespec		timespec
3127c478bd9Sstevel@tonic-gate #define	cfs_vattr		vattr
3137c478bd9Sstevel@tonic-gate #define	cfs_fid			fid
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate #define	TIME_OVERFLOW(tval)	FALSE
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate #define	CACHEFS_DEV_TO_DEV32_COPY(in_dev, out_dev, error)		\
3187c478bd9Sstevel@tonic-gate 	out_dev = (in_dev)
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate #define	CACHEFS_DEV32_TO_DEV_COPY(in_dev, out_dev)			\
3217c478bd9Sstevel@tonic-gate 	out_dev = (in_dev)
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate #define	CACHEFS_TIME_TO_TIME32_COPY(in_tval, out_tval, error)		\
3247c478bd9Sstevel@tonic-gate 	out_tval = (in_tval)
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate #define	CACHEFS_TIME32_TO_TIME_COPY(in_tval, out_tval)			\
3277c478bd9Sstevel@tonic-gate 	out_tval = (in_tval)
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate #define	CACHEFS_TS_TO_TS32_COPY(in_tsp, out_tsp, error)			\
3307c478bd9Sstevel@tonic-gate 	*(out_tsp) = *(in_tsp)
3317c478bd9Sstevel@tonic-gate 
3327c478bd9Sstevel@tonic-gate #define	CACHEFS_TS32_TO_TS_COPY(in_tsp, out_tsp)			\
3337c478bd9Sstevel@tonic-gate 	*(out_tsp) = *(in_tsp)
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate #define	CACHEFS_FID_COPY(in_fidp, out_fidp)				\
3367c478bd9Sstevel@tonic-gate 	*(out_fidp) = *(in_fidp)
3377c478bd9Sstevel@tonic-gate 
3387c478bd9Sstevel@tonic-gate #define	CACHEFS_VATTR_TO_VATTR32_COPY(in_vattrp, out_vattrp, error)	\
3397c478bd9Sstevel@tonic-gate 	*(out_vattrp) = *(in_vattrp);					\
3407c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_seq = 0
3417c478bd9Sstevel@tonic-gate 
3427c478bd9Sstevel@tonic-gate #define	CACHEFS_VATTR32_TO_VATTR_COPY(in_vattrp, out_vattrp)		\
3437c478bd9Sstevel@tonic-gate 	*(out_vattrp) = *(in_vattrp);					\
3447c478bd9Sstevel@tonic-gate 	(out_vattrp)->va_seq = 0
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate #endif /* _SYSCALL32 && _LP64 */
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate /*
3497c478bd9Sstevel@tonic-gate  * The "cfs_*" structs below refer to the on-disk structures. Presently
3507c478bd9Sstevel@tonic-gate  * they are 32-bit based. When they change to 64-bit, we'd have to modify the
3517c478bd9Sstevel@tonic-gate  * macros below accordingly.
3527c478bd9Sstevel@tonic-gate  */
3537c478bd9Sstevel@tonic-gate #define	CACHEFS_DEV_TO_CFS_DEV_COPY(in_dev, out_dev, error)		\
3547c478bd9Sstevel@tonic-gate 	CACHEFS_DEV_TO_DEV32_COPY(in_dev, out_dev, error)
3557c478bd9Sstevel@tonic-gate 
3567c478bd9Sstevel@tonic-gate #define	CACHEFS_CFS_DEV_TO_DEV_COPY(in_dev, out_dev)		\
3577c478bd9Sstevel@tonic-gate 	CACHEFS_DEV32_TO_DEV_COPY(in_dev, out_dev)
3587c478bd9Sstevel@tonic-gate 
3597c478bd9Sstevel@tonic-gate #define	CACHEFS_TIME_TO_CFS_TIME_COPY(in_tval, out_tval, error)		\
3607c478bd9Sstevel@tonic-gate 	CACHEFS_TIME_TO_TIME32_COPY(in_tval, out_tval, error)
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate #define	CACHEFS_CFS_TIME_TO_TIME_COPY(in_tval, out_tval)		\
3637c478bd9Sstevel@tonic-gate 	CACHEFS_TIME32_TO_TIME_COPY(in_tval, out_tval)
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate #define	CACHEFS_TS_TO_CFS_TS_COPY(in_tsp, out_tsp, error)		\
3667c478bd9Sstevel@tonic-gate 	CACHEFS_TS_TO_TS32_COPY(in_tsp, out_tsp, error)
3677c478bd9Sstevel@tonic-gate 
3687c478bd9Sstevel@tonic-gate #define	CACHEFS_CFS_TS_TO_TS_COPY(in_tsp, out_tsp)			\
3697c478bd9Sstevel@tonic-gate 	CACHEFS_TS32_TO_TS_COPY(in_tsp, out_tsp)
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate #define	CACHEFS_VATTR_TO_CFS_VATTR_COPY(in_vattrp, out_vattrp, error)	\
3727c478bd9Sstevel@tonic-gate 	CACHEFS_VATTR_TO_VATTR32_COPY(in_vattrp, out_vattrp, error)
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate #define	CACHEFS_CFS_VATTR_TO_VATTR_COPY(in_vattrp, out_vattrp)		\
3757c478bd9Sstevel@tonic-gate 	CACHEFS_VATTR32_TO_VATTR_COPY(in_vattrp, out_vattrp)
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate #include <sys/fs/cachefs_fscache.h>
3787c478bd9Sstevel@tonic-gate #include <sys/fs/cachefs_filegrp.h>
3797c478bd9Sstevel@tonic-gate 
3807c478bd9Sstevel@tonic-gate /*
3817c478bd9Sstevel@tonic-gate  * One cache_label structure per cache. Contains mainly user defined or
3827c478bd9Sstevel@tonic-gate  * default values for cache resource management. Contents is static.
3837c478bd9Sstevel@tonic-gate  * The value cl_maxfiles is not used any where in cachefs code. If and when
3847c478bd9Sstevel@tonic-gate  * this is really used the cl_maxfiles should be declared as a 64bit value
3857c478bd9Sstevel@tonic-gate  * for large file support.
3867c478bd9Sstevel@tonic-gate  * The maxblks, blkhiwat, blklowat, blocktresh, blockmin, may need to be
3877c478bd9Sstevel@tonic-gate  * 64bit values when we actually start supporting file systems of size
3887c478bd9Sstevel@tonic-gate  * greater than 1 terabyte.
3897c478bd9Sstevel@tonic-gate  */
3907c478bd9Sstevel@tonic-gate struct cache_label {
3917c478bd9Sstevel@tonic-gate 	int	cl_cfsversion;	/* cfs version number */
3927c478bd9Sstevel@tonic-gate 	int	cl_maxblks;	/* max blocks to be used by cache */
3937c478bd9Sstevel@tonic-gate 	int	cl_blkhiwat;	/* high water-mark for block usage */
3947c478bd9Sstevel@tonic-gate 	int	cl_blklowat;	/* low water-mark for block usage */
3957c478bd9Sstevel@tonic-gate 	int	cl_maxinodes;	/* max inodes to be used by cache */
3967c478bd9Sstevel@tonic-gate 	int	cl_filehiwat;	/* high water-mark for inode usage */
3977c478bd9Sstevel@tonic-gate 	int	cl_filelowat;	/* low water-mark for indoe usage */
3987c478bd9Sstevel@tonic-gate 	int	cl_blocktresh;	/* block max usage treshold */
3997c478bd9Sstevel@tonic-gate 	int	cl_blockmin;	/* block min usage treshold */
4007c478bd9Sstevel@tonic-gate 	int	cl_filetresh;	/* inode max usage treshold */
4017c478bd9Sstevel@tonic-gate 	int	cl_filemin;	/* inode min usage treshold */
4027c478bd9Sstevel@tonic-gate 	int	cl_maxfiles;	/* max cache file size */
4037c478bd9Sstevel@tonic-gate };
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate /*
4067c478bd9Sstevel@tonic-gate  * One cache_usage structure per cache. Keeps track of cache usage figures.
4077c478bd9Sstevel@tonic-gate  * Contents gets updated frequently.
4087c478bd9Sstevel@tonic-gate  */
4097c478bd9Sstevel@tonic-gate struct cache_usage {
4107c478bd9Sstevel@tonic-gate 	int	cu_blksused;	/* actual number of blocks used */
4117c478bd9Sstevel@tonic-gate 	int	cu_filesused;	/* actual number of files used */
4127c478bd9Sstevel@tonic-gate 	uint_t	cu_flags;	/* Cache state flags */
4137c478bd9Sstevel@tonic-gate 	ushort_t cu_unique;	/* Fid persistent uniquifier */
4147c478bd9Sstevel@tonic-gate };
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate #define	CUSAGE_ACTIVE	1	/* Cache is active */
4177c478bd9Sstevel@tonic-gate #define	CUSAGE_NEED_ADJUST 2	/* Adjust uniquifier before assigning new fid */
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate /*
4207c478bd9Sstevel@tonic-gate  * RL list identifiers.
4217c478bd9Sstevel@tonic-gate  */
4227c478bd9Sstevel@tonic-gate enum cachefs_rl_type {
4237c478bd9Sstevel@tonic-gate 	CACHEFS_RL_NONE = 0x101,
4247c478bd9Sstevel@tonic-gate 	CACHEFS_RL_FREE,
4257c478bd9Sstevel@tonic-gate 	CACHEFS_RL_GC,
4267c478bd9Sstevel@tonic-gate 	CACHEFS_RL_ACTIVE,
4277c478bd9Sstevel@tonic-gate 	CACHEFS_RL_ATTRFILE,
4287c478bd9Sstevel@tonic-gate 	CACHEFS_RL_MODIFIED,
4297c478bd9Sstevel@tonic-gate 	CACHEFS_RL_PACKED,
4307c478bd9Sstevel@tonic-gate 	CACHEFS_RL_PACKED_PENDING,
4317c478bd9Sstevel@tonic-gate 	CACHEFS_RL_MF
4327c478bd9Sstevel@tonic-gate };
4337c478bd9Sstevel@tonic-gate #define	CACHEFS_RL_START CACHEFS_RL_NONE
4347c478bd9Sstevel@tonic-gate #define	CACHEFS_RL_END CACHEFS_RL_MF
4357c478bd9Sstevel@tonic-gate #define	CACHEFS_RL_CNT	(CACHEFS_RL_END - CACHEFS_RL_START + 1)
4367c478bd9Sstevel@tonic-gate #define	CACHEFS_RL_INDEX(X)	(X - CACHEFS_RL_START)
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate struct cachefs_rl_listhead {
4397c478bd9Sstevel@tonic-gate 	uint_t		rli_front;		/* front of list */
4407c478bd9Sstevel@tonic-gate 	uint_t		rli_back;		/* back of list */
4417c478bd9Sstevel@tonic-gate 	int		rli_blkcnt;		/* number of 8k blocks */
4427c478bd9Sstevel@tonic-gate 	int		rli_itemcnt;		/* number of items on list */
4437c478bd9Sstevel@tonic-gate };
4447c478bd9Sstevel@tonic-gate typedef struct cachefs_rl_listhead cachefs_rl_listhead_t;
4457c478bd9Sstevel@tonic-gate 
4467c478bd9Sstevel@tonic-gate /*
4477c478bd9Sstevel@tonic-gate  * Resource List information.  One per cache.
4487c478bd9Sstevel@tonic-gate  */
4497c478bd9Sstevel@tonic-gate struct cachefs_rl_info {
4507c478bd9Sstevel@tonic-gate 	uint_t		rl_entries;	/* number of entries allocated in rl */
4517c478bd9Sstevel@tonic-gate 	cfs_time_t	rl_gctime;	/* time of item on front of gc list */
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate 	/* heads of the various lists */
4547c478bd9Sstevel@tonic-gate 	cachefs_rl_listhead_t	rl_items[CACHEFS_RL_CNT];
4557c478bd9Sstevel@tonic-gate };
4567c478bd9Sstevel@tonic-gate typedef struct cachefs_rl_info cachefs_rl_info_t;
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate /*
4597c478bd9Sstevel@tonic-gate  * rl_debug and rl_entry are stored on disk, so they need to be
4607c478bd9Sstevel@tonic-gate  * the same 32-bit vs. 64-bit.
4617c478bd9Sstevel@tonic-gate  */
4627c478bd9Sstevel@tonic-gate 
4637c478bd9Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
4647c478bd9Sstevel@tonic-gate #pragma pack(4)
4657c478bd9Sstevel@tonic-gate #endif
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate #ifdef CFSRLDEBUG
4687c478bd9Sstevel@tonic-gate /*
4697c478bd9Sstevel@tonic-gate  * RL debugging thingy
4707c478bd9Sstevel@tonic-gate  */
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate #define	CACHEFS_RLDB_STACKSIZE	16
4737c478bd9Sstevel@tonic-gate #define	CACHEFS_RLDB_DEF_MAXCOUNT 5
4747c478bd9Sstevel@tonic-gate 
4757c478bd9Sstevel@tonic-gate typedef struct rl_debug {
4767c478bd9Sstevel@tonic-gate 	hrtime_t db_hrtime;
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate 	uint_t db_attrc: 1;
4797c478bd9Sstevel@tonic-gate 	uint_t db_fsck: 1;
4807c478bd9Sstevel@tonic-gate 	ino64_t db_fsid;
4817c478bd9Sstevel@tonic-gate 	ino64_t db_fileno;
4827c478bd9Sstevel@tonic-gate 	enum cachefs_rl_type db_current;
4837c478bd9Sstevel@tonic-gate 
4847c478bd9Sstevel@tonic-gate 	int db_stackheight;
4857c478bd9Sstevel@tonic-gate 	pc_t db_stack[CACHEFS_RLDB_STACKSIZE];
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate 	struct rl_debug *db_next;
4887c478bd9Sstevel@tonic-gate } rl_debug_t;
4897c478bd9Sstevel@tonic-gate 
4907c478bd9Sstevel@tonic-gate extern time_t cachefs_dbvalid;
4917c478bd9Sstevel@tonic-gate extern struct kmem_cache *cachefs_rl_debug_cache;
4927c478bd9Sstevel@tonic-gate extern kmutex_t cachefs_rl_debug_mutex;
4937c478bd9Sstevel@tonic-gate #endif /* CFSRLDEBUG */
4947c478bd9Sstevel@tonic-gate 
4957c478bd9Sstevel@tonic-gate /*
4967c478bd9Sstevel@tonic-gate  * RL Entry type.
4977c478bd9Sstevel@tonic-gate  */
4987c478bd9Sstevel@tonic-gate 
4997c478bd9Sstevel@tonic-gate typedef struct rl_entry {
5007c478bd9Sstevel@tonic-gate 	uint_t rl_attrc: 1;
5017c478bd9Sstevel@tonic-gate 	uint_t rl_fsck: 1; /* used by fsck; true => rl_current is correct */
5027c478bd9Sstevel@tonic-gate 	uint_t rl_local: 1; /* 1 means a local file */
5037c478bd9Sstevel@tonic-gate 
5047c478bd9Sstevel@tonic-gate #ifdef CFSRLDEBUG
5057c478bd9Sstevel@tonic-gate 	cfs_time_t rl_dbvalid; /* this == cachefs_dbvalid => trust rl_debug */
5067c478bd9Sstevel@tonic-gate 	rl_debug_t *rl_debug;
5077c478bd9Sstevel@tonic-gate #endif /* CFSRLDEBUG */
5087c478bd9Sstevel@tonic-gate 
5097c478bd9Sstevel@tonic-gate 	ino64_t rl_fsid;
5107c478bd9Sstevel@tonic-gate 	ino64_t rl_fileno;
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate 	enum cachefs_rl_type rl_current;
5137c478bd9Sstevel@tonic-gate 	uint_t rl_fwd_idx;
5147c478bd9Sstevel@tonic-gate 	uint_t rl_bkwd_idx;
5157c478bd9Sstevel@tonic-gate } rl_entry_t;
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
5187c478bd9Sstevel@tonic-gate #pragma pack()
5197c478bd9Sstevel@tonic-gate #endif
5207c478bd9Sstevel@tonic-gate 
5217c478bd9Sstevel@tonic-gate /*
5227c478bd9Sstevel@tonic-gate  * rl entries per MAXBSIZE chunk.  rl_entry_t's size need not divide
5237c478bd9Sstevel@tonic-gate  * MAXBSIZE, as long as this constant is an integer (through integer
5247c478bd9Sstevel@tonic-gate  * division) (see cachefs_rl_entry_get()).
5257c478bd9Sstevel@tonic-gate  */
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate #define	CACHEFS_RLPMBS	(MAXBSIZE / (uint_t)sizeof (rl_entry_t))
5287c478bd9Sstevel@tonic-gate 
5297c478bd9Sstevel@tonic-gate /*
5307c478bd9Sstevel@tonic-gate  * struct cache contains cache-wide information, and provides access
5317c478bd9Sstevel@tonic-gate  * to lower level info. There is one cache structure per cache.
5327c478bd9Sstevel@tonic-gate  */
5337c478bd9Sstevel@tonic-gate struct cachefscache {
5347c478bd9Sstevel@tonic-gate 	struct cachefscache	*c_next;	/* list of caches */
5357c478bd9Sstevel@tonic-gate 	uint_t			c_flags;	/* misc flags */
5367c478bd9Sstevel@tonic-gate 	struct cache_label	c_label;	/* cache resource info */
5377c478bd9Sstevel@tonic-gate 	struct cache_usage	c_usage;	/* cache usage info */
5387c478bd9Sstevel@tonic-gate 	struct cachefs_rl_info	c_rlinfo;	/* rl global pointers */
5397c478bd9Sstevel@tonic-gate 	struct vnode		*c_resfilevp;	/* resource file vp */
5407c478bd9Sstevel@tonic-gate 	uint_t			c_rl_window;	/* window mapped in */
5417c478bd9Sstevel@tonic-gate 	rl_entry_t		*c_rl_entries;	/* mapping for rl entries */
5427c478bd9Sstevel@tonic-gate 	struct vnode		*c_dirvp;	/* cache directory vp */
5437c478bd9Sstevel@tonic-gate 	struct vnode		*c_lockvp;	/* lock file vp */
5447c478bd9Sstevel@tonic-gate 	struct vnode		*c_lostfoundvp;	/* lost+found directory vp */
5457c478bd9Sstevel@tonic-gate 	int			c_refcnt;	/* active fs ref count */
5467c478bd9Sstevel@tonic-gate 	struct fscache		*c_fslist;	/* fscache list head */
5477c478bd9Sstevel@tonic-gate 	struct cachefs_workq	c_workq;	/* async work */
5487c478bd9Sstevel@tonic-gate 	kmutex_t		c_contentslock; /* protect cache struct */
5497c478bd9Sstevel@tonic-gate 	kmutex_t		c_fslistlock;	/* protect fscache list */
5507c478bd9Sstevel@tonic-gate 	kmutex_t		c_mflock;	/* protect modified fixes */
5517c478bd9Sstevel@tonic-gate 	ushort_t		c_unique;	/* In core fid uniquifier */
5527c478bd9Sstevel@tonic-gate 	kcondvar_t		c_cwcv;		/* gc wait on work to do */
5537c478bd9Sstevel@tonic-gate 	kcondvar_t		c_cwhaltcv;	/* wait on gc thread exit */
5547c478bd9Sstevel@tonic-gate 	uint_t			c_gc_count;	/* garbage collection count */
5557c478bd9Sstevel@tonic-gate 	time_t			c_gc_time;	/* last garbage collection */
5567c478bd9Sstevel@tonic-gate 	time_t			c_gc_before;	/* atime of front before gc */
5577c478bd9Sstevel@tonic-gate 	time_t			c_gc_after;	/* atime of front after gc */
5587c478bd9Sstevel@tonic-gate 	uint_t			c_apop_inqueue;	/* # async pops queued */
5597c478bd9Sstevel@tonic-gate 	pid_t			c_rootdaemonid;	/* pid of root cachefsd */
5607c478bd9Sstevel@tonic-gate 	struct cachefs_log_cookie
5617c478bd9Sstevel@tonic-gate 				*c_log;		/* in-core logging stuff */
5627c478bd9Sstevel@tonic-gate 	struct cachefs_log_control
5637c478bd9Sstevel@tonic-gate 				*c_log_ctl;	/* on-disk logging stuff */
5647c478bd9Sstevel@tonic-gate 	kmutex_t		c_log_mutex;	/* protects c_log* */
5657c478bd9Sstevel@tonic-gate };
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate extern struct kmem_cache *cachefs_cache_kmcache;
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate #define	CACHEFS_MAX_APOP_INQUEUE	50	/* default value for below */
5707c478bd9Sstevel@tonic-gate extern uint_t cachefs_max_apop_inqueue;		/* max populations pending */
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate /*
5737c478bd9Sstevel@tonic-gate  * Various cache structure flags.
5747c478bd9Sstevel@tonic-gate  */
5757c478bd9Sstevel@tonic-gate #define	CACHE_NOCACHE		0x1	/* all cache refs go to back fs */
5767c478bd9Sstevel@tonic-gate #define	CACHE_ALLOC_PENDING	0x4	/* Allocation pending */
5777c478bd9Sstevel@tonic-gate #define	CACHE_NOFILL		0x8	/* No fill mode */
5787c478bd9Sstevel@tonic-gate #define	CACHE_GARBAGE_COLLECT	0x10	/* Garbage collect in progress */
5797c478bd9Sstevel@tonic-gate #define	CACHE_CACHEW_THREADRUN	0x20	/* Cachep worker thread is alive */
5807c478bd9Sstevel@tonic-gate #define	CACHE_CACHEW_THREADEXIT 0x40	/* cachew thread should exit */
5817c478bd9Sstevel@tonic-gate #define	CACHE_DIRTY		0x80
5827c478bd9Sstevel@tonic-gate #define	CACHE_PACKED_PENDING	0x100	/* Packed pending work to do */
5837c478bd9Sstevel@tonic-gate #define	CACHE_CHECK_RLTYPE	0x200	/* double-check with resource lists */
5847c478bd9Sstevel@tonic-gate 
5857c478bd9Sstevel@tonic-gate /*
5867c478bd9Sstevel@tonic-gate  * Values for the mount options flag, opt_flags.
5877c478bd9Sstevel@tonic-gate  */
5887c478bd9Sstevel@tonic-gate /*
5897c478bd9Sstevel@tonic-gate  * Mount options
5907c478bd9Sstevel@tonic-gate  */
5917c478bd9Sstevel@tonic-gate #define	CFS_WRITE_AROUND	0x01	/* write-around */
5927c478bd9Sstevel@tonic-gate #define	CFS_NONSHARED		0x02	/* write to cache and back file */
5937c478bd9Sstevel@tonic-gate #define	CFS_NOCONST_MODE	0x08	/* no-op consistency mode */
5947c478bd9Sstevel@tonic-gate #define	CFS_ACCESS_BACKFS	0x10	/* pass VOP_ACCESS to backfs */
5957c478bd9Sstevel@tonic-gate #define	CFS_CODCONST_MODE	0x80	/* cod consistency mode */
5967c478bd9Sstevel@tonic-gate #define	CFS_DISCONNECTABLE	0x100	/* server not reponding option */
5977c478bd9Sstevel@tonic-gate #define	CFS_SOFT		0x200	/* soft mounted */
5987c478bd9Sstevel@tonic-gate #define	CFS_NOACL		0x400	/* ACLs are disabled in this fs */
5997c478bd9Sstevel@tonic-gate #define	CFS_LLOCK		0x800	/* use local file/record locks */
6007c478bd9Sstevel@tonic-gate #define	CFS_SLIDE		0x1000	/* slide backfs under cachefs */
6017c478bd9Sstevel@tonic-gate #define	CFS_NOFILL		0x2000	/* start in nofill mode */
6027c478bd9Sstevel@tonic-gate #define	CFS_BACKFS_NFSV4	0x4000	/* back filesystem is NFSv4 */
6037c478bd9Sstevel@tonic-gate 
6047c478bd9Sstevel@tonic-gate #define	MAXCOOKIE_SIZE	36
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate #define	C_BACK_CHECK	0x2
6077c478bd9Sstevel@tonic-gate 
6087c478bd9Sstevel@tonic-gate /*
6097c478bd9Sstevel@tonic-gate  * Macro to determine if this is a snr error where we should do a
6107c478bd9Sstevel@tonic-gate  * state transition.
6117c478bd9Sstevel@tonic-gate  */
6127c478bd9Sstevel@tonic-gate 
6137c478bd9Sstevel@tonic-gate #define	CFS_TIMEOUT(FSCP, ERROR) \
6147c478bd9Sstevel@tonic-gate 	(ERROR && CFS_ISFS_SNR(FSCP) && \
6157c478bd9Sstevel@tonic-gate 	(((ERROR) == ETIMEDOUT) || ((ERROR) == EIO)))
6167c478bd9Sstevel@tonic-gate 
6177c478bd9Sstevel@tonic-gate /*
6187c478bd9Sstevel@tonic-gate  * Macros to assert that cachefs fscache and cnode are in
6197c478bd9Sstevel@tonic-gate  * sync with NFSv4. Note that NFSv4 always passes-through
6207c478bd9Sstevel@tonic-gate  * the vnode calls directly to the backfilesystem. For
6217c478bd9Sstevel@tonic-gate  * this to work:
6227c478bd9Sstevel@tonic-gate  * (1) cachefs is always setup for connected operation,
6237c478bd9Sstevel@tonic-gate  * (2) cachefs options (example disconnectable (snr), nonshared, etc)
6247c478bd9Sstevel@tonic-gate  *     are disabled, and
6257c478bd9Sstevel@tonic-gate  * (3) the back filesystem vnode pointer always exists
6267c478bd9Sstevel@tonic-gate  *      (except after a remove operation)
6277c478bd9Sstevel@tonic-gate  * (4) the front filesystem vnode pointer is always NULL.
6287c478bd9Sstevel@tonic-gate  */
6297c478bd9Sstevel@tonic-gate #ifdef DEBUG
6307c478bd9Sstevel@tonic-gate #define	CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp) \
6317c478bd9Sstevel@tonic-gate 	if (CFS_ISFS_BACKFS_NFSV4(fscp)) { \
6327c478bd9Sstevel@tonic-gate 		ASSERT((fscp)->fs_info.fi_mntflags == CFS_BACKFS_NFSV4); \
6337c478bd9Sstevel@tonic-gate 		ASSERT((fscp)->fs_cdconnected == CFS_CD_CONNECTED); \
6347c478bd9Sstevel@tonic-gate 	}
6357c478bd9Sstevel@tonic-gate #define	CFS_BACKFS_NFSV4_ASSERT_CNODE(cp) \
6367c478bd9Sstevel@tonic-gate 	if (CFS_ISFS_BACKFS_NFSV4(fscp)) { \
6377c478bd9Sstevel@tonic-gate 		if (MUTEX_HELD(&cp->c_statelock)) { \
6387c478bd9Sstevel@tonic-gate 			ASSERT((cp)->c_backvp != NULL || \
6397c478bd9Sstevel@tonic-gate 				((cp)->c_flags & CN_DESTROY) != 0); \
6407c478bd9Sstevel@tonic-gate 			ASSERT((cp)->c_frontvp == NULL); \
6417c478bd9Sstevel@tonic-gate 		} else { \
6427c478bd9Sstevel@tonic-gate 			mutex_enter(&(cp)->c_statelock); \
6437c478bd9Sstevel@tonic-gate 			ASSERT((cp)->c_backvp != NULL || \
6447c478bd9Sstevel@tonic-gate 				((cp)->c_flags & CN_DESTROY) != 0); \
6457c478bd9Sstevel@tonic-gate 			ASSERT((cp)->c_frontvp == NULL); \
6467c478bd9Sstevel@tonic-gate 			mutex_exit(&cp->c_statelock); \
6477c478bd9Sstevel@tonic-gate 		} \
6487c478bd9Sstevel@tonic-gate 	}
6497c478bd9Sstevel@tonic-gate #else
6507c478bd9Sstevel@tonic-gate #define	CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp)
6517c478bd9Sstevel@tonic-gate #define	CFS_BACKFS_NFSV4_ASSERT_CNODE(cp)
6527c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
6537c478bd9Sstevel@tonic-gate 
6547c478bd9Sstevel@tonic-gate #ifdef CFSDEBUG
6557c478bd9Sstevel@tonic-gate #define	CFS_DPRINT_BACKFS_NFSV4(fscp, x) \
6567c478bd9Sstevel@tonic-gate 	if (CFS_ISFS_BACKFS_NFSV4(fscp)) { \
6577c478bd9Sstevel@tonic-gate 		CFS_DEBUG(CFSDEBUG_VOPS_NFSV4) \
6587c478bd9Sstevel@tonic-gate 			printf x; \
6597c478bd9Sstevel@tonic-gate 	}
6607c478bd9Sstevel@tonic-gate #else
6617c478bd9Sstevel@tonic-gate #define	CFS_DPRINT_BACKFS_NFSV4(fscp, x)
6627c478bd9Sstevel@tonic-gate #endif /* CFSDEBUG */
6637c478bd9Sstevel@tonic-gate 
6647c478bd9Sstevel@tonic-gate /*
6657c478bd9Sstevel@tonic-gate  * cachefs_allocmap and cfs_cachefs_metadata are stored on disk,
6667c478bd9Sstevel@tonic-gate  * so they need to be the same 32-bit vs. 64-bit.
6677c478bd9Sstevel@tonic-gate  */
6687c478bd9Sstevel@tonic-gate 
6697c478bd9Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
6707c478bd9Sstevel@tonic-gate #pragma pack(4)
6717c478bd9Sstevel@tonic-gate #endif
6727c478bd9Sstevel@tonic-gate 
6737c478bd9Sstevel@tonic-gate /*
6747c478bd9Sstevel@tonic-gate  * Large file support. The start offset of the cached file can be
6757c478bd9Sstevel@tonic-gate  * greater than 2GB and by coelescing the different chunks we may
6767c478bd9Sstevel@tonic-gate  * end up having a chunk of siz3 > 2GB.
6777c478bd9Sstevel@tonic-gate  */
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate struct cachefs_allocmap {
6807c478bd9Sstevel@tonic-gate 	u_offset_t		am_start_off;	/* Start offset of this chunk */
6817c478bd9Sstevel@tonic-gate 	u_offset_t		am_size;	/* size of this chunk */
6827c478bd9Sstevel@tonic-gate };
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate #define	C_MAX_ALLOCINFO_SLOTS	32
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate /*
6877c478bd9Sstevel@tonic-gate  * CFS fastsymlinks. For symlink of size < C_FSL_SIZE, the symlink
6887c478bd9Sstevel@tonic-gate  * is stored in the cnode allocmap array.
6897c478bd9Sstevel@tonic-gate  */
6907c478bd9Sstevel@tonic-gate #define	C_FSL_SIZE	(sizeof (struct cachefs_allocmap) * \
6917c478bd9Sstevel@tonic-gate 			C_MAX_ALLOCINFO_SLOTS)
6927c478bd9Sstevel@tonic-gate 
6937c478bd9Sstevel@tonic-gate /*
6947c478bd9Sstevel@tonic-gate  * Structure representing a cached object in memory.
6957c478bd9Sstevel@tonic-gate  */
6967c478bd9Sstevel@tonic-gate struct cachefs_metadata {
6977c478bd9Sstevel@tonic-gate 	struct vattr		md_vattr;	/* attributes */
6987c478bd9Sstevel@tonic-gate 	o_mode_t		md_aclclass;	/* CLASS_OBJ perm for ACL */
6997c478bd9Sstevel@tonic-gate 	ushort_t		md_pad1;	/* compiler padding */
7007c478bd9Sstevel@tonic-gate 	fid_t			md_cookie;	/* back fid */
7017c478bd9Sstevel@tonic-gate 	int			md_flags;	/* various flags */
7027c478bd9Sstevel@tonic-gate 	uint_t			md_rlno;	/* rl entry */
7037c478bd9Sstevel@tonic-gate 	enum cachefs_rl_type	md_rltype;	/* rl type */
7047c478bd9Sstevel@tonic-gate 	int			md_consttype;	/* type of consistency */
7057c478bd9Sstevel@tonic-gate 	fid_t			md_fid;		/* fid of front file */
7067c478bd9Sstevel@tonic-gate 	uint_t			md_frontblks;	/* # blks used in frontfs */
7077c478bd9Sstevel@tonic-gate 	uint_t			md_gen;		/* fid uniquifier */
7087c478bd9Sstevel@tonic-gate 	struct cfs_cid		md_parent;	/* id of parent */
7097c478bd9Sstevel@tonic-gate 	timestruc_t		md_timestamp;	/* front file timestamp */
7107c478bd9Sstevel@tonic-gate 	timestruc_t		md_x_time;	/* see consistency routines */
7117c478bd9Sstevel@tonic-gate 	timestruc_t		md_localmtime;	/* persistent local mtime */
7127c478bd9Sstevel@tonic-gate 	timestruc_t		md_localctime;	/* persistent local ctime */
7137c478bd9Sstevel@tonic-gate 	uint_t			md_resettimes;	/* when to reset local times */
7147c478bd9Sstevel@tonic-gate 	ino64_t			md_localfileno;	/* persistent local inum */
7157c478bd9Sstevel@tonic-gate 	uint_t			md_resetfileno;	/* when to reset local fileno */
7167c478bd9Sstevel@tonic-gate 	uint_t			md_seq;		/* seq number for putpage */
7177c478bd9Sstevel@tonic-gate 	int			md_allocents;	/* nbr of entries in allocmap */
7187c478bd9Sstevel@tonic-gate 	struct cachefs_allocmap	md_allocinfo[C_MAX_ALLOCINFO_SLOTS];
7197c478bd9Sstevel@tonic-gate };
7207c478bd9Sstevel@tonic-gate typedef struct cachefs_metadata cachefs_metadata_t;
7217c478bd9Sstevel@tonic-gate 
7227c478bd9Sstevel@tonic-gate #if (defined(_SYSCALL32) && defined(_LP64))
7237c478bd9Sstevel@tonic-gate 
7247c478bd9Sstevel@tonic-gate /*
7257c478bd9Sstevel@tonic-gate  * fid_t is long aligned, so user fid could be only 4 byte aligned.
7267c478bd9Sstevel@tonic-gate  * Since vnode/vfs calls require fid_t (which would be 8 byte aligned in
7277c478bd9Sstevel@tonic-gate  * _LP64), we would have to copy the user's value (and on-disk data) in/out.
7287c478bd9Sstevel@tonic-gate  */
7297c478bd9Sstevel@tonic-gate /* on-disk metadata structure - fid aligned to int, time is 32-bit */
7307c478bd9Sstevel@tonic-gate 
7317c478bd9Sstevel@tonic-gate struct cfs_cachefs_metadata {
7327c478bd9Sstevel@tonic-gate 	struct cfs_vattr	md_vattr;	/* attributes */
7337c478bd9Sstevel@tonic-gate 	o_mode_t		md_aclclass;	/* CLASS_OBJ perm for ACL */
7347c478bd9Sstevel@tonic-gate 	cfs_fid_t		md_cookie;	/* back fid */
7357c478bd9Sstevel@tonic-gate 	int			md_flags;	/* various flags */
7367c478bd9Sstevel@tonic-gate 	uint_t			md_rlno;	/* rl entry */
7377c478bd9Sstevel@tonic-gate 	enum cachefs_rl_type	md_rltype;	/* rl type */
7387c478bd9Sstevel@tonic-gate 	int			md_consttype;	/* type of consistency */
7397c478bd9Sstevel@tonic-gate 	cfs_fid_t		md_fid;		/* fid of front file */
7407c478bd9Sstevel@tonic-gate 	uint_t			md_frontblks;	/* # blks used in frontfs */
7417c478bd9Sstevel@tonic-gate 	uint_t			md_gen;		/* fid uniquifier */
7427c478bd9Sstevel@tonic-gate 	struct cfs_cid		md_parent;	/* id of parent */
7437c478bd9Sstevel@tonic-gate 	cfs_timestruc_t		md_timestamp;	/* front file timestamp */
7447c478bd9Sstevel@tonic-gate 	cfs_timestruc_t		md_x_time;	/* see consistency routines */
7457c478bd9Sstevel@tonic-gate 	cfs_timestruc_t		md_localmtime;	/* persistent local mtime */
7467c478bd9Sstevel@tonic-gate 	cfs_timestruc_t		md_localctime;	/* persistent local ctime */
7477c478bd9Sstevel@tonic-gate 	uint_t			md_resettimes;	/* when to reset local times */
7487c478bd9Sstevel@tonic-gate 	ino64_t			md_localfileno;	/* persistent local inum */
7497c478bd9Sstevel@tonic-gate 	uint_t			md_resetfileno;	/* when to reset local fileno */
7507c478bd9Sstevel@tonic-gate 	uint_t			md_seq;		/* seq number for putpage */
7517c478bd9Sstevel@tonic-gate 	int			md_allocents;	/* nbr of entries in allocmap */
7527c478bd9Sstevel@tonic-gate 	struct cachefs_allocmap	md_allocinfo[C_MAX_ALLOCINFO_SLOTS];
7537c478bd9Sstevel@tonic-gate };
7547c478bd9Sstevel@tonic-gate typedef struct cfs_cachefs_metadata cfs_cachefs_metadata_t;
7557c478bd9Sstevel@tonic-gate 
7567c478bd9Sstevel@tonic-gate #else /* not _SYSCALL32 && _LP64 */
7577c478bd9Sstevel@tonic-gate 
7587c478bd9Sstevel@tonic-gate typedef cachefs_metadata_t	cfs_cachefs_metadata_t;
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate #define	cfs_cachefs_metadata	cachefs_metadata
7617c478bd9Sstevel@tonic-gate 
7627c478bd9Sstevel@tonic-gate #endif /* _SYSCALL32 && _LP64 */
7637c478bd9Sstevel@tonic-gate 
7647c478bd9Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
7657c478bd9Sstevel@tonic-gate #pragma pack()
7667c478bd9Sstevel@tonic-gate #endif
7677c478bd9Sstevel@tonic-gate 
7687c478bd9Sstevel@tonic-gate /*
7697c478bd9Sstevel@tonic-gate  * Various flags to be stored in md_flags field of the metadata.
7707c478bd9Sstevel@tonic-gate  */
7717c478bd9Sstevel@tonic-gate #define	MD_CREATEDONE	0x1		/* create was done to backfs */
7727c478bd9Sstevel@tonic-gate #define	MD_POPULATED	0x2		/* front file or dir is populated */
7737c478bd9Sstevel@tonic-gate #define	MD_FILE		0x4		/* front file or dir exists */
7747c478bd9Sstevel@tonic-gate #define	MD_FASTSYMLNK	0x8		/* fast symbolic link */
7757c478bd9Sstevel@tonic-gate #define	MD_PACKED	0x10		/* file is packed */
7767c478bd9Sstevel@tonic-gate #define	MD_INVALREADDIR	0x40		/* repopulate on readdir */
7777c478bd9Sstevel@tonic-gate #define	MD_PUTPAGE	0x200		/* we have already logged a putpage */
7787c478bd9Sstevel@tonic-gate #define	MD_FREE		0x400		/* not used */
7797c478bd9Sstevel@tonic-gate #define	MD_PUSHDONE	0x800		/* set if file pushed to back fs */
7807c478bd9Sstevel@tonic-gate #define	MD_MAPPING	0x1000		/* set if cid mapping space written */
7817c478bd9Sstevel@tonic-gate #define	MD_ACL		0x2000		/* file has a cached acl */
7827c478bd9Sstevel@tonic-gate #define	MD_ACLDIR	0x4000		/* front `dir' exists for holding acl */
7837c478bd9Sstevel@tonic-gate #define	MD_LOCALMTIME	0x8000		/* do not overwrite md_localmtime */
7847c478bd9Sstevel@tonic-gate #define	MD_LOCALCTIME	0x10000		/* do not overwrite md_localctime */
7857c478bd9Sstevel@tonic-gate #define	MD_LOCALFILENO	0x20000		/* do not overwrite md_localfileno */
7867c478bd9Sstevel@tonic-gate #define	MD_NEEDATTRS	0x40000		/* new attrs needed at next check */
7877c478bd9Sstevel@tonic-gate 
7887c478bd9Sstevel@tonic-gate #define	C_MAX_MOUNT_FSCDIRNAME		128
7897c478bd9Sstevel@tonic-gate /*
7907c478bd9Sstevel@tonic-gate  * cachefs mount structure and related data
7917c478bd9Sstevel@tonic-gate  */
7927c478bd9Sstevel@tonic-gate struct cachefs_mountargs {
7937c478bd9Sstevel@tonic-gate 	struct cachefsoptions	cfs_options;	/* consistency modes, etc. */
7947c478bd9Sstevel@tonic-gate 	char			*cfs_fsid;	/* CFS ID fpr file system */
7957c478bd9Sstevel@tonic-gate 	char			cfs_cacheid[C_MAX_MOUNT_FSCDIRNAME];
7967c478bd9Sstevel@tonic-gate 	/* CFS fscdir name */
7977c478bd9Sstevel@tonic-gate 	char			*cfs_cachedir;	/* path for this cache dir */
7987c478bd9Sstevel@tonic-gate 	char			*cfs_backfs;	/* back filesystem dir */
7997c478bd9Sstevel@tonic-gate 	uint_t			cfs_acregmin;	/* same as nfs values */
8007c478bd9Sstevel@tonic-gate 	uint_t			cfs_acregmax;
8017c478bd9Sstevel@tonic-gate 	uint_t			cfs_acdirmin;
8027c478bd9Sstevel@tonic-gate 	uint_t			cfs_acdirmax;
8037c478bd9Sstevel@tonic-gate 	char			*cfs_hostname;  /* server name */
8047c478bd9Sstevel@tonic-gate 	char			*cfs_backfsname; /* back filesystem name */
8057c478bd9Sstevel@tonic-gate };
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate #ifdef _SYSCALL32
8087c478bd9Sstevel@tonic-gate struct cachefs_mountargs32 {
8097c478bd9Sstevel@tonic-gate 	struct cachefsoptions	cfs_options;	/* consistency modes, etc. */
8107c478bd9Sstevel@tonic-gate 	caddr32_t		cfs_fsid;	/* CFS ID fpr file system */
8117c478bd9Sstevel@tonic-gate 	char			cfs_cacheid[C_MAX_MOUNT_FSCDIRNAME];
8127c478bd9Sstevel@tonic-gate 	/* CFS fscdir name */
8137c478bd9Sstevel@tonic-gate 	caddr32_t		cfs_cachedir;	/* path for this cache dir */
8147c478bd9Sstevel@tonic-gate 	caddr32_t		cfs_backfs;	/* back filesystem dir */
8157c478bd9Sstevel@tonic-gate 	uint32_t		cfs_acregmin;	/* same as nfs values */
8167c478bd9Sstevel@tonic-gate 	uint32_t		cfs_acregmax;
8177c478bd9Sstevel@tonic-gate 	uint32_t		cfs_acdirmin;
8187c478bd9Sstevel@tonic-gate 	uint32_t		cfs_acdirmax;
8197c478bd9Sstevel@tonic-gate 	caddr32_t		cfs_hostname;  /* server name */
8207c478bd9Sstevel@tonic-gate 	caddr32_t		cfs_backfsname; /* back filesystem name */
8217c478bd9Sstevel@tonic-gate };
8227c478bd9Sstevel@tonic-gate #endif /* _SYSCALL32 */
8237c478bd9Sstevel@tonic-gate 
8247c478bd9Sstevel@tonic-gate /*
8257c478bd9Sstevel@tonic-gate  * struct cachefsops - consistency modules.
8267c478bd9Sstevel@tonic-gate  */
8277c478bd9Sstevel@tonic-gate struct cachefsops {
8287c478bd9Sstevel@tonic-gate 	int	(*co_init_cobject)();
8297c478bd9Sstevel@tonic-gate 	int	(*co_check_cobject)();
8307c478bd9Sstevel@tonic-gate 	void	(*co_modify_cobject)();
8317c478bd9Sstevel@tonic-gate 	void	(*co_invalidate_cobject)();
8327c478bd9Sstevel@tonic-gate 	void	(*co_convert_cobject)();
8337c478bd9Sstevel@tonic-gate };
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate 
8367c478bd9Sstevel@tonic-gate 
8377c478bd9Sstevel@tonic-gate /*
8387c478bd9Sstevel@tonic-gate  * The attrcache file consists of a attrcache_header structure and an
8397c478bd9Sstevel@tonic-gate  * array of attrcache_slot structures (one per front file).
8407c478bd9Sstevel@tonic-gate  */
8417c478bd9Sstevel@tonic-gate 
8427c478bd9Sstevel@tonic-gate /*
8437c478bd9Sstevel@tonic-gate  * Attrcache file format
8447c478bd9Sstevel@tonic-gate  *
8457c478bd9Sstevel@tonic-gate  *	Header
8467c478bd9Sstevel@tonic-gate  *	Offset array (# of entries = file group size)
8477c478bd9Sstevel@tonic-gate  *	alloc list	(1 bit per entry, 0 = free) Note that the
8487c478bd9Sstevel@tonic-gate  *			file will be extended as needed
8497c478bd9Sstevel@tonic-gate  *	attrcache entries
8507c478bd9Sstevel@tonic-gate  *
8517c478bd9Sstevel@tonic-gate  */
8527c478bd9Sstevel@tonic-gate struct attrcache_header {
8537c478bd9Sstevel@tonic-gate 	uint_t		ach_count;		/* number of entries */
8547c478bd9Sstevel@tonic-gate 	int		ach_nffs;		/* number of front files */
8557c478bd9Sstevel@tonic-gate 	int		ach_nblks;		/* number of allocated blocks */
8567c478bd9Sstevel@tonic-gate 	uint_t		ach_rlno;		/* rl entry for this file */
8577c478bd9Sstevel@tonic-gate 	enum cachefs_rl_type ach_rl_current;	/* which list we're on */
8587c478bd9Sstevel@tonic-gate };
8597c478bd9Sstevel@tonic-gate 
8607c478bd9Sstevel@tonic-gate /*
8617c478bd9Sstevel@tonic-gate  * We assume that the seek offset to metadata will never be > 2GB.
8627c478bd9Sstevel@tonic-gate  * The filegrp size is 256 and the current calculations of the sizes
8637c478bd9Sstevel@tonic-gate  * of the data structures show that the ach_offset value here will not
8647c478bd9Sstevel@tonic-gate  * be > 2GB.
8657c478bd9Sstevel@tonic-gate  */
8667c478bd9Sstevel@tonic-gate 
8677c478bd9Sstevel@tonic-gate struct attrcache_index {
8687c478bd9Sstevel@tonic-gate 	uint_t	ach_written:1;		/* 1 if metadata written */
8697c478bd9Sstevel@tonic-gate 	uint_t	ach_offset:31;		/* seek offset to metadata */
8707c478bd9Sstevel@tonic-gate };
8717c478bd9Sstevel@tonic-gate 
8727c478bd9Sstevel@tonic-gate /*
8737c478bd9Sstevel@tonic-gate  * cnode structure, one per file.
8747c478bd9Sstevel@tonic-gate  */
8757c478bd9Sstevel@tonic-gate #define	c_attr			c_metadata.md_vattr
8767c478bd9Sstevel@tonic-gate #define	c_cookie		c_metadata.md_cookie
8777c478bd9Sstevel@tonic-gate #define	c_fileno		c_id.cid_fileno
8787c478bd9Sstevel@tonic-gate 
8797c478bd9Sstevel@tonic-gate /*
8807c478bd9Sstevel@tonic-gate  * LOCKS:	c_rwlock	Read / Write serialization
8817c478bd9Sstevel@tonic-gate  *		c_statelock	Protects most other fields in the cnode
8827c478bd9Sstevel@tonic-gate  *		c_popcv		Condvar used to prevent routines from nuking
8837c478bd9Sstevel@tonic-gate  *				a cnode which is currently being populated.
8847c478bd9Sstevel@tonic-gate  *				Threads blocked on it will be woken when the
8857c478bd9Sstevel@tonic-gate  *				populate completes.
8867c478bd9Sstevel@tonic-gate  *		c_iocv		broadcast, but never waited on - unused?
8877c478bd9Sstevel@tonic-gate  *		c_iomutex	c_nio and c_ioflags
8887c478bd9Sstevel@tonic-gate  *
8897c478bd9Sstevel@tonic-gate  * Fields protected by other locks:
8907c478bd9Sstevel@tonic-gate  *
8917c478bd9Sstevel@tonic-gate  *		c_next		fg_cnodelock in the filegrp struct
8927c478bd9Sstevel@tonic-gate  *		c_idleback	fs_idlelock in fscache struct
8937c478bd9Sstevel@tonic-gate  *		c_idlefront	fs_idlelock in fscache struct
8947c478bd9Sstevel@tonic-gate  *
8957c478bd9Sstevel@tonic-gate  * Large File support: c_size goes to u_offset_t and the apopoff type
8967c478bd9Sstevel@tonic-gate  * goes to offset_t.
8977c478bd9Sstevel@tonic-gate  */
8987c478bd9Sstevel@tonic-gate struct cnode {
8997c478bd9Sstevel@tonic-gate 	int		c_flags;	/* see below */
9007c478bd9Sstevel@tonic-gate 	struct cnode	*c_next;	/* next cnode in fgp list */
9017c478bd9Sstevel@tonic-gate 	struct cnode	*c_idleback;	/* idle list back ptr */
9027c478bd9Sstevel@tonic-gate 	struct cnode	*c_idlefront;	/* idle list front ptr */
9037c478bd9Sstevel@tonic-gate 	struct vnode	*c_frontvp;	/* front vnode pointer */
9047c478bd9Sstevel@tonic-gate 	struct vnode	*c_backvp;	/* back vnode pointer */
9057c478bd9Sstevel@tonic-gate 	struct vnode	*c_acldirvp;	/* dir for storing dflt ACL */
9067c478bd9Sstevel@tonic-gate 	u_offset_t	c_size;		/* client view of the size */
9077c478bd9Sstevel@tonic-gate 	struct filegrp	*c_filegrp;	/* back pointer to filegrp */
9087c478bd9Sstevel@tonic-gate 	struct cfs_cid	c_id;		/* unique file number */
9097c478bd9Sstevel@tonic-gate 	int		c_invals;	/* # of recent dir invals */
9107c478bd9Sstevel@tonic-gate 	int		c_usage;	/* Usefulness of cache */
9117c478bd9Sstevel@tonic-gate 	struct vnode	*c_vnode;	/* pointer to vnode */
9127c478bd9Sstevel@tonic-gate 	struct cachefs_metadata	c_metadata;	/* cookie, ... */
9137c478bd9Sstevel@tonic-gate 	int		c_error;
9147c478bd9Sstevel@tonic-gate 	kmutex_t	c_statelock;	/* statelock */
9157c478bd9Sstevel@tonic-gate 	krwlock_t	c_rwlock;	/* serialize write/setattr requests */
9167c478bd9Sstevel@tonic-gate 	kcondvar_t	c_popcv;	/* cnode populate cond var. */
9177c478bd9Sstevel@tonic-gate 	kthread_id_t	c_popthrp;	/* threadp performing pop */
9187c478bd9Sstevel@tonic-gate 	vnode_t		*c_unldvp;	/* dir to unlink in */
9197c478bd9Sstevel@tonic-gate 	char		*c_unlname;	/* name to unlink */
9207c478bd9Sstevel@tonic-gate 	cred_t		*c_unlcred;	/* creds for unlink */
9217c478bd9Sstevel@tonic-gate 	int		c_nio;		/* Number of io's pending */
9227c478bd9Sstevel@tonic-gate 	uint_t		c_ioflags;
9237c478bd9Sstevel@tonic-gate 	kcondvar_t	c_iocv;		/* IO cond var. */
9247c478bd9Sstevel@tonic-gate 	kmutex_t	c_iomutex;
9257c478bd9Sstevel@tonic-gate 	cred_t		*c_cred;
9267c478bd9Sstevel@tonic-gate 	int		c_ipending;	/* 1 if inactive is pending */
9277c478bd9Sstevel@tonic-gate 	int		c_mapcnt;	/* number of mapped blocks */
9287c478bd9Sstevel@tonic-gate 	offset_t	c_apopoffset;	/* offset for async pop */
9297c478bd9Sstevel@tonic-gate 	uint_t		c_apoplen;	/* length for async pop */
9307c478bd9Sstevel@tonic-gate 	u_offset_t	c_modaddr;	/* writepage offset */
9317c478bd9Sstevel@tonic-gate 	int		c_rdcnt;	/* # of read opens for backvp */
9327c478bd9Sstevel@tonic-gate 	int		c_wrcnt;	/* # of write opens for backvp */
9337c478bd9Sstevel@tonic-gate };
9347c478bd9Sstevel@tonic-gate typedef struct cnode cnode_t;
9357c478bd9Sstevel@tonic-gate 
9367c478bd9Sstevel@tonic-gate extern struct kmem_cache *cachefs_cnode_cache;
9377c478bd9Sstevel@tonic-gate 
9387c478bd9Sstevel@tonic-gate /*
9397c478bd9Sstevel@tonic-gate  * Directory caching parameters - First cut...
9407c478bd9Sstevel@tonic-gate  */
9417c478bd9Sstevel@tonic-gate #define	CFS_DIRCACHE_COST	3
9427c478bd9Sstevel@tonic-gate #define	CFS_DIRCACHE_INVAL	3
9437c478bd9Sstevel@tonic-gate #define	CFS_DIRCACHE_ENABLE	(CFS_DIRCACHE_INVAL * CFS_DIRCACHE_COST)
9447c478bd9Sstevel@tonic-gate 
9457c478bd9Sstevel@tonic-gate /*
9467c478bd9Sstevel@tonic-gate  * Conversion macros
9477c478bd9Sstevel@tonic-gate  */
9487c478bd9Sstevel@tonic-gate #define	VTOC(VP)		((struct cnode *)((void *)((VP)->v_data)))
9497c478bd9Sstevel@tonic-gate #define	CTOV(CP)		((CP)->c_vnode)
9507c478bd9Sstevel@tonic-gate #define	VFS_TO_FSCACHE(VFSP)	((struct fscache *)((void *)((VFSP)->vfs_data)))
9517c478bd9Sstevel@tonic-gate #define	C_TO_FSCACHE(CP)	(VFS_TO_FSCACHE(CTOV(CP)->v_vfsp))
9527c478bd9Sstevel@tonic-gate 
9537c478bd9Sstevel@tonic-gate /*
9547c478bd9Sstevel@tonic-gate  * Various flags stored in the flags field of the cnode structure.
9557c478bd9Sstevel@tonic-gate  */
9567c478bd9Sstevel@tonic-gate #define	CN_NOCACHE	0x1		/* no-cache mode */
9577c478bd9Sstevel@tonic-gate #define	CN_DESTROY	0x2		/* destroy when inactive */
9587c478bd9Sstevel@tonic-gate #define	CN_ROOT		0x4		/* root of the file system */
9597c478bd9Sstevel@tonic-gate #define	CN_IDLE		0x8		/* file is idle */
9607c478bd9Sstevel@tonic-gate #define	CN_NEEDOPEN	0x10		/* need to open backvp */
9617c478bd9Sstevel@tonic-gate #define	CN_UPDATED	0x40		/* Metadata was updated - needs sync */
9627c478bd9Sstevel@tonic-gate #define	CDIRTY		0x80
9637c478bd9Sstevel@tonic-gate #define	CN_NEED_FRONT_SYNC	0x100	/* front file needs to be sync'd */
9647c478bd9Sstevel@tonic-gate #define	CN_ALLOC_PENDING	0x200	/* Need to alloc attr cache entry */
9657c478bd9Sstevel@tonic-gate #define	CN_STALE	0x400		/* cnode is stale */
9667c478bd9Sstevel@tonic-gate #define	CN_MODIFIED	0x800		/* Object has been written to */
9677c478bd9Sstevel@tonic-gate #define	CN_POPULATION_PENDING	0x1000	/* Population data needs to be sync'd */
9687c478bd9Sstevel@tonic-gate #define	CN_ASYNC_POPULATE	0x2000	/* async population pending */
9697c478bd9Sstevel@tonic-gate #define	CN_ASYNC_POP_WORKING	0x4000	/* async population in progress */
9707c478bd9Sstevel@tonic-gate #define	CN_PENDRM	0x8000		/* hold off unlink until reconnected */
9717c478bd9Sstevel@tonic-gate #define	CN_MAPWRITE	0x100000	/* mmapped file that is being written */
9727c478bd9Sstevel@tonic-gate #define	CN_CMODINPROG	0x200000	/* writepage() in progress */
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate /*
9757c478bd9Sstevel@tonic-gate  * io flags (in c_ioflag)
9767c478bd9Sstevel@tonic-gate  */
9777c478bd9Sstevel@tonic-gate #define	CIO_PUTPAGES	0x1		/* putpage pending: off==0, len==0 */
9787c478bd9Sstevel@tonic-gate 
9797c478bd9Sstevel@tonic-gate #define	CFS_MAX_THREADS		5
9807c478bd9Sstevel@tonic-gate #define	CFS_ASYNC_TIMEOUT	(60 * hz)
9817c478bd9Sstevel@tonic-gate 
9827c478bd9Sstevel@tonic-gate enum cachefs_cmd {
9837c478bd9Sstevel@tonic-gate 	CFS_INVALID,
9847c478bd9Sstevel@tonic-gate 	CFS_CACHE_SYNC,
9857c478bd9Sstevel@tonic-gate 	CFS_PUTPAGE,
9867c478bd9Sstevel@tonic-gate 	CFS_IDLE,
9877c478bd9Sstevel@tonic-gate 	CFS_POPULATE,
9887c478bd9Sstevel@tonic-gate 	CFS_NOOP
9897c478bd9Sstevel@tonic-gate };
9907c478bd9Sstevel@tonic-gate 
9917c478bd9Sstevel@tonic-gate struct cachefs_fs_sync_req {
9927c478bd9Sstevel@tonic-gate 	struct cachefscache *cf_cachep;
9937c478bd9Sstevel@tonic-gate };
9947c478bd9Sstevel@tonic-gate 
9957c478bd9Sstevel@tonic-gate struct cachefs_idle_req {
9967c478bd9Sstevel@tonic-gate 	vnode_t *ci_vp;
9977c478bd9Sstevel@tonic-gate };
9987c478bd9Sstevel@tonic-gate 
9997c478bd9Sstevel@tonic-gate /*
10007c478bd9Sstevel@tonic-gate  * Large File support the offset in the vnode for putpage request
10017c478bd9Sstevel@tonic-gate  * can now be greater than 2GB.
10027c478bd9Sstevel@tonic-gate  */
10037c478bd9Sstevel@tonic-gate 
10047c478bd9Sstevel@tonic-gate struct cachefs_putpage_req {
10057c478bd9Sstevel@tonic-gate 	vnode_t *cp_vp;
10067c478bd9Sstevel@tonic-gate 	offset_t cp_off;
10077c478bd9Sstevel@tonic-gate 	int cp_len;
10087c478bd9Sstevel@tonic-gate 	int cp_flags;
10097c478bd9Sstevel@tonic-gate };
10107c478bd9Sstevel@tonic-gate 
10117c478bd9Sstevel@tonic-gate /*
10127c478bd9Sstevel@tonic-gate  * Large File support the offset in the vnode for populate request
10137c478bd9Sstevel@tonic-gate  * can now be greater than 2GB.
10147c478bd9Sstevel@tonic-gate  */
10157c478bd9Sstevel@tonic-gate 
10167c478bd9Sstevel@tonic-gate struct cachefs_populate_req {
10177c478bd9Sstevel@tonic-gate 	vnode_t *cpop_vp;
10187c478bd9Sstevel@tonic-gate 	offset_t cpop_off;
10197c478bd9Sstevel@tonic-gate 	size_t cpop_size;
10207c478bd9Sstevel@tonic-gate };
10217c478bd9Sstevel@tonic-gate 
10227c478bd9Sstevel@tonic-gate struct cachefs_req {
10237c478bd9Sstevel@tonic-gate 	struct cachefs_req	*cfs_next;
10247c478bd9Sstevel@tonic-gate 	enum cachefs_cmd	cfs_cmd;	/* Command to execute */
10257c478bd9Sstevel@tonic-gate 	cred_t *cfs_cr;
10267c478bd9Sstevel@tonic-gate 	union {
10277c478bd9Sstevel@tonic-gate 		struct cachefs_fs_sync_req cu_fs_sync;
10287c478bd9Sstevel@tonic-gate 		struct cachefs_idle_req cu_idle;
10297c478bd9Sstevel@tonic-gate 		struct cachefs_putpage_req cu_putpage;
10307c478bd9Sstevel@tonic-gate 		struct cachefs_populate_req cu_populate;
10317c478bd9Sstevel@tonic-gate 	} cfs_req_u;
10327c478bd9Sstevel@tonic-gate 	kmutex_t cfs_req_lock;	/* Protects contents */
10337c478bd9Sstevel@tonic-gate };
10347c478bd9Sstevel@tonic-gate 
10357c478bd9Sstevel@tonic-gate extern struct kmem_cache *cachefs_req_cache;
10367c478bd9Sstevel@tonic-gate 
10377c478bd9Sstevel@tonic-gate /*
10387c478bd9Sstevel@tonic-gate  * Large file support: We allow cachefs to understand the 64 bit inode type.
10397c478bd9Sstevel@tonic-gate  */
10407c478bd9Sstevel@tonic-gate 
10417c478bd9Sstevel@tonic-gate struct cachefs_fid {
10427c478bd9Sstevel@tonic-gate 	ushort_t	cf_len;
10437c478bd9Sstevel@tonic-gate 	ino64_t		cf_fileno;
10447c478bd9Sstevel@tonic-gate 	uint_t		cf_gen;
10457c478bd9Sstevel@tonic-gate };
10467c478bd9Sstevel@tonic-gate #define	CFS_FID_SIZE	(sizeof (struct cachefs_fid) - sizeof (ushort_t))
10477c478bd9Sstevel@tonic-gate 
10487c478bd9Sstevel@tonic-gate /*
10497c478bd9Sstevel@tonic-gate  *
10507c478bd9Sstevel@tonic-gate  * cachefs kstat stuff.  each time you mount a cachefs filesystem, it
10517c478bd9Sstevel@tonic-gate  * gets a unique number.  it'll get that number again if you remount
10527c478bd9Sstevel@tonic-gate  * the same thing.  the number is unique until reboot, but it doesn't
10537c478bd9Sstevel@tonic-gate  * survive reboots.
10547c478bd9Sstevel@tonic-gate  *
10557c478bd9Sstevel@tonic-gate  * each cachefs kstat uses this per-filesystem identifier.  to get the
10567c478bd9Sstevel@tonic-gate  * valid identifiers, the `cachefs.0.key' kstat has a mapping of all
10577c478bd9Sstevel@tonic-gate  * the available filesystems.  its structure, cachefs_kstat_key, is
10587c478bd9Sstevel@tonic-gate  * below.
10597c478bd9Sstevel@tonic-gate  *
10607c478bd9Sstevel@tonic-gate  */
10617c478bd9Sstevel@tonic-gate 
10627c478bd9Sstevel@tonic-gate typedef struct cachefs_kstat_key {
10637c478bd9Sstevel@tonic-gate 	int ks_id;
10647c478bd9Sstevel@tonic-gate 	int ks_mounted;
10657c478bd9Sstevel@tonic-gate 	uint64_t ks_vfsp;
10667c478bd9Sstevel@tonic-gate 	uint64_t ks_mountpoint;
10677c478bd9Sstevel@tonic-gate 	uint64_t ks_backfs;
10687c478bd9Sstevel@tonic-gate 	uint64_t ks_cachedir;
10697c478bd9Sstevel@tonic-gate 	uint64_t ks_cacheid;
10707c478bd9Sstevel@tonic-gate } cachefs_kstat_key_t;
10717c478bd9Sstevel@tonic-gate extern cachefs_kstat_key_t *cachefs_kstat_key;
10727c478bd9Sstevel@tonic-gate extern int cachefs_kstat_key_n;
10737c478bd9Sstevel@tonic-gate 
10747c478bd9Sstevel@tonic-gate /*
10757c478bd9Sstevel@tonic-gate  * cachefs debugging aid.  cachefs_debug_info_t is a cookie that we
10767c478bd9Sstevel@tonic-gate  * can keep around to see what was happening at a certain time.
10777c478bd9Sstevel@tonic-gate  *
10787c478bd9Sstevel@tonic-gate  * for example, if we have a deadlock on the cnode's statelock
10797c478bd9Sstevel@tonic-gate  * (i.e. someone is not letting go of it), we can add a
10807c478bd9Sstevel@tonic-gate  * cachefs_debug_info_t * to the cnode structure, and call
10817c478bd9Sstevel@tonic-gate  * cachefs_debug_save() whenever we grab the lock.  then, when we're
10827c478bd9Sstevel@tonic-gate  * deadlocked, we can see what was going on when we grabbed the lock
10837c478bd9Sstevel@tonic-gate  * in the first place, and (hopefully) why we didn't release it.
10847c478bd9Sstevel@tonic-gate  */
10857c478bd9Sstevel@tonic-gate 
10867c478bd9Sstevel@tonic-gate #define	CACHEFS_DEBUG_DEPTH		(16)
10877c478bd9Sstevel@tonic-gate typedef struct cachefs_debug_info {
10887c478bd9Sstevel@tonic-gate 	char		*cdb_message;	/* arbitrary message */
10897c478bd9Sstevel@tonic-gate 	uint_t		cdb_flags;	/* arbitrary flags */
10907c478bd9Sstevel@tonic-gate 	int		cdb_int;	/* arbitrary int */
10917c478bd9Sstevel@tonic-gate 	void		*cdb_pointer;	/* arbitrary pointer */
10927c478bd9Sstevel@tonic-gate 	uint_t		cdb_count;	/* how many times called */
10937c478bd9Sstevel@tonic-gate 
10947c478bd9Sstevel@tonic-gate 	cachefscache_t	*cdb_cachep;	/* relevant cachep (maybe undefined) */
10957c478bd9Sstevel@tonic-gate 	struct fscache	*cdb_fscp;	/* relevant fscache */
10967c478bd9Sstevel@tonic-gate 	struct cnode	*cdb_cnode;	/* relevant cnode */
10977c478bd9Sstevel@tonic-gate 	vnode_t		*cdb_frontvp;	/* relevant front vnode */
10987c478bd9Sstevel@tonic-gate 	vnode_t		*cdb_backvp;	/* relevant back vnode */
10997c478bd9Sstevel@tonic-gate 
11007c478bd9Sstevel@tonic-gate 	kthread_id_t	cdb_thread;	/* thread who called */
11017c478bd9Sstevel@tonic-gate 	hrtime_t	cdb_timestamp;	/* when */
11027c478bd9Sstevel@tonic-gate 	int		cdb_depth;	/* depth of saved stack */
11037c478bd9Sstevel@tonic-gate 	pc_t		cdb_stack[CACHEFS_DEBUG_DEPTH]; /* stack trace */
11047c478bd9Sstevel@tonic-gate 	struct cachefs_debug_info *cdb_next; /* pointer to next */
11057c478bd9Sstevel@tonic-gate } cachefs_debug_info_t;
11067c478bd9Sstevel@tonic-gate 
11077c478bd9Sstevel@tonic-gate /*
11087c478bd9Sstevel@tonic-gate  * cachefs function prototypes
11097c478bd9Sstevel@tonic-gate  */
1110*ba3594baSGarrett D'Amore #if defined(_KERNEL)
11117c478bd9Sstevel@tonic-gate extern int cachefs_getcookie(vnode_t *, struct fid *, struct vattr *,
11127c478bd9Sstevel@tonic-gate 		cred_t *, uint32_t);
11137c478bd9Sstevel@tonic-gate cachefscache_t *cachefs_cache_create(void);
11147c478bd9Sstevel@tonic-gate void cachefs_cache_destroy(cachefscache_t *cachep);
11157c478bd9Sstevel@tonic-gate int cachefs_cache_activate_ro(cachefscache_t *cachep, vnode_t *cdvp);
11167c478bd9Sstevel@tonic-gate void cachefs_cache_activate_rw(cachefscache_t *cachep);
11177c478bd9Sstevel@tonic-gate void cachefs_cache_dirty(struct cachefscache *cachep, int lockit);
11187c478bd9Sstevel@tonic-gate int cachefs_cache_rssync(struct cachefscache *cachep);
11197c478bd9Sstevel@tonic-gate void cachefs_cache_sync(struct cachefscache *cachep);
11207c478bd9Sstevel@tonic-gate uint_t cachefs_cache_unique(cachefscache_t *cachep);
11217c478bd9Sstevel@tonic-gate void cachefs_do_req(struct cachefs_req *);
11227c478bd9Sstevel@tonic-gate 
11237c478bd9Sstevel@tonic-gate /* cachefs_cnode.c */
11247c478bd9Sstevel@tonic-gate void cachefs_cnode_idle(struct vnode *vp, cred_t *cr);
11257c478bd9Sstevel@tonic-gate void cachefs_cnode_idleclean(fscache_t *fscp, int unmount);
11267c478bd9Sstevel@tonic-gate int cachefs_cnode_inactive(register struct vnode *vp, cred_t *cr);
11277c478bd9Sstevel@tonic-gate void cachefs_cnode_listadd(struct cnode *cp);
11287c478bd9Sstevel@tonic-gate void cachefs_cnode_listrem(struct cnode *cp);
11297c478bd9Sstevel@tonic-gate void cachefs_cnode_free(struct cnode *cp);
11307c478bd9Sstevel@tonic-gate void cachefs_cnode_cleanfreelist();
11317c478bd9Sstevel@tonic-gate void cachefs_cnode_idleadd(struct cnode *cp);
11327c478bd9Sstevel@tonic-gate void cachefs_cnode_idlerem(struct cnode *cp);
11337c478bd9Sstevel@tonic-gate int cachefs_cnode_find(filegrp_t *fgp, cfs_cid_t *cidp, fid_t *cookiep,
11347c478bd9Sstevel@tonic-gate     struct cnode **cpp, struct vnode *vp, vattr_t *vap);
11357c478bd9Sstevel@tonic-gate int cachefs_cnode_make(cfs_cid_t *cidp, fscache_t *fscp, fid_t *cookiep,
11367c478bd9Sstevel@tonic-gate     vattr_t *vap, vnode_t *backvp, cred_t *cr, int flag, cnode_t **cpp);
11377c478bd9Sstevel@tonic-gate int cachefs_cid_inuse(filegrp_t *fgp, cfs_cid_t *cidp);
11387c478bd9Sstevel@tonic-gate int cachefs_fileno_inuse(fscache_t *fscp, ino64_t fileno);
11397c478bd9Sstevel@tonic-gate int cachefs_cnode_create(fscache_t *fscp, vattr_t *vap, int flag,
11407c478bd9Sstevel@tonic-gate     cnode_t **cpp);
11417c478bd9Sstevel@tonic-gate void cachefs_cnode_move(cnode_t *cp);
11427c478bd9Sstevel@tonic-gate int cachefs_cnode_lostfound(cnode_t *cp, char *rname);
11437c478bd9Sstevel@tonic-gate void cachefs_cnode_sync(cnode_t *cp);
11447c478bd9Sstevel@tonic-gate void cachefs_cnode_traverse(fscache_t *fscp, void (*routinep)(cnode_t *));
11457c478bd9Sstevel@tonic-gate void cachefs_cnode_stale(cnode_t *cp);
11467c478bd9Sstevel@tonic-gate void cachefs_cnode_setlocalstats(cnode_t *cp);
11477c478bd9Sstevel@tonic-gate void cachefs_cnode_disable_caching(cnode_t *cp);
11487c478bd9Sstevel@tonic-gate 
11497c478bd9Sstevel@tonic-gate void cachefs_enable_caching(struct fscache *);
11507c478bd9Sstevel@tonic-gate 
11517c478bd9Sstevel@tonic-gate /* cachefs_fscache.c */
11527c478bd9Sstevel@tonic-gate void fscache_destroy(fscache_t *);
11537c478bd9Sstevel@tonic-gate 
11547c478bd9Sstevel@tonic-gate /* cachefs_ioctl.h */
11557c478bd9Sstevel@tonic-gate int cachefs_pack_common(vnode_t *vp, cred_t *cr);
11567c478bd9Sstevel@tonic-gate void cachefs_inum_register(fscache_t *fscp, ino64_t real, ino64_t fake);
11577c478bd9Sstevel@tonic-gate ino64_t cachefs_inum_real2fake(fscache_t *fscp, ino64_t real);
11587c478bd9Sstevel@tonic-gate 
11597c478bd9Sstevel@tonic-gate 
11607c478bd9Sstevel@tonic-gate /* cachefs_subr.c */
11617c478bd9Sstevel@tonic-gate int cachefs_sync_metadata(cnode_t *);
11627c478bd9Sstevel@tonic-gate int cachefs_cnode_cnt(int);
11637c478bd9Sstevel@tonic-gate int cachefs_getbackvp(struct fscache *, struct cnode *);
11647c478bd9Sstevel@tonic-gate int cachefs_getfrontfile(cnode_t *);
11657c478bd9Sstevel@tonic-gate void cachefs_removefrontfile(cachefs_metadata_t *mdp, cfs_cid_t *cidp,
11667c478bd9Sstevel@tonic-gate     filegrp_t *fgp);
11677c478bd9Sstevel@tonic-gate void cachefs_nocache(cnode_t *);
11687c478bd9Sstevel@tonic-gate void cachefs_inval_object(cnode_t *);
11697c478bd9Sstevel@tonic-gate void make_ascii_name(cfs_cid_t *cidp, char *strp);
11707c478bd9Sstevel@tonic-gate int cachefs_async_halt(struct cachefs_workq *, int);
11717c478bd9Sstevel@tonic-gate int cachefs_async_okay(void);
11727c478bd9Sstevel@tonic-gate int cachefs_check_allocmap(cnode_t *cp, u_offset_t off);
11737c478bd9Sstevel@tonic-gate void cachefs_update_allocmap(cnode_t *, u_offset_t, size_t);
11747c478bd9Sstevel@tonic-gate int cachefs_cachesymlink(struct cnode *cp, cred_t *cr);
11757c478bd9Sstevel@tonic-gate int cachefs_stuffsymlink(cnode_t *cp, caddr_t buf, int buflen);
11767c478bd9Sstevel@tonic-gate int cachefs_readlink_back(cnode_t *cp, cred_t *cr, caddr_t *bufp, int *buflenp);
11777c478bd9Sstevel@tonic-gate /*
11787c478bd9Sstevel@tonic-gate  * void cachefs_cluster_allocmap(struct cnode *, u_offset_t, u_offset_t *,
11797c478bd9Sstevel@tonic-gate  *	size_t *, size_t);
11807c478bd9Sstevel@tonic-gate  */
11817c478bd9Sstevel@tonic-gate void cachefs_cluster_allocmap(u_offset_t, u_offset_t *, size_t *, size_t,
11827c478bd9Sstevel@tonic-gate 		struct cnode *);
11837c478bd9Sstevel@tonic-gate int cachefs_populate(cnode_t *, u_offset_t, size_t, vnode_t *, vnode_t *,
11847c478bd9Sstevel@tonic-gate 	u_offset_t, cred_t *);
11857c478bd9Sstevel@tonic-gate int cachefs_stats_kstat_snapshot(kstat_t *, void *, int);
11867c478bd9Sstevel@tonic-gate cachefs_debug_info_t *cachefs_debug_save(cachefs_debug_info_t *, int,
11877c478bd9Sstevel@tonic-gate     char *, uint_t, int, void *, cachefscache_t *, struct fscache *,
11887c478bd9Sstevel@tonic-gate     struct cnode *);
11897c478bd9Sstevel@tonic-gate void cachefs_debug_show(cachefs_debug_info_t *);
11907c478bd9Sstevel@tonic-gate uint32_t cachefs_cred_checksum(cred_t *cr);
11917c478bd9Sstevel@tonic-gate int cachefs_frontfile_size(cnode_t *cp, u_offset_t length);
11927c478bd9Sstevel@tonic-gate int cachefs_req_create(void *, void *, int);
11937c478bd9Sstevel@tonic-gate void cachefs_req_destroy(void *, void *);
11947c478bd9Sstevel@tonic-gate int cachefs_stop_cache(cnode_t *);
11957c478bd9Sstevel@tonic-gate 
11967c478bd9Sstevel@tonic-gate 
11977c478bd9Sstevel@tonic-gate /* cachefs_resource.c */
11987c478bd9Sstevel@tonic-gate void cachefs_rlent_moveto_nolock(cachefscache_t *cachep,
11997c478bd9Sstevel@tonic-gate     enum cachefs_rl_type type, uint_t entno, size_t);
12007c478bd9Sstevel@tonic-gate void cachefs_rlent_moveto(cachefscache_t *, enum cachefs_rl_type, uint_t,
12017c478bd9Sstevel@tonic-gate     size_t);
12027c478bd9Sstevel@tonic-gate void cachefs_rlent_verify(cachefscache_t *, enum cachefs_rl_type, uint_t);
12037c478bd9Sstevel@tonic-gate void cachefs_rl_changefileno(cachefscache_t *cachep, uint_t entno,
12047c478bd9Sstevel@tonic-gate 	ino64_t fileno);
12057c478bd9Sstevel@tonic-gate int cachefs_rlent_data(cachefscache_t *cachep, rl_entry_t *valp,
12067c478bd9Sstevel@tonic-gate     uint_t *entnop);
12077c478bd9Sstevel@tonic-gate void cachefs_move_modified_to_mf(cachefscache_t *cachep, fscache_t *fscp);
12087c478bd9Sstevel@tonic-gate int cachefs_allocblocks(cachefscache_t *, size_t, enum cachefs_rl_type);
12097c478bd9Sstevel@tonic-gate void cachefs_freeblocks(cachefscache_t *, size_t, enum cachefs_rl_type);
12107c478bd9Sstevel@tonic-gate void cachefs_freefile(cachefscache_t *);
12117c478bd9Sstevel@tonic-gate int cachefs_allocfile(cachefscache_t *);
12127c478bd9Sstevel@tonic-gate int cachefs_rl_alloc(struct cachefscache *cachep, rl_entry_t *valp,
12137c478bd9Sstevel@tonic-gate     uint_t *entnop);
12147c478bd9Sstevel@tonic-gate int cachefs_rl_attrc(struct cachefscache *, int, int);
12157c478bd9Sstevel@tonic-gate void cachefs_cachep_worker_thread(cachefscache_t *);
12167c478bd9Sstevel@tonic-gate void cachefs_rl_cleanup(cachefscache_t *);
12177c478bd9Sstevel@tonic-gate int cachefs_rl_entry_get(cachefscache_t *, uint_t, rl_entry_t **);
12187c478bd9Sstevel@tonic-gate #ifdef CFSRLDEBUG
12197c478bd9Sstevel@tonic-gate void cachefs_rl_debug_save(rl_entry_t *);
12207c478bd9Sstevel@tonic-gate void cachefs_rl_debug_show(rl_entry_t *);
12217c478bd9Sstevel@tonic-gate void cachefs_rl_debug_destroy(rl_entry_t *);
12227c478bd9Sstevel@tonic-gate #endif /* CFSRLDEBUG */
12237c478bd9Sstevel@tonic-gate 
12247c478bd9Sstevel@tonic-gate /* cachefs_log.c */
12257c478bd9Sstevel@tonic-gate int cachefs_log_kstat_snapshot(kstat_t *, void *, int);
12267c478bd9Sstevel@tonic-gate void cachefs_log_process_queue(cachefscache_t *, int);
12277c478bd9Sstevel@tonic-gate int cachefs_log_logfile_open(cachefscache_t *, char *);
12287c478bd9Sstevel@tonic-gate struct cachefs_log_cookie
12297c478bd9Sstevel@tonic-gate 	*cachefs_log_create_cookie(struct cachefs_log_control *);
12307c478bd9Sstevel@tonic-gate void cachefs_log_error(cachefscache_t *, int, int);
12317c478bd9Sstevel@tonic-gate void cachefs_log_destroy_cookie(struct cachefs_log_cookie *);
12327c478bd9Sstevel@tonic-gate 
12337c478bd9Sstevel@tonic-gate void cachefs_log_mount(cachefscache_t *, int, struct vfs *,
12347c478bd9Sstevel@tonic-gate     fscache_t *, char *, enum uio_seg, char *);
12357c478bd9Sstevel@tonic-gate void cachefs_log_umount(cachefscache_t *, int, struct vfs *);
12367c478bd9Sstevel@tonic-gate void cachefs_log_getpage(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12377c478bd9Sstevel@tonic-gate     uid_t, u_offset_t, size_t);
12387c478bd9Sstevel@tonic-gate void cachefs_log_readdir(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12397c478bd9Sstevel@tonic-gate     uid_t, u_offset_t, int);
12407c478bd9Sstevel@tonic-gate void cachefs_log_readlink(cachefscache_t *, int, struct vfs *,
12417c478bd9Sstevel@tonic-gate     fid_t *, ino64_t, uid_t, size_t);
12427c478bd9Sstevel@tonic-gate void cachefs_log_remove(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12437c478bd9Sstevel@tonic-gate     uid_t);
12447c478bd9Sstevel@tonic-gate void cachefs_log_rmdir(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12457c478bd9Sstevel@tonic-gate     uid_t);
12467c478bd9Sstevel@tonic-gate void cachefs_log_truncate(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12477c478bd9Sstevel@tonic-gate     uid_t, u_offset_t);
12487c478bd9Sstevel@tonic-gate void cachefs_log_putpage(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12497c478bd9Sstevel@tonic-gate     uid_t, u_offset_t, size_t);
12507c478bd9Sstevel@tonic-gate void cachefs_log_create(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12517c478bd9Sstevel@tonic-gate     uid_t);
12527c478bd9Sstevel@tonic-gate void cachefs_log_mkdir(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12537c478bd9Sstevel@tonic-gate     uid_t);
12547c478bd9Sstevel@tonic-gate void cachefs_log_rename(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12557c478bd9Sstevel@tonic-gate     int, uid_t);
12567c478bd9Sstevel@tonic-gate void cachefs_log_symlink(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12577c478bd9Sstevel@tonic-gate     uid_t, int);
12587c478bd9Sstevel@tonic-gate void cachefs_log_populate(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12597c478bd9Sstevel@tonic-gate     u_offset_t, size_t);
12607c478bd9Sstevel@tonic-gate void cachefs_log_csymlink(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12617c478bd9Sstevel@tonic-gate     int);
12627c478bd9Sstevel@tonic-gate void cachefs_log_filldir(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12637c478bd9Sstevel@tonic-gate     u_offset_t);
12647c478bd9Sstevel@tonic-gate void cachefs_log_mdcreate(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12657c478bd9Sstevel@tonic-gate     uint_t);
12667c478bd9Sstevel@tonic-gate void cachefs_log_gpfront(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12677c478bd9Sstevel@tonic-gate     uid_t, u_offset_t, uint_t);
12687c478bd9Sstevel@tonic-gate void cachefs_log_rfdir(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12697c478bd9Sstevel@tonic-gate     uid_t);
12707c478bd9Sstevel@tonic-gate void cachefs_log_ualloc(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12717c478bd9Sstevel@tonic-gate     u_offset_t, size_t);
12727c478bd9Sstevel@tonic-gate void cachefs_log_calloc(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
12737c478bd9Sstevel@tonic-gate     u_offset_t, size_t);
12747c478bd9Sstevel@tonic-gate void cachefs_log_nocache(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t);
12757c478bd9Sstevel@tonic-gate 
12767c478bd9Sstevel@tonic-gate /* cachefs_vnops.c */
12777c478bd9Sstevel@tonic-gate struct vnodeops *cachefs_getvnodeops(void);
12787c478bd9Sstevel@tonic-gate int cachefs_lookup_common(vnode_t *dvp, char *nm, vnode_t **vpp,
12797c478bd9Sstevel@tonic-gate     struct pathname *pnp, int flags, vnode_t *rdir, cred_t *cr);
12807c478bd9Sstevel@tonic-gate int cachefs_putpage_common(struct vnode *vp, offset_t off,
12817c478bd9Sstevel@tonic-gate     size_t len, int flags, cred_t *cr);
12827c478bd9Sstevel@tonic-gate ino64_t cachefs_fileno_conflict(fscache_t *fscp, ino64_t old);
12837c478bd9Sstevel@tonic-gate int cachefs_remove_connected(vnode_t *dvp, char *nm, cred_t *cr,
12847c478bd9Sstevel@tonic-gate     vnode_t *vp);
12857c478bd9Sstevel@tonic-gate int cachefs_remove_disconnected(vnode_t *dvp, char *nm, cred_t *cr,
12867c478bd9Sstevel@tonic-gate     vnode_t *vp);
12877c478bd9Sstevel@tonic-gate int cachefs_cacheacl(cnode_t *, vsecattr_t *);
12887c478bd9Sstevel@tonic-gate void cachefs_purgeacl(cnode_t *);
12897c478bd9Sstevel@tonic-gate int cachefs_vtype_aclok(vnode_t *);
12907c478bd9Sstevel@tonic-gate 
12917c478bd9Sstevel@tonic-gate /* cachefs_vfsops.c */
12927c478bd9Sstevel@tonic-gate int cachefs_init_vfsops(int);
12937c478bd9Sstevel@tonic-gate int cachefs_init_vnops(char *);
12947c478bd9Sstevel@tonic-gate void cachefs_kstat_mount(struct fscache *, char *, char *, char *, char *);
12957c478bd9Sstevel@tonic-gate void cachefs_kstat_umount(int);
12967c478bd9Sstevel@tonic-gate int cachefs_kstat_key_update(kstat_t *, int);
12977c478bd9Sstevel@tonic-gate int cachefs_kstat_key_snapshot(kstat_t *, void *, int);
12987c478bd9Sstevel@tonic-gate 
12997c478bd9Sstevel@tonic-gate extern void cachefs_workq_init(struct cachefs_workq *);
13007c478bd9Sstevel@tonic-gate extern void cachefs_addqueue(struct cachefs_req *, struct cachefs_workq *);
13017c478bd9Sstevel@tonic-gate 
13027c478bd9Sstevel@tonic-gate 
13037c478bd9Sstevel@tonic-gate extern void *cachefs_kmem_alloc(size_t, int);
13047c478bd9Sstevel@tonic-gate extern void *cachefs_kmem_zalloc(size_t, int);
13057c478bd9Sstevel@tonic-gate extern void cachefs_kmem_free(void *, size_t);
13067c478bd9Sstevel@tonic-gate extern char *cachefs_strdup(char *);
13077c478bd9Sstevel@tonic-gate 
1308*ba3594baSGarrett D'Amore #endif /* defined (_KERNEL) */
13097c478bd9Sstevel@tonic-gate 
13107c478bd9Sstevel@tonic-gate 
13117c478bd9Sstevel@tonic-gate 
13127c478bd9Sstevel@tonic-gate #define	C_RL_MAXENTS	0x4000		/* Whatever */
13137c478bd9Sstevel@tonic-gate 
13147c478bd9Sstevel@tonic-gate /*
13157c478bd9Sstevel@tonic-gate  * ioctls.
13167c478bd9Sstevel@tonic-gate  */
13177c478bd9Sstevel@tonic-gate #include <sys/ioccom.h>
13187c478bd9Sstevel@tonic-gate #define	_FIOCOD		_IO('f', 78)		/* consistency on demand */
13197c478bd9Sstevel@tonic-gate #define	_FIOSTOPCACHE	_IO('f', 86)		/* stop using cache */
13207c478bd9Sstevel@tonic-gate 
13217c478bd9Sstevel@tonic-gate #define	CACHEFSIO_PACK		_IO('f', 81)
13227c478bd9Sstevel@tonic-gate #define	CACHEFSIO_UNPACK	_IO('f', 82)
13237c478bd9Sstevel@tonic-gate #define	CACHEFSIO_UNPACKALL	_IO('f', 83)
13247c478bd9Sstevel@tonic-gate #define	CACHEFSIO_PACKINFO	_IO('f', 84)
13257c478bd9Sstevel@tonic-gate #define	CACHEFSIO_DCMD		_IO('f', 85)
13267c478bd9Sstevel@tonic-gate 
13277c478bd9Sstevel@tonic-gate #ifdef __cplusplus
13287c478bd9Sstevel@tonic-gate }
13297c478bd9Sstevel@tonic-gate #endif
13307c478bd9Sstevel@tonic-gate 
13317c478bd9Sstevel@tonic-gate #endif /* _SYS_FS_CACHEFS_FS_H */
1332