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