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