summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/fs/ufs_log.h
blob: d71aff1d1e0d3a7585425ee8cb225abe4f6623cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _SYS_FS_UFS_LOG_H
#define	_SYS_FS_UFS_LOG_H

#include <sys/buf.h>
#include <sys/fs/ufs_trans.h>
#include <sys/fs/ufs_filio.h>
#include <sys/fs/ufs_inode.h>

#ifdef	__cplusplus
extern "C" {
#endif

typedef struct lufs_save {
	buf_t		*sv_bp;
	size_t		sv_nb_left;
	int		sv_error;
} lufs_save_t;

typedef struct lufs_buf {
	buf_t		lb_buf;
	void		*lb_ptr;
} lufs_buf_t;

/*
 * Log space is stored as extents
 */
#define	LUFS_EXTENTS	(UINT32_C(0))
#define	LS_SECTORS	2

typedef struct extent {
	uint32_t	lbno;	/* Logical block # within the space */
	uint32_t	pbno;	/* Physical block number of extent. */
				/* in disk blocks for non-MTB ufs */
				/* in frags for MTB ufs */
	uint32_t	nbno;	/* # blocks in this extent */
} extent_t;

typedef struct ic_extent {
	uint32_t	ic_lbno;	/* Logical block # within the space */
	uint32_t	ic_nbno;	/* # blocks in this extent */
	daddr_t		ic_pbno;	/* Physical block number of extent. */
					/* (always in disk blocks) 	*/
} ic_extent_t;

typedef struct extent_block {
	uint32_t	type;		/* Set to LUFS_EXTENTS to identify */
					/*   structure on disk. */
	int32_t		chksum;		/* Checksum over entire block. */
	uint32_t	nextents;	/* Size of extents array. */
	uint32_t	nbytes;		/* # bytes mapped by extent_block. */
	uint32_t	nextbno;	/* blkno of next extent_block. */
	extent_t	extents[1];
} extent_block_t;

typedef struct ic_extent_block {
	uint32_t	ic_nextents;	/* Size of extents array. */
	uint32_t	ic_nbytes;	/* # bytes mapped by extent_block. */
	uint32_t	ic_nextbno;	/* blkno of next extent_block. */
	ic_extent_t	ic_extents[1];
} ic_extent_block_t;

/*
 * Don't size the incore buffers too small or too large
 */
#define	LDL_MINTRANSFER		(UINT32_C(32768))	/* 32 k */
#define	LDL_MAXTRANSFER		(UINT32_C(1048576))	/* 1 M */

/*
 * LDL_DIVISOR (ldl_divisor) is the number to calculate the log size
 * from the file system size according to the calculation in lufs_enable()
 */
#define	LDL_DIVISOR		1024 /* 1024 gives 1MB per 1GB */

/*
 * This gives the maximum size of log for which the 1MB per 1GB rule
 * applies. The size of the log will only be greater than this based
 * on the cylinder group space requirements.
 */
#define	LDL_SOFTLOGCAP		(256 * 1024 * 1024)

/*
 * But set reasonable min/max units
 */
#define	LDL_MINLOGSIZE		(1024 * 1024)
#define	LDL_MAXLOGSIZE		(512 * 1024 * 1024)

/*
 * Log space requirement per cylinder group. This needs to accommodate a
 * cg delta (inc. header) and have a factor to cover other deltas involved
 * in a single transaction which could touch all cyl groups in a file system.
 */
#define	LDL_CGSIZEREQ(fs) \
	((fs)->fs_cgsize + ((fs)->fs_cgsize >> 1))

#define	LDL_MINBUFSIZE		(32 * 1024)
#define	LDL_USABLE_BSIZE	(DEV_BSIZE - sizeof (sect_trailer_t))
#define	NB_LEFT_IN_SECTOR(off) 	(LDL_USABLE_BSIZE - ((off) - dbtob(btodb(off))))

typedef struct cirbuf {
	buf_t		*cb_bp;		/* buf's with space in circular buf */
	buf_t		*cb_dirty;	/* filling this buffer for log write */
	buf_t		*cb_free;	/* free bufs list */
	caddr_t		cb_va;		/* address of circular buffer */
	size_t		cb_nb;		/* size of circular buffer */
	krwlock_t	cb_rwlock;	/* r/w lock to protect list mgmt. */
} cirbuf_t;

#define	LUFS_VERSION		(UINT32_C(1))	/* Version 1 */
#define	LUFS_VERSION_LATEST	LUFS_VERSION

/*
 * The old Disksuite unit structure has been split into two parts -- the
 * incore part which is created at run time and the ondisk structure.  To
 * minimize code changes, the incore structure retains the old name,
 * ml_unit_t and the ondisk structure is called ml_odunit_t.  The ondisk
 * structure is stored at the beginning of the log.
 *
 * This structure must fit into a sector (512b)
 *
 */
typedef struct ml_odunit {
	uint32_t	od_version;	/* version number */
	uint32_t	od_badlog;	/* is the log okay? */
	uint32_t	od_unused1;

	/*
	 * Important constants
	 */
	uint32_t	od_maxtransfer;	/* max transfer in bytes */
	uint32_t	od_devbsize;	/* device bsize */
	int32_t		od_bol_lof;	/* byte offset to begin of log */
	int32_t		od_eol_lof;	/* byte offset to end of log */

	/*
	 * The disk space is split into state and circular log
	 */
	uint32_t	od_requestsize;	/* size requested by user */
	uint32_t	od_statesize;	/* size of state area in bytes */
	uint32_t	od_logsize;	/* size of log area in bytes */
	int32_t		od_statebno;	/* first block of state area */
	int32_t		od_unused2;

	/*
	 * Head and tail of log
	 */
	int32_t		od_head_lof;	/* byte offset of head */
	uint32_t	od_head_ident;	/* head sector id # */
	int32_t		od_tail_lof;	/* byte offset of tail */
	uint32_t	od_tail_ident;	/* tail sector id # */
	uint32_t	od_chksum;	/* checksum to verify ondisk contents */

	/*
	 * Used for error recovery
	 */
	uint32_t	od_head_tid;	/* used for logscan; set at sethead */

	/*
	 * Debug bits
	 */
	int32_t		od_debug;

	/*
	 * Misc
	 */
	struct timeval	od_timestamp;	/* time of last state change */
} ml_odunit_t;

typedef struct ml_unit {
	struct ml_unit	*un_next;	/* next incore log */
	int		un_flags;	/* Incore state */
	buf_t		*un_bp;		/* contains memory for un_ondisk */
	struct ufsvfs	*un_ufsvfs;	/* backpointer to ufsvfs */
	dev_t		un_dev;		/* for convenience */
	ic_extent_block_t *un_ebp;	/* block of extents */
	size_t		un_nbeb;	/* # bytes used by *un_ebp */
	struct mt_map	*un_deltamap;	/* deltamap */
	struct mt_map	*un_logmap;	/* logmap includes moby trans stuff */
	struct mt_map	*un_matamap;	/* optional - matamap */

	/*
	 * Used for managing transactions
	 */
	uint32_t	un_maxresv;	/* maximum reservable space */
	uint32_t	un_resv;	/* reserved byte count for this trans */
	uint32_t	un_resv_wantin;	/* reserved byte count for next trans */

	/*
	 * Used during logscan
	 */
	uint32_t	un_tid;

	/*
	 * Read/Write Buffers
	 */
	cirbuf_t	un_rdbuf;	/* read buffer space */
	cirbuf_t	un_wrbuf;	/* write buffer space */

	/*
	 * Ondisk state
	 */
	ml_odunit_t	un_ondisk;	/* ondisk log information */

	/*
	 * locks
	 */
	kmutex_t	un_log_mutex;	/* allows one log write at a time */
	kmutex_t	un_state_mutex;	/* only 1 state update at a time */
} ml_unit_t;

/*
 * Macros to allow access to the ondisk elements via the ml_unit_t incore
 * structure.
 */

#define	un_version	un_ondisk.od_version
#define	un_badlog	un_ondisk.od_badlog
#define	un_maxtransfer	un_ondisk.od_maxtransfer
#define	un_devbsize	un_ondisk.od_devbsize
#define	un_bol_lof	un_ondisk.od_bol_lof
#define	un_eol_lof	un_ondisk.od_eol_lof
#define	un_statesize	un_ondisk.od_statesize
#define	un_logsize	un_ondisk.od_logsize
#define	un_statebno	un_ondisk.od_statebno
#define	un_requestsize	un_ondisk.od_requestsize
#define	un_head_lof	un_ondisk.od_head_lof
#define	un_head_ident	un_ondisk.od_head_ident
#define	un_tail_lof	un_ondisk.od_tail_lof
#define	un_tail_ident	un_ondisk.od_tail_ident
#define	un_chksum	un_ondisk.od_chksum
#define	un_head_tid	un_ondisk.od_head_tid
#define	un_debug	un_ondisk.od_debug
#define	un_timestamp	un_ondisk.od_timestamp

/*
 *	un_flags
 */
#define	LDL_SCAN	0x0001	/* log scan in progress */
#define	LDL_ERROR	0x0002	/* in error state */
#define	LDL_NOROLL	0x0004  /* Log Not Yet Rollable */

typedef struct sect_trailer {
	uint32_t	st_tid;		/* transaction id */
	uint32_t	st_ident;	/* unique sector id */
} sect_trailer_t;

/*
 * map block
 */
#define	MAPBLOCKSIZE	(8192)
#define	MAPBLOCKSHIFT	(13)
#define	MAPBLOCKOFF	(MAPBLOCKSIZE-1)
#define	MAPBLOCKMASK	(~MAPBLOCKOFF)
#define	DEV_BMASK	(DEV_BSIZE - 1)

/*
 * cached roll buffer
 */
typedef struct crb {
	int64_t		c_mof;		/* master file offset of buffer */
	caddr_t		c_buf;		/* pointer to cached roll buffer */
	uint32_t	c_nb;		/* size of buffer */
	ushort_t	c_refcnt;	/* reference count on crb */
	uchar_t		c_invalid;	/* crb should not be used */
} crb_t;

#define	CRB_END ((crb_t *)1) /* must be non zero */

/*
 * delta header
 */
struct delta {
	int64_t		d_mof;	/* byte offset on device to start writing */
				/*   delta */
	int32_t		d_nb;	/* # bytes in the delta */
	delta_t 	d_typ;	/* Type of delta.  Defined in ufs_trans.h */
};
/*
 * common map entry
 */
typedef struct mapentry	mapentry_t;
struct mapentry {
	/*
	 * doubly linked list of all mapentries in map -- MUST BE FIRST
	 */
	mapentry_t	*me_next;
	mapentry_t	*me_prev;

	mapentry_t	*me_hash;
	mapentry_t	*me_agenext;
	mapentry_t	*me_cancel;
	crb_t		*me_crb;
	int		(*me_func)();
	ulong_t		me_arg;
	ulong_t		me_age;
	struct delta	me_delta;
	uint32_t	me_tid;
	off_t		me_lof;
	ushort_t	me_flags;
};

#define	me_mof	me_delta.d_mof
#define	me_nb	me_delta.d_nb
#define	me_dt	me_delta.d_typ

/*
 * me_flags
 */
#define	ME_SCAN		(0x0001)	/* entry from log scan */
#define	ME_HASH		(0x0002)	/* on hash   list */
#define	ME_CANCEL	(0x0004)	/* on cancel list */
#define	ME_AGE		(0x0008)	/* on age    list */
#define	ME_LIST		(0x0010)	/* on list   list */
#define	ME_ROLL		(0x0020)	/* on pseudo-roll list */
#define	ME_USER		(0x0040)	/* User Block DT_CANCEL entry */

/*
 * MAP TYPES
 */
enum maptypes	{
	deltamaptype, logmaptype, matamaptype
};

/*
 * MAP
 */
#define	DELTAMAP_NHASH	(512)
#define	LOGMAP_NHASH	(2048)
#define	MAP_INDEX(mof, mtm) \
	(((mof) >> MAPBLOCKSHIFT) & (mtm->mtm_nhash-1))
#define	MAP_HASH(mof, mtm) \
	((mtm)->mtm_hash + MAP_INDEX((mof), (mtm)))

typedef struct mt_map {
	/*
	 * anchor doubly linked list this map's entries -- MUST BE FIRST
	 */
	mapentry_t	*mtm_next;
	mapentry_t	*mtm_prev;

	enum maptypes	mtm_type;	/* map type */
	int		mtm_flags;	/* generic flags */
	int		mtm_ref;	/* PTE like ref bit */
	ulong_t		mtm_debug;	/* set at create time */
	ulong_t		mtm_age;	/* mono-inc; tags mapentries */
	mapentry_t	*mtm_cancel;	/* to be canceled at commit */
	ulong_t		mtm_nhash;	/* # of hash anchors */
	mapentry_t	**mtm_hash;	/* array of singly linked lists */
	struct topstats	*mtm_tops;	/* trans ops - enabled by an ioctl */
	long		mtm_nme;	/* # of mapentries */
	long		mtm_nmet;	/* # of mapentries this transaction */
	long		mtm_cfrags;	/* Canceled frags */
	long		mtm_cfragmax;	/* Maximum canceled frags */
	/*
	 * used after logscan to set the log's tail
	 */
	off_t		mtm_tail_lof;
	size_t		mtm_tail_nb;

	/*
	 * debug field for Scan test
	 */
	off_t		mtm_trimlof;	/* log was trimmed to this lof */
	off_t		mtm_trimtail;	/* tail lof before trimming */
	off_t		mtm_trimalof;	/* lof of last allocation delta */
	off_t		mtm_trimclof;	/* lof of last commit delta */
	off_t		mtm_trimrlof;	/* lof of last rolled delta */
	ml_unit_t	*mtm_ul;	/* log unit for this map */

	/*
	 * moby trans stuff
	 */
	uint32_t		mtm_tid;
	uint32_t		mtm_committid;
	ushort_t		mtm_closed;
	ushort_t		mtm_seq;
	long			mtm_wantin;
	long			mtm_active;
	long			mtm_activesync;
	ulong_t			mtm_dirty;
	kmutex_t		mtm_lock;
	kcondvar_t		mtm_cv_commit;
	kcondvar_t		mtm_cv_next;
	kcondvar_t		mtm_cv_eot;

	/*
	 * mutex that protects all the fields in mt_map except
	 * mtm_mapnext and mtm_refcnt
	 */
	kmutex_t	mtm_mutex;

	/*
	 * logmap only condition variables
	 */
	kcondvar_t	mtm_to_roll_cv; /* roll log or kill roll thread */
	kcondvar_t	mtm_from_roll_cv; /* log rolled or thread exiting */

	/*
	 * rw lock for the agenext mapentry field
	 */
	krwlock_t	mtm_rwlock;
	/*
	 * DEBUG: runtestscan
	 */
	kmutex_t	mtm_scan_mutex;

	/*
	 * logmap only taskq sync count variable, protected by mtm_lock.
	 * keeps track of the number of pending top_issue_sync
	 * dispatches.
	 */
	int		mtm_taskq_sync_count;

	/*
	 * logmap only condition variable, to synchronize with lufs_unsnarf.
	 */
	kcondvar_t	mtm_cv;
} mt_map_t;

/*
 * mtm_flags
 */
#define	MTM_ROLL_EXIT		0x00000001 /* force roll thread to exit */
#define	MTM_ROLL_RUNNING	0x00000002 /* roll thread is running */
#define	MTM_FORCE_ROLL		0x00000004 /* force at least one roll cycle */
#define	MTM_ROLLING		0x00000008 /* currently rolling the log */
#define	MTM_CANCELED		0x00000010 /* cancel entries were removed */

/*
 * Generic range checking macros
 */
#define	OVERLAP(sof, snb, dof, dnb) \
	(((sof) >= (dof) && (sof) < ((dof) + (dnb))) || \
	((dof) >= (sof) && (dof) < ((sof) + (snb))))
#define	WITHIN(sof, snb, dof, dnb) \
	(((sof) >= (dof)) && (((sof) + (snb)) <= ((dof) + (dnb))))
#define	DATAoverlapME(mof, hnb, me) \
	(OVERLAP((mof), (hnb), (me)->me_mof, (me)->me_nb))
#define	MEwithinDATA(me, mof, hnb) \
	(WITHIN((me)->me_mof, (me)->me_nb, (mof), (hnb)))
#define	DATAwithinME(mof, hnb, me) \
	(WITHIN((mof), (hnb), (me)->me_mof, (me)->me_nb))
#define	DATAwithinCRB(mof, nb, crb) \
	(WITHIN((mof), (nb), (crb)->c_mof, (crb)->c_nb))

/*
 * TRANSACTION OPS STATS
 */
typedef struct topstats {
	uint64_t	mtm_top_num[TOP_MAX];
	uint64_t	mtm_top_size_etot[TOP_MAX];
	uint64_t	mtm_top_size_rtot[TOP_MAX];
	uint64_t	mtm_top_size_max[TOP_MAX];
	uint64_t	mtm_top_size_min[TOP_MAX];
	uint64_t	mtm_delta_num[DT_MAX];
} topstats_t;

/*
 * fio_lufs_stats_t is used by _FIO_GET_TOP_STATS ioctl for getting topstats
 */
typedef struct fio_lufs_stats {
	uint32_t	ls_debug;	/* out: un_debug value */
	uint32_t	_ls_pad;	/* make size 64-bit aligned on x86 */
	topstats_t	ls_topstats;	/* out: transaction stats */
} fio_lufs_stats_t;

/*
 * roll buf structure; one per roll buffer
 */
typedef uint16_t rbsecmap_t;
typedef struct rollbuf {
	buf_t rb_bh;		/* roll buffer header */
	struct rollbuf *rb_next; /* link for mof ordered roll bufs */
	crb_t *rb_crb;		/* cached roll buffer to roll */
	mapentry_t *rb_age;	/* age list */
	rbsecmap_t rb_secmap;	/* sector map */
} rollbuf_t;

/*
 * un_debug
 *	MT_TRANSACT		- keep per thread accounting of tranactions
 *	MT_MATAMAP		- double check deltas and ops against matamap
 *	MT_WRITE_CHECK		- check master+deltas against metadata write
 *	MT_LOG_WRITE_CHECK	- read after write for log writes
 *	MT_CHECK_MAP		- check map after every insert/delete
 *	MT_TRACE		- trace transactions (used with MT_TRANSACT)
 *	MT_SIZE			- fail on size errors (used with MT_TRANSACT)
 *	MT_NOASYNC		- force every op to be sync
 *	MT_FORCEROLL		- forcibly roll the log after every commit
 *	MT_SCAN			- running runtestscan; special case as needed
 */
#define	MT_NONE			(0x00000000)
#define	MT_TRANSACT		(0x00000001)
#define	MT_MATAMAP		(0x00000002)
#define	MT_WRITE_CHECK		(0x00000004)
#define	MT_LOG_WRITE_CHECK	(0x00000008)
#define	MT_CHECK_MAP		(0x00000010)
#define	MT_TRACE		(0x00000020)
#define	MT_SIZE			(0x00000040)
#define	MT_NOASYNC		(0x00000080)
#define	MT_FORCEROLL		(0x00000100)
#define	MT_SCAN			(0x00000200)

struct logstats {
	kstat_named_t ls_lreads;	/* master reads */
	kstat_named_t ls_lwrites;	/* master writes */
	kstat_named_t ls_lreadsinmem;	/* log reads in memory */
	kstat_named_t ls_ldlreads;	/* log reads */
	kstat_named_t ls_ldlwrites;	/* log writes */
	kstat_named_t ls_mreads;	/* log master reads */
	kstat_named_t ls_rreads;	/* log roll reads */
	kstat_named_t ls_rwrites;	/* log roll writes */
};

#ifdef _KERNEL

typedef struct threadtrans {
	ulong_t		deltas_size;	/* size of deltas this transaction */
	uint32_t	last_async_tid;	/* last async transaction id */
	uchar_t		any_deltas;	/* any deltas done this transaction */
#ifdef DEBUG
	uint_t		topid;		/* transaction type */
	ulong_t		esize;		/* estimated trans size */
	ulong_t		rsize;		/* real trans size */
	dev_t		dev;		/* device */
#endif /* DEBUG */
} threadtrans_t;

/*
 * Log layer protos -- lufs_log.c
 */
extern void		ldl_strategy(ml_unit_t *, buf_t *);
extern void		ldl_round_commit(ml_unit_t *);
extern void		ldl_push_commit(ml_unit_t *);
extern int		ldl_need_commit(ml_unit_t *);
extern int		ldl_has_space(ml_unit_t *, mapentry_t *);
extern void		ldl_write(ml_unit_t *, caddr_t, offset_t, mapentry_t *);
extern void		ldl_waito(ml_unit_t *);
extern int		ldl_read(ml_unit_t *, caddr_t, offset_t, off_t,
					mapentry_t *);
extern void		ldl_sethead(ml_unit_t *, off_t, uint32_t);
extern void		ldl_settail(ml_unit_t *, off_t, size_t);
extern ulong_t		ldl_logscan_nbcommit(off_t);
extern int		ldl_logscan_read(ml_unit_t *, off_t *, size_t, caddr_t);
extern void		ldl_logscan_begin(ml_unit_t *);
extern void		ldl_logscan_end(ml_unit_t *);
extern int		ldl_need_roll(ml_unit_t *);
extern void		ldl_seterror(ml_unit_t *, char *);
extern size_t		ldl_bufsize(ml_unit_t *);
extern void		ldl_savestate(ml_unit_t *);
extern void		free_cirbuf(cirbuf_t *);
extern void		alloc_rdbuf(cirbuf_t *, size_t, size_t);
extern void		alloc_wrbuf(cirbuf_t *, size_t);

/*
 * trans driver layer -- lufs.c
 */
extern int		trans_not_wait(struct buf *cb);
extern int		trans_not_done(struct buf *cb);
extern int		trans_wait(struct buf *cb);
extern int		trans_done(struct buf *cb);
extern void		lufs_strategy(ml_unit_t *, buf_t *);
extern void		lufs_read_strategy(ml_unit_t *, buf_t *);
extern void		lufs_write_strategy(ml_unit_t *, buf_t *);
extern void		lufs_init(void);
extern uint32_t		lufs_hd_genid(const ml_unit_t *);
extern int		lufs_enable(struct vnode *, struct fiolog *, cred_t *);
extern int		lufs_disable(vnode_t *, struct fiolog *);

/*
 * transaction op layer -- lufs_top.c
 */
extern void	_init_top(void);
extern int	top_read_roll(rollbuf_t *, ml_unit_t *);


/*
 * map layer -- lufs_map.c
 */
extern void		map_free_entries(mt_map_t *);
extern int		matamap_overlap(mt_map_t *, offset_t, off_t);
extern int		matamap_within(mt_map_t *, offset_t, off_t);
extern int		deltamap_need_commit(mt_map_t *);
extern void		deltamap_add(mt_map_t *, offset_t, off_t, delta_t,
				int (*)(), ulong_t, threadtrans_t *tp);
extern mapentry_t	*deltamap_remove(mt_map_t *, offset_t, off_t);
extern void		deltamap_del(mt_map_t *, offset_t, off_t);
extern void		deltamap_push(ml_unit_t *);
extern void		logmap_cancel_remove(mt_map_t *);
extern int		logmap_need_commit(mt_map_t *);
extern int		logmap_need_roll_async(mt_map_t *);
extern int		logmap_need_roll_sync(mt_map_t *);
extern void		logmap_start_roll(ml_unit_t *);
extern void		logmap_kill_roll(ml_unit_t *);
extern void		logmap_forceroll(mt_map_t *);
extern void		logmap_forceroll_nowait(mt_map_t *);
extern int		logmap_overlap(mt_map_t *, offset_t, off_t);
extern void		logmap_remove_roll(mt_map_t *, offset_t, off_t);
extern int		logmap_next_roll(mt_map_t *, offset_t *);
extern int		logmap_list_get(mt_map_t *, offset_t, off_t,
				mapentry_t **);
extern int		logmap_list_get_roll(mt_map_t *, offset_t, rollbuf_t *);
extern void		logmap_list_put(mt_map_t *, mapentry_t *);
extern void		logmap_list_put_roll(mt_map_t *, mapentry_t *);
extern int		logmap_setup_read(mapentry_t *, rollbuf_t *);
extern void		logmap_make_space(struct mt_map *, ml_unit_t *,
				mapentry_t *);
extern void		logmap_add(ml_unit_t *, char *, offset_t, mapentry_t *);
extern void		logmap_add_buf(ml_unit_t *, char *, offset_t,
				mapentry_t *, caddr_t, uint32_t);
extern void		logmap_commit(ml_unit_t *, uint32_t);
extern void		logmap_sethead(mt_map_t *, ml_unit_t *);
extern void		logmap_settail(mt_map_t *, ml_unit_t *);
extern void		logmap_roll_dev(ml_unit_t *ul);
extern void		logmap_cancel(ml_unit_t *, offset_t, off_t, int);
extern void		logmap_free_cancel(mt_map_t *, mapentry_t **);
extern int		logmap_iscancel(mt_map_t *, offset_t, off_t);
extern void		logmap_logscan(ml_unit_t *);
extern mt_map_t		*map_put(mt_map_t *);
extern mt_map_t		*map_get(ml_unit_t *, enum maptypes, int);
extern void		_init_map(void);

/*
 * scan and roll threads -- lufs_thread.c
 */
extern void	trans_roll(ml_unit_t *);

/*
 * DEBUG
 */
#ifdef	DEBUG
extern int	map_put_debug(mt_map_t *);
extern int	map_get_debug(ml_unit_t *, mt_map_t *);
extern int	top_write_debug(ml_unit_t *, mapentry_t *, offset_t, off_t);
extern int	matamap_overlap(mt_map_t *, offset_t, off_t);
extern int	ldl_sethead_debug(ml_unit_t *);
extern int	map_check_linkage(mt_map_t *);
extern int	logmap_logscan_debug(mt_map_t *, mapentry_t *);
extern int	map_check_ldl_write(ml_unit_t *, caddr_t, offset_t,
								mapentry_t *);
extern int	logmap_logscan_commit_debug(off_t, mt_map_t *);
extern int	logmap_logscan_add_debug(struct delta *, mt_map_t *);
extern int	top_delta_debug(ml_unit_t *, offset_t, off_t, delta_t);
extern int	top_begin_debug(ml_unit_t *, top_t, ulong_t);
extern int	top_end_debug(ml_unit_t *, mt_map_t *, top_t, ulong_t);
extern int	top_roll_debug(ml_unit_t *);
extern int	top_init_debug(void);
extern int	lufs_initialize_debug(ml_odunit_t *);
#endif	/* DEBUG */

extern uint64_t delta_stats[DT_MAX];
extern uint64_t roll_stats[DT_MAX];
extern struct logstats logstats;
extern int ufs_crb_enable;

extern uint_t topkey;
extern uint32_t ufs_ncg_log;

extern uint_t lufs_debug;

#endif	/* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_FS_UFS_LOG_H */