Coda Distributed File System
rvm_private.h
Go to the documentation of this file.
1/* BLURB lgpl
2
3 Coda File System
4 Release 8
5
6 Copyright (c) 1987-2025 Carnegie Mellon University
7 Additional copyrights listed below
8
9This code is distributed "AS IS" without warranty of any kind under
10the terms of the GNU Library General Public Licence Version 2, as
11shown in the file LICENSE. The technical and financial contributors to
12Coda are listed in the file CREDITS.
13
14 Additional copyrights
15 none currently
16
17#*/
18
19/*
20*
21* Internal Definitions for RVM
22*
23*/
24
25/* permit multiple includes */
26#ifndef _RVM_PRIVATE_
27#define _RVM_PRIVATE_ 1
28
29/* turn on debuging for now */
30#ifndef DEBUG
31#define DEBUG 1
32#endif
33
34#ifdef HAVE_CONFIG_H
35#include <config.h>
36#endif
37
38#include <sys/types.h>
39#include <stdlib.h>
40#include <string.h>
41#include <assert.h>
42#include <rvm/rvm.h>
43#include <rvm/rvm_statistics.h>
44
45#ifndef HAVE_GETPAGESIZE /* defined(__linux__) && defined(sparc) */
46#include <asm/page.h>
47#define getpagesize() PAGE_SIZE
48#else
49#include <unistd.h>
50#endif
51
52#include <fcntl.h>
53#ifndef O_BINARY
54#define O_BINARY 0
55#endif
56
57/* note: Log Version must change if Statistics Version changed */
58#define RVM_LOG_VERSION "RVM Log Version 1.4 Oct 17, 1997 "
59
60/* general purpose macros */
61
62/* make sure realloc knows what to do with null ptr */
63#define REALLOC(x, l) (((x) == NULL) ? malloc(l) : realloc((x), (l)))
64
65/* bcopy <=> memcpy, defs of syscalls */
66#ifdef __STDC__
67#define BCOPY(x, y, n) memcpy((y), (x), (n))
68#define BZERO(x, n) memset((x), 0, (n))
69#else
70#define BCOPY(x, y, n) bcopy((x), (y), (n))
71#define BZERO(x, n) bzero((x), (n))
72#endif
73
74/* loop terminated by explicit break */
75#define DO_FOREVER for (;;)
76
77#define FORWARD rvm_true /* record scan forward */
78#define REVERSE rvm_false /* record scan reverse */
79
80/* RVM Internal Error Messages */
81
82#define ERR_DATE_SKEW "Current time before last recorded - check kernel date"
83/* timestamp arithmetic */
84
85/* comparison macros */
86#define TIME_LSS(x, y) \
87 (((x).tv_sec < (y).tv_sec) || \
88 ((((x).tv_sec == (y).tv_sec) && ((x).tv_usec < (y).tv_usec))))
89#define TIME_GTR(x, y) \
90 (((x).tv_sec > (y).tv_sec) || \
91 ((((x).tv_sec == (y).tv_sec) && ((x).tv_usec > (y).tv_usec))))
92#define TIME_LEQ(x, y) (!TIME_GTR((x), (y)))
93#define TIME_GEQ(x, y) (!TIME_LSS((x), (y)))
94#define TIME_EQL(x, y) \
95 (((x).tv_sec == (y).tv_sec) && ((x).tv_usec == (y).tv_usec))
96#define TIME_EQL_ZERO(x) (((x).tv_sec == 0 && ((x).tv_usec == 0)))
97
98#define ZERO_TIME(x) \
99 do { \
100 (x).tv_sec = 0; \
101 (x).tv_usec = 0; \
102 } while (0)
103
104/* range monitoring vector */
105typedef struct {
106 char *vmaddr; /* range vm address */
107 rvm_length_t length; /* range length */
108 unsigned long format; /* data print format switches */
109 int radix; /* print radix for vmaddr */
110} chk_vec_t;
111
112/* signal handler function type (rvmutl only) */
114
115/* recovery monitor call-back function type */
116typedef void rvm_monitor_call_t();
117/* rvm_length_t vmaddr;
118 rvm_length_t length;
119 char *data_ptr;
120 rvm_offset_t *data_offset;
121 rec_hdr_t *rec_hdr;
122 rvm_length_t index;
123 char *msg;
124*/
125/* round up & down macros
126 **** all depend on sizes being a power of 2 ****
127*/
128#define LENGTH_MASK ((rvm_length_t)(~(sizeof(rvm_length_t) - 1)))
129#define ROUND_TO_LENGTH(len) \
130 (((rvm_length_t)((rvm_length_t)(len) + sizeof(rvm_length_t) - 1)) & \
131 LENGTH_MASK)
132#define CHOP_TO_LENGTH(len) ((rvm_length_t)((rvm_length_t)(len) & LENGTH_MASK))
133#define ALIGNED_LEN(addr, len) \
134 (ROUND_TO_LENGTH((rvm_length_t)(addr) + (rvm_length_t)(len)) - \
135 CHOP_TO_LENGTH(addr))
136#define BYTE_SKEW(len) ((rvm_length_t)(len) & ~LENGTH_MASK)
137
138#define SECTOR_SIZE 512
139#define SECTOR_MASK ((rvm_length_t)(~(SECTOR_SIZE - 1)))
140#define ROUND_TO_SECTOR_SIZE(x) \
141 (((rvm_length_t)(x) + SECTOR_SIZE - 1) & SECTOR_MASK)
142#define CHOP_TO_SECTOR_SIZE(x) ((rvm_length_t)(x) & SECTOR_MASK)
143
144#define SECTOR_INDEX(x) ((x) & (SECTOR_SIZE - 1))
145
146#define ROUND_OFFSET_TO_SECTOR_SIZE(x) rvm_rnd_offset_to_sector(&(x))
147
148#define CHOP_OFFSET_TO_SECTOR_SIZE(x) \
149 (RVM_MK_OFFSET(RVM_OFFSET_HIGH_BITS_TO_LENGTH(x), \
150 CHOP_TO_SECTOR_SIZE(RVM_OFFSET_TO_LENGTH(x))))
151
152#define OFFSET_TO_SECTOR_INDEX(x) (SECTOR_INDEX(RVM_OFFSET_TO_LENGTH((x))))
153
154#define CHOP_OFFSET_TO_LENGTH_SIZE(x) \
155 (RVM_MK_OFFSET(RVM_OFFSET_HIGH_BITS_TO_LENGTH(x), \
156 CHOP_TO_LENGTH(RVM_OFFSET_TO_LENGTH(x))))
157
158#define ROUND_TO_PAGE_SIZE(x) (((rvm_length_t)(x) + page_size - 1) & page_mask)
159#define CHOP_TO_PAGE_SIZE(x) ((rvm_length_t)(x) & page_mask)
160
161/* other stuff... */
162
163#define OFFSET_TO_FLOAT(x) \
164 ((4.294967e+9) * ((float)(RVM_OFFSET_HIGH_BITS_TO_LENGTH(x))) + \
165 (float)(RVM_OFFSET_TO_LENGTH(x)))
166/* internal structure id's */
167typedef enum
168{
169 struct_first_id = 9, /* base for free list array length */
170
171 /* free list allocated structures */
172 log_id, /* log device descriptor */
173 int_tid_id, /* internal transaction descriptor */
174 tid_rvm_id, /* external tid while on free list */
175 range_id, /* range descriptor */
176 seg_id, /* segment descriptor */
177 region_id, /* internal region descriptor */
178 region_rvm_id, /* external region while on free list */
179 options_rvm_id, /* external options while on free list */
180 statistics_rvm_id, /* rvm_statistics record while on free list */
181 mem_region_id, /* vm region tree node */
182 dev_region_id, /* device region tree node */
183 log_special_id, /* special log record */
184
185 struct_last_cache_id, /* marker for free lists array length */
186
187 /* non-free list allocated structures */
188
189 log_status_id, /* log status descriptor */
190 log_dev_status_id, /* log device status area (on disk) */
191 log_wrap_id, /* log wrap-around marker */
192 log_seg_id, /* segment mapping marker in log */
193 seg_dict_id, /* recovery dictionary segment desc. */
194 trans_hdr_id, /* transaction header in log */
195 rec_end_id, /* log record end marker */
196 nv_range_id, /* new value range header */
197 nv_buf_id, /* new value vm buffer */
198 free_page_id, /* free page header descriptor */
199 rw_qentry_id, /* rw_lock queue entry */
200 tree_root_id, /* tree root */
201 /* mmapped_list_id,*/ /* BSD/mmap systems only */
202 struct_last_id /* marker for last structure id */
204/* macros to use struct_id's as int's & vice versa
205 for free list allocated structures only */
206#define ID_INDEX(id) ((rvm_length_t)(id) - (rvm_length_t)struct_first_id - 1)
207#define INDEX_ID(i) ((struct_id_t)((i) + 1 + (long)struct_first_id))
208
209/* number of free list allocated structures */
210#define NUM_CACHE_TYPES \
211 ((rvm_length_t)struct_last_cache_id - (rvm_length_t)struct_first_id - 1)
212#define NUM_TYPES \
213 ((rvm_length_t)struct_last_id - (rvm_length_t)struct_first_id - 1)
214
215// clang-format off
216/* preallocation sizes for internal structure free lists
217 must be in same order as above free list allocted enum's
218*/
219#define NUM_PRE_ALLOCATED \
220 0, /* log's */ \
221 20, /* tid's */ \
222 20, /* rvm_tid's */ \
223 50, /* range's */ \
224 0, /* seg's */ \
225 10, /* region's */ \
226 0, /* rvm_region's */ \
227 0, /* rvm_options */ \
228 2, /* rvm_statistics */ \
229 10, /* mem_region nodes */ \
230 1, /* dev_region nodes */ \
231 1 /* special log markers */
232
233/* maximum sizes for internal structure free lists
234 must be in same order as above free list allocted enum's
235*/
236#define MAX_ALLOCATED \
237 0, /* log's */ \
238 20, /* tid's */ \
239 20, /* rvm_tid's */ \
240 50, /* range's */ \
241 0, /* seg's */ \
242 10, /* region's */ \
243 0, /* rvm_region's */ \
244 0, /* rvm_options */ \
245 2, /* rvm_statistics */ \
246 10, /* mem_region nodes */ \
247 2000, /* dev_region nodes */ \
248 1 /* special log markers */
249
250/* sizes and names of internal types
251 must be in same order as above enum's
252*/
253#define CACHE_TYPE_SIZES \
254 sizeof(log_t), \
255 sizeof(int_tid_t), \
256 sizeof(rvm_tid_t), \
257 sizeof(range_t), \
258 sizeof(seg_t), \
259 sizeof(region_t), \
260 sizeof(rvm_region_t), \
261 sizeof(rvm_options_t), \
262 sizeof(rvm_statistics_t), \
263 sizeof(mem_region_t), \
264 sizeof(dev_region_t), \
265 sizeof(log_special_t)
266
267#define OTHER_TYPE_SIZES \
268 0, \
269 sizeof(log_status_t), \
270 sizeof(log_dev_status_t), \
271 sizeof(log_wrap_t), \
272 sizeof(log_seg_t), \
273 sizeof(seg_dict_t), \
274 sizeof(trans_hdr_t), \
275 sizeof(rec_end_t), \
276 sizeof(nv_range_t), \
277 sizeof(nv_buf_t), \
278 sizeof(free_page_t), \
279 sizeof(rw_qentry_t), \
280 sizeof(tree_root_t)/*, \
281 sizeof(mmapped_list_t)*/
283#define TYPE_NAMES \
284 "log_id", \
285 "int_tid_id", \
286 "tid_rvm_id", \
287 "range_id", \
288 "seg_id", \
289 "region_id", \
290 "region_rvm_id", \
291 "options_rvm_id", \
292 "statistics_rvm_id", \
293 "mem_region_id", \
294 "dev_region_id", \
295 "log_special_id", \
296 "struct_last_cache_id", \
297 "log_status_id", \
298 "log_dev_status_id", \
299 "log_wrap_id", \
300 "log_seg_id", \
301 "seg_dict_id", \
302 "trans_hdr_id", \
303 "rec_end_id", \
304 "nv_range_id", \
305 "nv_buf_id", \
306 "free_page_id", \
307 "rw_qentry_id", \
308 "tree_root_id"
309 // "mmapped_list_id"
310// clang-format on
311
312/* doubly-linked list cell header
313 this structure serves as the link and struct_id carrier for larger
314 structures when declared as the 1st field of the structure.
315 it is also used as the root, or header, of a list when statically allocated,
316 or embedded in another structure as other than the 1st field,
317 in which case its struct_id is that of the type of elements on the list.
319typedef struct list_entry_s {
320 struct list_entry_s *nextentry; /* in accordance with insque(3) */
321 struct list_entry_s *preventry;
322 union {
323 struct list_entry_s *name; /* back pointer to head of list */
324 long length; /* length of list if header */
326 struct_id_t struct_id; /* self identifier; NEVER altered */
327 rvm_bool_t is_hdr; /* true if list header */
329
330/* list macros, lst: address of list header */
331#define LIST_EMPTY(lst) ((lst).list.length == 0)
332#define LIST_NOT_EMPTY(lst) ((lst).list.length != 0)
333
334/* list iterators for simple list traversals, no unlinking */
335#define FOR_ENTRIES_OF(lst, type, ptr) /* list iterator, FIFO order */ \
336 for ((ptr) = (type *)((lst).nextentry); !((ptr)->links.is_hdr); \
337 (ptr) = (type *)((ptr)->links.nextentry))
339#define FOR_REVERSE_ENTRIES_OF(lst, type, ptr) /* list iterator, LIFO order */ \
340 for ((ptr) = (type *)((lst).preventry); !((ptr)->links.is_hdr); \
341 (ptr) = (type *)((ptr)->links.preventry))
342
343/* list iterators for traversals that unlink the entries */
344#define UNLINK_ENTRIES_OF(lst, type, ptr) /* list generator, FIFO order */ \
345 for ((ptr) = (type *)((lst).nextentry); !((ptr)->links.is_hdr); \
346 (ptr) = (type *)((lst).nextentry))
348#define UNLINK_REVERSE_ENTRIES_OF(lst, type, \
349 ptr) /* list generator, LIFO order */ \
350 for ((ptr) = (type *)((lst).preventry); !((ptr)->links.is_hdr); \
351 (ptr) = (type *)((lst).preventry))
352
353/* free page list entry */
354typedef struct {
355 list_entry_t links; /* list links */
356 rvm_length_t len; /* length of free pages in bytes */
358
359/* Synchronization and Threads support */
360
361/*
362 * We can have one of three thread models:
363 * cthreads: Mach threads (kernel or coroutine)
364 * lwp: Coda's lightweight process package
365 * pthreads: POSIX threads
366 *
367 * If RVM_USELWP is defined, then lwp support is compiled in.
368 * If RVM_USEPT is defined, then pthreads support is compiled in.
369 * If niether of these is defined, then cthreads support is compiled in.
370 *
371 * It is assumed in the rds package that cthreads and pthreads use
372 * preemptive scheduling, and they are synchronized appropriately.
373 *
374 * You must define only one of the above targets, and it must be defined
375 * consistently across the following packages: RVM, RDS, and URT
376 */
377
378#ifdef RVM_USELWP /* special thread support for Coda */
379#include "rvm_lwp.h"
380#elif defined(RVM_USEPT) /* special support for pthreads */
381#include "rvm_pthread.h"
382#else /* normal: use Cthreads */
383#include <cthreads.h>
384
385/* define types symbolically to permit use of non-Cthread thread support */
386#define RVM_MUTEX struct mutex
387#define RVM_CONDITION struct condition
388
389/* macro for testing if a lock is free */
390#define LOCK_FREE(lck) \
391 (mutex_try_lock(&(lck)) ? (mutex_unlock(&(lck)), rvm_true) : rvm_false)
392#endif
393
394/* protect a critical section
395 lck: address of mutex
396 body: the critical section code
398#define CRITICAL(lck, body) \
399 do { \
400 mutex_lock(&(lck)); \
401 body; \
402 mutex_unlock(&(lck)); \
403 } while (0)
404
405/* rw_lock (read/write) support
406 An rw_lock permits many readers of a structure, but only
407 if there is no writer pending. Only a single writer is permitted,
408 and to get the write lock, there must be no readers.
409 If a write is requested, no additional readers will be permitted
410 until the write is satisfied. Blocked threads are processed in
411 FIFO order.
413typedef enum /* rw_lock access modes */
415 r = 32, /* get lock for read-only */
416 w, /* get lock for read/write */
417 f /* lock free, (internal use only) */
420typedef struct /* rw_lock structure */
422 RVM_MUTEX mutex; /* mutex to protect rw_lock innards */
423 long read_cnt; /* read lock count, 0 ==> free */
424 long write_cnt; /* write lock count, 0 ==> free */
425 list_entry_t queue; /* blocked thread queue */
426 rw_lock_mode_t lock_mode; /* current lock mode */
427} rw_lock_t;
429typedef struct /* rw_lock queue entry */
431 list_entry_t links; /* queue links & struct_id */
432 RVM_CONDITION wait; /* condition code for blocking */
433 rw_lock_mode_t mode; /* access mode */
435
436/* protect a rw_lock critical section
437 lck: address of rw_lock
438 mode: r or w
439 body: the critical section code
441#define RW_CRITICAL(rwl, mode, body) \
442 do { \
443 rw_lock(&(rwl), (mode)); \
444 body; \
445 rw_unlock(&(rwl), (mode)); \
446 } while (0)
447
448/* macro for testing if an rw_lock is free */
449#define RW_LOCK_FREE(rwl) \
450 (((rwl).read_cnt + (rwl).write_cnt) == 0) && ((rwl).lock_mode == f)
451/* tree node structures */
453typedef struct tree_node_s /* basic tree node */
455 struct tree_node_s *lss; /* ptr to less than entry */
456 struct tree_node_s *gtr; /* ptr to greater than entry */
457 long bf; /* balance factor */
458 struct_id_t struct_id; /* self identifier */
461typedef union {
462 tree_node_t node; /* links for trees */
463 list_entry_t entry; /* links for allocation cache */
466typedef enum /* traversal states */
468 lss = 50,
470 gtr,
474typedef struct /* tree traversal position entry */
476 tree_node_t *ptr; /* node pointer */
477 traverse_state_t state; /* state of traversal {lss,self,gtr} */
478} tree_pos_t;
480typedef struct /* tree root structure */
482 struct_id_t struct_id; /* self identifier */
483 tree_node_t *root; /* ptr to root node */
484 tree_pos_t *traverse; /* traversal position vector */
485 rvm_length_t traverse_len; /* max length of traverse vector */
486 long level; /* current position in traversal
487 vector */
488 rvm_length_t n_nodes; /* number of nodes in tree */
489 rvm_length_t max_depth; /* length of deepest path in tree */
490 rvm_bool_t unlink; /* unlink nodes as traversed */
492
493extern tree_root_t region_tree; /* root of mapped region tree */
494extern rw_lock_t region_tree_lock; /* lock for region tree */
496#define TRAVERSE_LEN_INCR 15 /* allocate 15 slots at a time */
497/* tree structure iterators
498 -- nodes are delinked as traversed
499 -- do not use tree_insert or tree_delete or otherwise change
500 tree shape in body of iterators if iteration is to be continued
501 -- iterators may not be nested for same tree
503#define FOR_NODES_OF(tree, type, ptr) /* tree iterator, lss -> gtr order */ \
504 for ((ptr) = (type *)init_tree_generator(&(tree), FORWARD, rvm_false); \
505 (ptr) != NULL; (ptr) = (type *)tree_successor(&(tree)))
507#define FOR_REVERSE_NODES_OF(tree, type, \
508 ptr) /* tree iterator, gtr -> lss order */ \
509 for ((ptr) = (type *)init_tree_generator(&(tree), REVERSE, rvm_false); \
510 (ptr) != NULL; (ptr) = (type *)tree_predecessor(&(tree)))
511
512/* insertion test and iterate from existing nodes with equivalent key */
513#define FROM_EXISTING_NODE_OF(tree, type, ptr, node, cmp) \
514 for ((ptr) = (type *)tree_iterate_insert(&(tree), (node), (cmp)); \
515 (ptr) != NULL; (ptr) = (type *)tree_successor(&(tree)))
517#define UNLINK_NODES_OF(tree, type, ptr) /* tree iterator, lss -> gtr order */ \
518 for ((ptr) = (type *)init_tree_generator(&(tree), FORWARD, rvm_true); \
519 (ptr) != NULL; (ptr) = (type *)tree_successor(&(tree)))
521#define UNLINK_REVERSE_NODES_OF(tree, type, \
522 ptr) /* tree iterator, gtr -> lss order */ \
523 for ((ptr) = (type *)init_tree_generator(&(tree), REVERSE, rvm_true); \
524 (ptr) != NULL; (ptr) = (type *)tree_predecessor(&(tree)))
525/* Structure to remember where we have/have not mmapped */
526
527/* vm buffers for dev_region_t nodes */
528typedef struct {
529 struct_id_t struct_id; /* self identifier */
530 rvm_length_t ref_cnt; /* references to buffer */
531 rvm_length_t chk_sum; /* data buffer checksum */
532 rvm_length_t alloc_len; /* allocated length of buffer */
533 rvm_length_t data_len; /* length of log data */
534 char *buf; /* start of data area */
535} nv_buf_t;
537#define NV_BUF_SIZE(len) (ROUND_TO_LENGTH((len)) + sizeof(nv_buf_t))
538
539/* storage device region node */
540typedef struct {
541 tree_links_t links; /* ptr structure */
542 rvm_offset_t offset; /* segment start offset of changes */
543 rvm_offset_t end_offset; /* end offset (offset + length) */
544 rvm_length_t length; /* length of region */
545 char *nv_ptr; /* ptr into nv_buf */
546 nv_buf_t *nv_buf; /* buffer for new values if allocated */
547 rvm_offset_t log_offset; /* location of new values in log */
548 char *vmaddr; /* original vm addr (debug use only) */
550
551/* virtual memory region node */
552typedef struct {
553 tree_links_t links; /* ptr structure */
554 struct region_s *region; /* region descriptor */
555 char *vmaddr; /* base address */
556 rvm_length_t length; /* length of vm region */
558
559/* node comparator function type */
560typedef long cmp_func_t(tree_node_t *node1, tree_node_t *node2);
561
562/* log records written by commit, and associated with new value records */
563
564/* generic record header; not actually allocated, but any record header
565 can be cast to this to get its type & length for detailed analysis
567typedef struct {
568 struct_id_t struct_id; /* type of entry */
569 rvm_length_t rec_length; /* record length */
570 struct timeval timestamp; /* timestamp of record entry */
571 rvm_length_t rec_num; /* record number of entry */
572} rec_hdr_t;
573
574/* transaction record header: trans_hdr_t
575 * -- a single copy in the log descriptor */
576typedef struct {
577 rec_hdr_t rec_hdr; /* common log record header */
578 rvm_length_t num_ranges; /* number of ranges in record */
579 struct timeval uname; /* uname of transaction */
580 struct timeval commit_stamp; /* timestamp of commit */
581 rvm_length_t n_coalesced; /* count of coalesced transactions */
582 rvm_length_t flags; /* mode and optimization flags */
584
585/* new value record range header: nv_range_t */
586typedef struct {
587 rec_hdr_t rec_hdr; /* common log record header */
588 rvm_length_t sub_rec_len; /* back displacement to previous hdr */
589 rvm_length_t range_num; /* range number in record */
590 rvm_length_t length; /* actual modification length */
591 rvm_offset_t offset; /* offset of changes in segment */
592 char *vmaddr; /* modification vm address */
593 rvm_length_t chk_sum; /* data checksum */
594 long seg_code; /* segment short name */
595 rvm_bool_t is_split; /* is a range split for log wrap */
596} nv_range_t;
597
598/* special log types -- these records are inserted into the log to
599 record events not related to transaction commit and new value
600 recording.
601 These are generally used by the recovery algorithm to reconstruct the
602 committed images of segments at the time of a crash.
603*/
604/* segment mapping descriptor -- inserted by map when a segment
605 is mapped the first time; used to relate the short names to
606 an actual device or file name */
607typedef struct {
608 long seg_code; /* segment short name */
609 rvm_offset_t num_bytes; /* maximum usable length of seg dev */
610 long name_len; /* length of segment name */
611 char *name; /* full path name */
612} log_seg_t;
613
614/* log_special_t: the carrier for all special log types
615 free list allocated; additional type-dependent data can be placed
616 after this structure; all records end with rec_end_t record
618typedef struct {
619 list_entry_t links; /* list links and free list struct id */
620 /* following fields are written in log */
621 rec_hdr_t rec_hdr; /* common log record header */
622 union {
623 log_seg_t log_seg; /* segment mapping marker */
624 } special;
626
627/* generic log entry types */
628
629/* log record end marker: rec_end_t -- a single copy in the log descriptor */
630typedef struct {
631 rec_hdr_t rec_hdr; /* common log record header */
632 struct_id_t rec_type; /* type of recorded ended */
633 rvm_length_t sub_rec_len; /* back displacement to previous sub-record;
634 same as rec_length if none */
635} rec_end_t;
636
637/* log wrap-around marker -- a single copy in the log descriptor */
638typedef struct {
639 rec_hdr_t rec_hdr; /* common log record header */
640 struct_id_t struct_id2; /* for scan_wrap_reverse()! */
641} log_wrap_t;
642
643/* device descriptor -- included in log and segment descriptors */
644typedef struct {
645 char *name; /* print name of device */
646 long name_len; /* allocation length */
647 long handle; /* device handle */
648 rvm_offset_t num_bytes; /* length of device */
649 rvm_bool_t raw_io; /* true if using raw i/o */
650 unsigned long type; /* to store device type */
651 rvm_bool_t read_only; /* true if opened read-only */
653 struct iovec *iov; /* gather write io vector */
654 long iov_length; /* length of iov array */
655 long iov_cnt; /* count of entries used in iov */
656 rvm_length_t io_length; /* accumulated length of i/o */
657 rvm_offset_t last_position; /* last location seeked or transferred */
658
659 /* the following fields are used for log devices only */
660 char *wrt_buf; /* working raw io write buffer base */
661 rvm_length_t wrt_buf_len; /* usable wrt_buf length */
662 char *ptr; /* write buffer fill ptr */
663 char *buf_start; /* start of buffer flush region */
664 char *buf_end; /* end of buffer */
665 rvm_offset_t sync_offset; /* end offset after last sync */
667 char *pad_buf; /* padding buffer */
668 long pad_buf_len; /* length of current pad buf */
669} device_t;
670/* log structure macros */
672#define RANGE_LEN(range) (ALIGNED_LEN((range)->nv.vmaddr, (range)->nv.length))
674#define RANGE_SIZE(range) ((rvm_length_t)(NV_RANGE_OVERHEAD + RANGE_LEN(range)))
676#define TRANS_SIZE (ROUND_TO_LENGTH((sizeof(trans_hdr_t) + sizeof(rec_end_t))))
678#define NV_RANGE_OVERHEAD (ROUND_TO_LENGTH(sizeof(nv_range_t)))
680#define MIN_NV_RANGE_SIZE (NV_RANGE_OVERHEAD + 64)
682#define MIN_TRANS_SIZE \
683 (TRANS_SIZE + MIN_NV_RANGE_SIZE + ROUND_TO_LENGTH(sizeof(log_wrap_t)))
685#define LOG_SPECIAL_SIZE \
686 (ROUND_TO_LENGTH(sizeof(log_special_t) - sizeof(list_entry_t)))
688#define LOG_SPECIAL_IOV_MAX 3
689
690/* largest log type header on disc */
691#define MAX_HDR_SIZE (ROUND_TO_LENGTH((sizeof(log_special_t) + MAXPATHLEN)))
692/* other constants */
693
694/* maximum size nv's kept in vm during recovery */
695#define NV_LOCAL_MAX \
696 (8 * 1024 - ROUND_TO_LENGTH(NV_BUF_SIZE(sizeof(rvm_length_t) + 1)))
697
698/* size of status area i/o buffer */
699#define LOG_DEV_STATUS_SIZE ROUND_TO_SECTOR_SIZE(sizeof(log_dev_status_t))
700
701/* offsets for log status structures in files and partitions */
702#define RAW_STATUS_OFFSET 16 * SECTOR_SIZE
703#define FILE_STATUS_OFFSET 0
705#define UPDATE_STATUS 100 /* flushes before updating log status area */
706
707/* log status descriptor -- included in the log descriptor */
708#ifdef RVM_LOG_TAIL_SHADOW
709extern rvm_offset_t log_tail_shadow;
710extern rvm_bool_t has_wrapped;
711#define RVM_ASSIGN_OFFSET(x, y) (x) = (y)
712#endif /* RVM_LOG_TAIL_SHADOW */
714typedef struct {
715 /* status area control fields */
716 long update_cnt; /* number of updates before write */
717 rvm_bool_t valid; /* data in status area valid */
718 rvm_bool_t log_empty; /* true if log device & buffer empty */
719
720 /* log pointers & limits */
721 rvm_offset_t log_start; /* first offset for records */
722 rvm_offset_t log_size; /* dev.num_bytes - log_start: space for records */
723 rvm_offset_t log_head; /* current log head */
724 rvm_offset_t log_tail; /* current log tail */
725 rvm_offset_t prev_log_head; /* previous head (truncation only) */
726 rvm_offset_t prev_log_tail; /* previous tail (truncation only) */
727
728 /* consistency check fields */
729 struct timeval status_init; /* timestamp log creation */
730 struct timeval status_write; /* timestamp for last status write*/
731 struct timeval last_trunc; /* timestamp for last truncation */
732 struct timeval prev_trunc; /* timestamp for previous truncation */
733 struct timeval first_write; /* timestamp of first record in log */
734 struct timeval last_write; /* timestamp of last record in log */
735 struct timeval first_uname; /* first transaction uname in log */
736 struct timeval last_uname; /* last transaction uname in log */
737 struct timeval last_commit; /* last transaction commit timestamp */
738 struct timeval wrap_time; /* wrap timestamp if log wrapped */
739 rvm_length_t first_rec_num; /* 1st rec num of truncation epoch */
740 rvm_length_t last_rec_num; /* last rec num of truncation epoch */
741 rvm_length_t next_rec_num; /* assignment counter for rec_nums */
742
743 /* transaction statistics */
744 rvm_length_t n_abort; /* number of transactions aborted */
745 rvm_length_t n_flush_commit; /* number of flush mode commits */
746 rvm_length_t n_no_flush_commit; /* number of no_flush mode commits */
747 rvm_length_t n_split; /* number trans split for log wrap */
748 rvm_length_t n_truncation_wait; /* transactions delayed by truncation */
749
750 /* log statistics */
751 rvm_length_t n_flush; /* number of internal flushes */
752 rvm_length_t n_rvm_flush; /* number of explicit flush calls */
753 rvm_length_t n_special; /* number of special log records */
754 /* current overlap eliminated by range coalesce */
755 rvm_offset_t range_overlap;
756 /* current overlap eliminated by trans coalesce */
757 rvm_offset_t trans_overlap;
758 /* number of ranges eliminated by range coalesce/flush */
759 rvm_length_t n_range_elim;
760 /* number of ranges eliminated by trans coalesce/flush */
761 rvm_length_t n_trans_elim;
762 /* number of transactions coalesced in this flush cycle */
763 rvm_length_t n_trans_coalesced;
764 struct timeval flush_time; /* time spent in flushes */
765 rvm_length_t last_flush_time; /* duration of last flush (msec) */
766 rvm_length_t last_truncation_time; /* duration of last truncation (sec) */
767 rvm_length_t last_tree_build_time; /* duration of tree build (sec) */
768 rvm_length_t last_tree_apply_time; /* duration of tree apply phase (sec) */
769
770 /* histogram vectors */
772 rvm_length_t flush_times[flush_times_len]; /* flush timings */
773 rvm_length_t range_lengths[range_lengths_len]; /* range lengths flushed */
774 /* num ranges eliminated by range coalesce/flush */
775 rvm_length_t range_elims[range_elims_len];
776 /* num ranges eliminated by trans coalesce/flush */
777 rvm_length_t trans_elims[trans_elims_len];
778 /* space saved by range coalesce/flush */
779 rvm_length_t range_overlaps[range_overlaps_len];
780 /* space saved by trans coalesce/flush */
781 rvm_length_t trans_overlaps[range_overlaps_len];
782
783 /* cummulative transaction stats */
784 rvm_length_t tot_abort; /* total aborted transactions */
785 rvm_length_t tot_flush_commit; /* total flush commits */
786 rvm_length_t tot_no_flush_commit; /* total no_flush commits */
787 rvm_length_t tot_split; /* total transactions split for log wrap-around */
788
789 /* cummulative log statistics */
790 rvm_length_t tot_flush; /* total internal flush calls */
791 rvm_length_t tot_rvm_flush; /* total explicit rvm_flush calls */
792 rvm_length_t tot_special; /* total special log records */
793 rvm_length_t tot_wrap; /* total log wrap-arounds */
794 rvm_length_t log_dev_max; /* maximum % log device used so far */
795 rvm_offset_t tot_log_written; /* total length of all writes to log */
796 /* total overlap eliminated by range coalesce */
797 rvm_offset_t tot_range_overlap;
798 /* total overlap eliminated by trans coalesce */
799 rvm_offset_t tot_trans_overlap;
800 /* total number of ranges eliminated by range coalesce */
801 rvm_length_t tot_range_elim;
802 /* total number of ranges eliminated by trans coalesce */
803 rvm_length_t tot_trans_elim;
804 /* total number of transactions coalesced */
805 rvm_length_t tot_trans_coalesced;
806
807 /* truncation statistics */
808 rvm_length_t tot_rvm_truncate; /* total explicit rvm_truncate calls */
809 rvm_length_t tot_async_truncation; /* total asynchronous truncations */
810 /* total forced synchronous truncations */
811 rvm_length_t tot_sync_truncation;
812 /* total transactions delayed by truncation */
813 rvm_length_t tot_truncation_wait;
814 rvm_length_t tot_recovery; /* total recovery truncations */
815 struct timeval tot_flush_time; /* total time spent in flush */
816 struct timeval tot_truncation_time; /* cumulative truncation time */
817
818 /* histogram vectors */
819
820 /* truncation timings */
821 rvm_length_t tot_tree_build_times[truncation_times_len];
822 rvm_length_t tot_tree_apply_times[truncation_times_len];
823 rvm_length_t tot_truncation_times[truncation_times_len];
824 /* cummulative flush timings */
825 rvm_length_t tot_flush_times[flush_times_len];
826 /* cummulative range lengths flushed */
827 rvm_length_t tot_range_lengths[range_lengths_len];
828 /* total num ranges eliminated by range coalesce/flush */
829 rvm_length_t tot_range_elims[range_elims_len];
830 /* total num ranges eliminated by trans coalesce/flush */
831 rvm_length_t tot_trans_elims[trans_elims_len];
832 /* space saved by range coalesce/flush */
833 rvm_length_t tot_range_overlaps[range_overlaps_len];
834 /* space saved by trans coalesce/flush */
835 rvm_length_t tot_trans_overlaps[range_overlaps_len];
836 /* transactions coalesced per flush */
837 rvm_length_t tot_trans_coalesces[trans_coalesces_len];
838 rvm_length_t flush_state; /* flush status */
839 rvm_length_t trunc_state; /* truncation status */
841
842/* log status descriptor on log device: log_dev_status_t */
843typedef struct {
844 struct_id_t struct_id; /* self identifier */
845 rvm_length_t chk_sum; /* check sum */
846 char version[RVM_VERSION_MAX]; /* RVM interface version string */
847 char log_version[RVM_VERSION_MAX]; /* RVM log version string */
848 char statistics_version[RVM_VERSION_MAX]; /* RVM statistics version string */
849 log_status_t status; /* log status info */
851
852/* Flush and Truncation states */
853/* log flush initiated by rvm_flush */
854#define RVM_FLUSH_CALL (1)
855/* log flush initated by commit */
856#define RVM_FLUSH_COMMIT (2)
857/* truncation initiated by rvm_truncate */
858#define RVM_RECOVERY (4)
859#define RVM_TRUNCATE_CALL (010)
860/* truncation initiated by rvm daemon */
861#define RVM_ASYNC_TRUNCATE (020)
862/* truncation forced by flush */
863#define RVM_SYNC_TRUNCATE (040)
864/* truncation phase 1: find current log tail */
865#define RVM_TRUNC_FIND_TAIL (0100)
866/* phase 2: build modification trees */
867#define RVM_TRUNC_BUILD_TREE (0200)
868/* phase 3: apply modifications */
869#define RVM_TRUNC_APPLY (0400)
870/* phase 4: update log status */
871#define RVM_TRUNC_UPDATE (01000)
873#define RVM_TRUNC_PHASES \
874 (RVM_TRUNC_FIND_TAIL | RVM_TRUNC_BUILD_TREE | RVM_TRUNC_APPLY | \
875 RVM_TRUNC_UPDATE)
876
877/* log recovery buffer descriptor -- single copy in log descriptor */
878typedef struct {
879 char *buf; /* working recovery buffer base */
880 char *shadow_buf;
881 long length; /* length of allocated buffer */
882 rvm_offset_t buf_len; /* log buffer length as offset */
883 long r_length; /* length of data read into buffer */
884 rvm_offset_t offset; /* offset of buffer start in segment */
885 long ptr; /* index of present buffer position */
886 struct timeval timestamp; /* timestamp of transaction in buffer */
888 char *aux_buf; /* working auxiliary buffer base */
889 long aux_length; /* length of aux_buf */
890 rvm_offset_t aux_offset; /* offset of data in buffer */
891 long aux_rlength; /* length of data read into buffer */
893 struct timeval prev_timestamp; /* timestamp of previous record */
894 rvm_length_t prev_rec_num; /* previous record number */
895 rvm_bool_t prev_direction; /* last scanning direction */
896 rvm_bool_t split_ok; /* ok to process split records */
897} log_buf_t;
898
899/* log buffer management defs */
901#define SYNCH rvm_true /* synchronization required */
902#define NO_SYNCH rvm_false /* synchronization not required */
903/* log truncation daemon control structures */
905typedef enum
907 rvm_idle = 1000, /* daemon idle */
908 init_truncate, /* initiate truncation */
909 truncating, /* truncation in progress */
910 terminate, /* shutdown */
911 error /* terminated due to error */
914typedef struct {
915 cthread_t thread; /* daemon thread handle */
916 RVM_MUTEX lock; /* daemon lock -- protects following fields */
917 RVM_CONDITION code; /* condition code to signal daemon */
918 RVM_CONDITION flush_flag; /* condition code to signal flush */
919 RVM_CONDITION wake_up; /* condition code to signal threads
920 waiting for truncation completion */
921 daemon_state_t state; /* control state */
922 long truncate; /* truncation threshold, as % of log */
924
925/* log descriptor */
926typedef struct {
927 list_entry_t links; /* list links and struct id --
928 points to log list root */
929 long ref_cnt; /* count seg's using this log device */
931 RVM_MUTEX dev_lock; /* log device lock, protects device and
932 following i/o related fields: */
933 device_t dev; /* log device descriptor */
934 log_status_t status; /* log status area descriptor */
935 trans_hdr_t trans_hdr; /* i/o header for transaction log entry */
936 rec_end_t rec_end; /* i/o end marker for log entry */
937 log_wrap_t log_wrap; /* i/o log wrap-around marker */
938 log_buf_t log_buf; /* log recovery buffer */
939 /* end of log_dev_lock protected fields */
941 RVM_MUTEX tid_list_lock; /* lock for tid list header & links
942 used when adding/deleting a tid */
943 list_entry_t tid_list; /* root of active transaction list */
945 RVM_MUTEX flush_list_lock; /* lock for flush list header & links
946 used to add/delete a no_flush tid */
947 list_entry_t flush_list; /* list of no_flush committed tid's */
949 RVM_MUTEX special_list_lock; /* lock for special list header & links
950 used to add/delete a special entry */
951 list_entry_t special_list; /* list of special log entries */
953 rw_lock_t flush_lock; /* log flush synchronization */
954 log_daemon_t daemon; /* truncation daemon control */
955 RVM_MUTEX truncation_lock; /* truncation synchronization */
956 cthread_t trunc_thread;
957 rvm_bool_t in_recovery; /* true if in recovery */
959 struct seg_dict_s *seg_dict_vec; /* recovery segment dictionary */
960 long seg_dict_len; /* length of seg_dict_vec */
961 device_t *cur_seg_dev; /* current segment device in truncation */
962} log_t;
963
964/* segment descriptor: seg_t */
965typedef struct {
966 list_entry_t links; /* list links and struct id */
968 RVM_MUTEX dev_lock; /* device lock */
969 device_t dev; /* segment device descriptor */
970 long seg_code; /* short name for log entries */
971 log_t *log; /* log descriptor ptr */
973 RVM_MUTEX seg_lock; /* lock for seg lists: protects header
974 and links -- used when mapping or
975 unmapping a region */
976 list_entry_t map_list; /* mapped region list header */
977 list_entry_t unmap_list; /* unmapped region list header */
979 rvm_bool_t threads_waiting; /* at least one thread is waiting to
980 map a previously unmapped region */
981} seg_t;
982
983/* recovery dictionary segment descriptor: seg_dict_t */
985 struct_id_t struct_id; /* self-identifier */
986 seg_t *seg; /* ptr to real segment */
987 device_t dev; /* used in recovery only */
988 long seg_code; /* short segment id */
989 tree_root_t mod_tree; /* modification tree for recovery */
990};
992typedef struct seg_dict_s seg_dict_t;
994#define SEG_DICT_INDEX(x) ((x) - 1) /* index of segemnt in seg_dict_vec */
995/* region descriptor: region_t */
996typedef struct region_s {
997 list_entry_t links; /* list links and struct id --
998 protected by seg.map_lock or seg.unmap_lock */
999 rw_lock_t region_lock; /* rw lock for following fields */
1000 seg_t *seg; /* back ptr to segment */
1001 mem_region_t *mem_region; /* back ptr to region tree node */
1002 rvm_offset_t offset; /* offset of region base in segment */
1003 rvm_offset_t end_offset; /* offset of region end in segment */
1004 char *vmaddr; /* virtual memory base address */
1005 rvm_length_t length; /* length of region */
1006 rvm_bool_t no_copy; /* data not copied on map */
1008 RVM_MUTEX count_lock; /* accounting lock for next 2 fields */
1009 long n_uncommit; /* # uncommitted modifications in region */
1010 rvm_bool_t dirty; /* dirty bit; set by end_transaction */
1012 struct timeval unmap_ts; /* unmap timestamp for truncation chk */
1013} region_t;
1014
1015/* modification range descriptor: range_t */
1016typedef struct {
1017 tree_links_t links; /* tree links and struct id */
1018 char *data; /* old/new values, when used */
1019 rvm_length_t data_len; /* allocation length of data buffer */
1020 char *nvaddr; /* address of saved new values */
1021 region_t *region; /* back ptr to affected region */
1022 rvm_offset_t end_offset; /* end byte of range */
1023 nv_range_t nv; /* nv range record header for i/o */
1024} range_t;
1025
1026/* transaction id descriptor: int_tid_t */
1027typedef struct {
1028 list_entry_t links; /* list links and struct id; protected
1029 by log tid_list_lock */
1030 rw_lock_t tid_lock; /* remaining fields protected by
1031 tid_lock until on flush list*/
1032 struct timeval uname; /* unique identifier */
1033 struct timeval commit_stamp; /* timestamp of commit */
1034 log_t *log; /* back link to log descriptor */
1035 rvm_offset_t log_size; /* log space required */
1036 tree_root_t range_tree; /* range tree root */
1037 range_t **x_ranges; /* vector of overlapping ranges */
1038 long x_ranges_alloc; /* allocated length of x_ranges */
1039 long x_ranges_len; /* current length of x_ranges */
1040 rvm_length_t range_elim; /* ranges eliminated by range coalesce */
1041 rvm_length_t trans_elim; /* ranges eliminated by trans coalesce */
1042 rvm_offset_t range_overlap; /* overlap eliminated by range coalesce */
1043 rvm_offset_t trans_overlap; /* overlap eliminated by trans coalesce */
1044 rvm_length_t n_coalesced; /* count of coalesced transactions */
1045 range_t split_range; /* extra range for flush */
1046 rvm_length_t flags; /* mode and optimization flags */
1047 rvm_length_t back_link; /* displacement to previous header */
1048} int_tid_t;
1049
1050/* definitions for tid flags field (also used in trans_hdr flags field */
1051#define RESTORE_FLAG (2 * RVM_COALESCE_TRANS)
1052#define FLUSH_FLAG (2 * RESTORE_FLAG)
1053#define FIRST_ENTRY_FLAG (2 * FLUSH_FLAG)
1054#define LAST_ENTRY_FLAG (2 * FIRST_ENTRY_FLAG)
1055#define FLUSH_MARK (2 * LAST_ENTRY_FLAG)
1057#define TID(x) ((tid->flags & (x)) != 0)
1058#define TRANS_HDR(x) ((trans_hdr->flags & (x)) != 0)
1059/* functions and structures for managing list of RVM-allocated
1060 regions of memory (added by tilt, Nov 19 1996) */
1062typedef struct rvm_page_entry {
1063 char *start;
1064 char *end;
1068
1069rvm_bool_t rvm_register_page(char *vmaddr, rvm_length_t length);
1070rvm_bool_t rvm_unregister_page(char *vmaddr, rvm_length_t length);
1071
1072/* list management functions [rvm_utils.c] */
1073void init_list_header(list_entry_t *whichlist, struct_id_t struct_id);
1075 list_entry_t *cell);
1077void clear_free_lists(void);
1078
1079/* internal type allocators/deallocators [rvm_utils.c] */
1080region_t *make_region(void);
1082
1083seg_t *make_seg(char *seg_dev_name, rvm_return_t *retval);
1084void free_seg(seg_t *seg);
1085void free_seg_dict_vec(log_t *log);
1086
1087log_t *make_log(char *dev_name, rvm_return_t *retval);
1088void free_log(log_t *log);
1089char *make_full_name(char *dev_str, char *dev_name, rvm_return_t *retval);
1090
1092void free_log_special(log_special_t *special);
1093
1094rvm_return_t dev_init(device_t *dev, char *dev_str);
1095
1096range_t *make_range(void);
1097void free_range(range_t *range);
1098
1100void free_tid(int_tid_t *tid);
1101
1103void free_mem_region(mem_region_t *node);
1104
1106void free_dev_region(dev_region_t *node);
1107
1108/* log management functions [rvm_logstatus.c] */
1109void init_log_list(void);
1110void enter_log(log_t *log);
1111rvm_return_t open_log(char *dev_name, log_t **log_ptr, char *status_buf,
1112 rvm_options_t *rvm_options);
1113rvm_return_t create_log(log_t **log_ptr, rvm_options_t *rvm_options);
1114rvm_return_t do_log_options(log_t **log, rvm_options_t *rvm_options);
1117void copy_log_stats(log_t *log);
1118void clear_log_status(log_t *log);
1120rvm_return_t read_log_status(log_t *log, char *status_buf);
1123void log_tail_length(log_t *log, rvm_offset_t *tail_length);
1124void log_tail_sngl_w(log_t *log, rvm_offset_t *tail_length);
1125long cur_log_percent(log_t *log, rvm_offset_t *space_needed);
1126void cur_log_length(log_t *log, rvm_offset_t *length);
1127
1128/* [rvm_logflush.c] */
1131
1132/* [rvm_logrecovr.c] */
1134rvm_return_t init_buffer(log_t *log, rvm_offset_t *offset, rvm_bool_t direction,
1135 rvm_bool_t synch);
1136void clear_aux_buf(log_t *log);
1138 rvm_length_t *aux_ptr, rvm_length_t *data_len,
1139 rvm_bool_t direction, rvm_bool_t synch);
1140void reset_hdr_chks(log_t *log);
1141
1144 rvm_bool_t direction);
1145rvm_bool_t validate_hdr(log_t *log, rec_hdr_t *rec_hdr, rec_end_t *rec_end,
1146 rvm_bool_t direction);
1153rvm_return_t wait_for_truncation(log_t *log, struct timeval *time_stamp);
1154rvm_return_t log_recover(log_t *log, rvm_length_t *count, rvm_bool_t is_daemon,
1155 rvm_length_t flag);
1156void log_daemon(void * /* log_t *log */);
1158void free_log_buf(log_t *log);
1159
1160/* Segment & region management functions [rvm_map.c] */
1161void init_map_roots(void);
1163char *page_alloc(rvm_length_t len);
1164void page_free(char *vmaddr, rvm_length_t length);
1166seg_t *seg_lookup(char *dev_name, rvm_return_t *retval);
1169 rvm_offset_t *base2, rvm_offset_t *end2);
1171 rvm_offset_t *base2, rvm_offset_t *end2);
1172long mem_total_include(tree_node_t *tnode1, tree_node_t *tnode2);
1173region_t *find_whole_range(char *dest, rvm_length_t length,
1174 rw_lock_mode_t mode);
1175rvm_return_t rvm_map(rvm_region_t *rvm_region, rvm_options_t *rvm_options);
1176
1177/* segment dictionary functions [rvm_logrecovr.c] */
1178rvm_return_t enter_seg_dict(log_t *log, long seg_code);
1180
1181/* I/O functions [rvm_io.c] */
1182long open_dev(device_t *dev, long flags, long mode);
1183long close_dev(device_t *dev);
1184long read_dev(device_t *dev, rvm_offset_t *offset, char *dest,
1185 rvm_length_t length);
1186long write_dev(device_t *dev, rvm_offset_t *offset, char *src,
1187 rvm_length_t length, rvm_bool_t no_sync);
1188long sync_dev(device_t *dev);
1189long gather_write_dev(device_t *dev, rvm_offset_t *offset);
1190
1191/* length is optional */
1192long set_dev_char(device_t *dev, rvm_offset_t *dev_length);
1193
1194/* read/write lock [rvm_utils.c] */
1195void rw_lock(rw_lock_t *rwl, rw_lock_mode_t mode);
1196void rw_unlock(rw_lock_t *rwl, rw_lock_mode_t mode);
1197void init_rw_lock(rw_lock_t *rwl);
1198
1199void init_tree_root(tree_root_t *root);
1204 rvm_bool_t unlink);
1206 cmp_func_t *cmp);
1209
1210/* initialization, query, and structure checkers [rvm_init.c] */
1211rvm_bool_t bad_init(void);
1212
1213/* [rvm_status.c] */
1214rvm_return_t bad_options(rvm_options_t *rvm_options, rvm_bool_t chk_log_dev);
1216
1217/* [rvm_trans.c] */
1219
1220/* [rvm_status.c] */
1222
1223/* make unique name [rvm_utils.c] */
1224void make_uname(struct timeval *time);
1225long init_unames(void);
1226
1227/* time value arithmetic [rvm_utils.c] */
1228struct timeval add_times(struct timeval *x, struct timeval *y);
1229struct timeval sub_times(struct timeval *x, struct timeval *y);
1230long round_time(struct timeval *x);
1231
1232/* statistics gathering functions [rvm_utils] */
1233void enter_histogram(long val, rvm_length_t *histo, rvm_length_t *histo_def,
1234 long length);
1235
1236/* [rvm_utils.c] */
1237long init_utils(void);
1238
1239/* check summing and byte-aligned copy and pad functions [rvm_utils.c] */
1240rvm_length_t chk_sum(char *nvaddr, rvm_length_t len);
1241void src_aligned_bcopy(char *src, char *dest, rvm_length_t len);
1242void dest_aligned_bcopy(char *src, char *dest, rvm_length_t len);
1243
1244/* offset arithmetic */
1246
1247/* debug support [rvm_debug] */
1248void rvm_debug(rvm_length_t val);
1249
1250static inline void getpagesizeandmask(rvm_length_t *page_size,
1252{
1253#ifdef HAVE_MMAP
1254 /* get page size */
1256#else
1257 {
1258 SYSTEM_INFO nt_info;
1259 GetSystemInfo(&nt_info);
1260 *page_size = (rvm_length_t)nt_info.dwAllocationGranularity;
1261 }
1262#endif
1263 *page_mask = ~(*page_size - 1);
1264}
1265
1266#endif /* _RVM_PRIVATE_ */
long cthread_t
Definition: cthreads.h:99
level
Definition: make_certs.py:100
name
Definition: pwdtopdbtool.py:40
y
Definition: pwdtopdbtool.py:40
x
Definition: pwdtopdbtool.py:40
void(* type)()
Definition: rp2main.c:424
int rvm_return_t
Definition: rvm.h:94
#define RVM_VERSION_MAX
Definition: rvm.h:32
rvm_bool_t
Definition: rvm.h:60
rvm_mode_t
Definition: rvm.h:82
unsigned long rvm_length_t
Definition: rvm.h:140
rvm_length_t page_size
Definition: rvm_map.c:67
rvm_length_t page_mask
Definition: rvm_map.c:68
void log_daemon(void *)
Definition: rvm_logrecovr.c:2746
void init_list_header(list_entry_t *whichlist, struct_id_t struct_id)
Definition: rvm_utils.c:93
long read_dev(device_t *dev, rvm_offset_t *offset, char *dest, rvm_length_t length)
Definition: rvm_io.c:226
rvm_return_t open_log(char *dev_name, log_t **log_ptr, char *status_buf, rvm_options_t *rvm_options)
Definition: rvm_logstatus.c:325
rvm_return_t create_log(log_t **log_ptr, rvm_options_t *rvm_options)
rvm_return_t define_all_segs(log_t *log)
Definition: rvm_map.c:530
region_t * make_region(void)
Definition: rvm_utils.c:365
rvm_bool_t rvm_register_page(char *vmaddr, rvm_length_t length)
Definition: rvm_map.c:165
rvm_return_t queue_special(log_t *log, log_special_t *special)
Definition: rvm_logflush.c:667
struct region_s region_t
range_t * make_range(void)
Definition: rvm_utils.c:694
struct_id_t
Definition: rvm_private.h:168
@ log_id
Definition: rvm_private.h:172
@ int_tid_id
Definition: rvm_private.h:173
@ range_id
Definition: rvm_private.h:175
@ options_rvm_id
Definition: rvm_private.h:179
@ mem_region_id
Definition: rvm_private.h:181
@ tid_rvm_id
Definition: rvm_private.h:174
@ struct_last_cache_id
Definition: rvm_private.h:185
@ region_rvm_id
Definition: rvm_private.h:178
@ dev_region_id
Definition: rvm_private.h:182
@ seg_id
Definition: rvm_private.h:176
@ log_dev_status_id
Definition: rvm_private.h:190
@ log_status_id
Definition: rvm_private.h:189
@ trans_hdr_id
Definition: rvm_private.h:194
@ log_special_id
Definition: rvm_private.h:183
@ nv_range_id
Definition: rvm_private.h:196
@ struct_first_id
Definition: rvm_private.h:169
@ seg_dict_id
Definition: rvm_private.h:193
@ free_page_id
Definition: rvm_private.h:198
@ tree_root_id
Definition: rvm_private.h:200
@ struct_last_id
Definition: rvm_private.h:202
@ log_seg_id
Definition: rvm_private.h:192
@ statistics_rvm_id
Definition: rvm_private.h:180
@ region_id
Definition: rvm_private.h:177
@ rw_qentry_id
Definition: rvm_private.h:199
@ log_wrap_id
Definition: rvm_private.h:191
@ nv_buf_id
Definition: rvm_private.h:197
@ rec_end_id
Definition: rvm_private.h:195
rvm_return_t rvm_map(rvm_region_t *rvm_region, rvm_options_t *rvm_options)
Definition: rvm_map.c:922
void free_range(range_t *range)
Definition: rvm_utils.c:712
rvm_return_t scan_nv_forward(log_t *log, rvm_bool_t synch)
Definition: rvm_logrecovr.c:648
tree_node_t * tree_predecessor(tree_root_t *tree)
Definition: rvm_utils.c:1970
rvm_return_t validate_rec_reverse(log_t *log, rvm_bool_t synch)
Definition: rvm_logrecovr.c:922
void clear_free_lists(void)
Definition: rvm_utils.c:266
rvm_return_t enter_seg_dict(log_t *log, long seg_code)
Definition: rvm_logrecovr.c:1375
long cur_log_percent(log_t *log, rvm_offset_t *space_needed)
Definition: rvm_logstatus.c:954
rvm_return_t read_log_status(log_t *log, char *status_buf)
Definition: rvm_logstatus.c:653
void init_rw_lock(rw_lock_t *rwl)
Definition: rvm_utils.c:1194
#define RVM_MUTEX
Definition: rvm_private.h:385
void init_map_roots(void)
Definition: rvm_map.c:80
struct tree_node_s tree_node_t
rvm_return_t scan_reverse(log_t *log, rvm_bool_t synch)
Definition: rvm_logrecovr.c:997
void cur_log_length(log_t *log, rvm_offset_t *length)
Definition: rvm_logstatus.c:939
long open_dev(device_t *dev, long flags, long mode)
Definition: rvm_io.c:177
seg_t * make_seg(char *seg_dev_name, rvm_return_t *retval)
Definition: rvm_utils.c:459
#define RVM_CONDITION
Definition: rvm_private.h:386
rvm_return_t flush_log(log_t *log, rvm_length_t *count)
Definition: rvm_logflush.c:569
long gather_write_dev(device_t *dev, rvm_offset_t *offset)
Definition: rvm_io.c:483
struct timeval add_times(struct timeval *x, struct timeval *y)
Definition: rvm_utils.c:328
void copy_log_stats(log_t *log)
Definition: rvm_logstatus.c:465
rvm_return_t dev_init(device_t *dev, char *dev_str)
Definition: rvm_utils.c:430
void dest_aligned_bcopy(char *src, char *dest, rvm_length_t len)
Definition: rvm_utils.c:1183
rvm_return_t load_aux_buf(log_t *log, rvm_offset_t *offset, rvm_length_t length, rvm_length_t *aux_ptr, rvm_length_t *data_len, rvm_bool_t direction, rvm_bool_t synch)
Definition: rvm_logrecovr.c:392
void free_region(region_t *region)
Definition: rvm_utils.c:377
rvm_return_t bad_statistics(rvm_statistics_t *rvm_statistics)
Definition: rvm_status.c:81
long dev_partial_include(rvm_offset_t *base1, rvm_offset_t *end1, rvm_offset_t *base2, rvm_offset_t *end2)
Definition: rvm_map.c:594
rvm_return_t init_log_status(log_t *log)
Definition: rvm_logstatus.c:562
void enter_histogram(long val, rvm_length_t *histo, rvm_length_t *histo_def, long length)
Definition: rvm_utils.c:2096
tree_root_t region_tree
Definition: rvm_map.c:63
rvm_return_t do_log_options(log_t **log, rvm_options_t *rvm_options)
Definition: rvm_logstatus.c:415
rvm_return_t bad_region(rvm_region_t *rvm_region)
Definition: rvm_map.c:95
rvm_return_t init_buffer(log_t *log, rvm_offset_t *offset, rvm_bool_t direction, rvm_bool_t synch)
Definition: rvm_logrecovr.c:178
traverse_state_t
Definition: rvm_private.h:466
@ gtr
Definition: rvm_private.h:469
@ init
Definition: rvm_private.h:470
@ self
Definition: rvm_private.h:468
@ lss
Definition: rvm_private.h:467
daemon_state_t
Definition: rvm_private.h:905
@ rvm_idle
Definition: rvm_private.h:906
@ terminate
Definition: rvm_private.h:909
@ init_truncate
Definition: rvm_private.h:907
@ error
Definition: rvm_private.h:910
@ truncating
Definition: rvm_private.h:908
long close_dev(device_t *dev)
Definition: rvm_io.c:203
seg_t * seg_lookup(char *dev_name, rvm_return_t *retval)
Definition: rvm_map.c:475
void page_free(char *vmaddr, rvm_length_t length)
Definition: rvm_map.c:365
rvm_length_t chk_sum(char *nvaddr, rvm_length_t len)
Definition: rvm_utils.c:1144
tree_node_t * tree_successor(tree_root_t *tree)
Definition: rvm_utils.c:1907
tree_node_t * tree_iterate_insert(tree_root_t *tree, tree_node_t *node, cmp_func_t *cmp)
Definition: rvm_utils.c:2052
rw_lock_mode_t
Definition: rvm_private.h:413
@ r
Definition: rvm_private.h:414
@ f
Definition: rvm_private.h:416
@ w
Definition: rvm_private.h:415
long round_time(struct timeval *x)
Definition: rvm_utils.c:356
long dev_total_include(rvm_offset_t *base1, rvm_offset_t *end1, rvm_offset_t *base2, rvm_offset_t *end2)
Definition: rvm_map.c:606
struct list_entry_s list_entry_t
dev_region_t * make_dev_region(void)
Definition: rvm_utils.c:805
rvm_bool_t bad_init(void)
Definition: rvm_init.c:41
#define getpagesize()
Definition: rvm_private.h:47
rvm_return_t close_all_segs(void)
Definition: rvm_map.c:449
rvm_bool_t chk_hdr_sequence(log_t *log, rec_hdr_t *rec_hdr, rvm_bool_t direction)
Definition: rvm_logrecovr.c:544
void log_tail_sngl_w(log_t *log, rvm_offset_t *tail_length)
Definition: rvm_logstatus.c:917
rvm_return_t wait_for_truncation(log_t *log, struct timeval *time_stamp)
Definition: rvm_logrecovr.c:2693
void src_aligned_bcopy(char *src, char *dest, rvm_length_t len)
Definition: rvm_utils.c:1174
long cmp_func_t(tree_node_t *node1, tree_node_t *node2)
Definition: rvm_private.h:559
void free_seg_dict_vec(log_t *log)
Definition: rvm_utils.c:511
rvm_bool_t rvm_unregister_page(char *vmaddr, rvm_length_t length)
Definition: rvm_map.c:263
void log_tail_length(log_t *log, rvm_offset_t *tail_length)
Definition: rvm_logstatus.c:890
void rw_lock(rw_lock_t *rwl, rw_lock_mode_t mode)
Definition: rvm_utils.c:1215
log_t * make_log(char *dev_name, rvm_return_t *retval)
Definition: rvm_utils.c:576
int_tid_t * make_tid(rvm_mode_t mode)
Definition: rvm_utils.c:729
rvm_return_t def_seg_dict(log_t *log, rec_hdr_t *rec_hdr)
Definition: rvm_logrecovr.c:1406
long mem_total_include(tree_node_t *tnode1, tree_node_t *tnode2)
Definition: rvm_map.c:641
struct rvm_page_entry rvm_page_entry_t
rvm_return_t write_log_status(log_t *log, device_t *dev)
Definition: rvm_logstatus.c:706
void free_mem_region(mem_region_t *node)
Definition: rvm_utils.c:794
void reset_hdr_chks(log_t *log)
Definition: rvm_logrecovr.c:535
rvm_return_t log_recover(log_t *log, rvm_length_t *count, rvm_bool_t is_daemon, rvm_length_t flag)
Definition: rvm_logrecovr.c:2483
tree_node_t * init_tree_generator(tree_root_t *tree, rvm_bool_t direction, rvm_bool_t unlink)
Definition: rvm_utils.c:2033
char * make_full_name(char *dev_str, char *dev_name, rvm_return_t *retval)
Definition: rvm_utils.c:388
rvm_return_t update_log_tail(log_t *log, rec_hdr_t *rec_hdr)
Definition: rvm_logstatus.c:817
void clear_aux_buf(log_t *log)
Definition: rvm_logrecovr.c:493
rvm_return_t close_log(log_t *log)
Definition: rvm_logstatus.c:234
rvm_return_t close_all_logs(void)
Definition: rvm_logstatus.c:286
rvm_return_t scan_wrap_reverse(log_t *log, rvm_bool_t synch)
Definition: rvm_logrecovr.c:868
void make_uname(struct timeval *time)
Definition: rvm_utils.c:279
void rvm_monitor_call_t()
Definition: rvm_private.h:116
rvm_offset_t rvm_rnd_offset_to_sector(rvm_offset_t *x)
Definition: rvm_utils.c:2217
void free_log_special(log_special_t *special)
Definition: rvm_utils.c:674
list_entry_t * alloc_list_entry(struct_id_t id)
Definition: rvm_utils.c:201
char * page_alloc(rvm_length_t len)
Definition: rvm_map.c:325
list_entry_t * move_list_entry(list_entry_t *fromptr, list_entry_t *toptr, list_entry_t *cell)
Definition: rvm_utils.c:130
rvm_return_t bad_options(rvm_options_t *rvm_options, rvm_bool_t chk_log_dev)
Definition: rvm_status.c:91
rvm_return_t bad_tid(rvm_tid_t *rvm_tid)
Definition: rvm_trans.c:42
struct timeval sub_times(struct timeval *x, struct timeval *y)
Definition: rvm_utils.c:341
rvm_bool_t validate_hdr(log_t *log, rec_hdr_t *rec_hdr, rec_end_t *rec_end, rvm_bool_t direction)
Definition: rvm_logrecovr.c:603
rvm_bool_t tree_insert(tree_root_t *tree, tree_node_t *node, cmp_func_t *cmp)
Definition: rvm_utils.c:1542
rvm_bool_t initiate_truncation(log_t *log, rvm_length_t threshold)
Definition: rvm_logrecovr.c:2666
long init_unames(void)
Definition: rvm_utils.c:293
void free_seg(seg_t *seg)
Definition: rvm_utils.c:483
void rw_unlock(rw_lock_t *rwl, rw_lock_mode_t mode)
Definition: rvm_utils.c:1270
mem_region_t * make_mem_region(void)
Definition: rvm_utils.c:782
rvm_bool_t chk_hdr_currency(log_t *log, rec_hdr_t *rec_hdr)
Definition: rvm_logrecovr.c:517
log_special_t * make_log_special(struct_id_t special_id, rvm_length_t length)
Definition: rvm_utils.c:644
void enter_log(log_t *log)
Definition: rvm_logstatus.c:105
rvm_bool_t rvm_signal_call_t()
Definition: rvm_private.h:113
rvm_return_t alloc_log_buf(log_t *log)
Definition: rvm_logrecovr.c:119
long sync_dev(device_t *dev)
Definition: rvm_io.c:508
long write_dev(device_t *dev, rvm_offset_t *offset, char *src, rvm_length_t length, rvm_bool_t no_sync)
Definition: rvm_io.c:285
tree_node_t * tree_lookup(tree_root_t *tree, tree_node_t *node, cmp_func_t *cmp)
Definition: rvm_utils.c:1422
void free_log(log_t *log)
Definition: rvm_utils.c:527
rw_lock_t region_tree_lock
Definition: rvm_map.c:62
void free_tid(int_tid_t *tid)
Definition: rvm_utils.c:757
void free_dev_region(dev_region_t *node)
Definition: rvm_utils.c:820
void init_tree_root(tree_root_t *root)
Definition: rvm_utils.c:1363
rvm_return_t do_rvm_options(rvm_options_t *rvm_options)
Definition: rvm_status.c:106
region_t * find_whole_range(char *dest, rvm_length_t length, rw_lock_mode_t mode)
Definition: rvm_map.c:670
rvm_return_t scan_forward(log_t *log, rvm_bool_t synch)
Definition: rvm_logrecovr.c:813
long init_utils(void)
Definition: rvm_utils.c:315
void init_log_list(void)
Definition: rvm_logstatus.c:90
long set_dev_char(device_t *dev, rvm_offset_t *dev_length)
Definition: rvm_io.c:119
void rvm_debug(rvm_length_t val)
Definition: rvm_debug.c:73
rvm_bool_t tree_delete(tree_root_t *tree, tree_node_t *node, cmp_func_t *cmp)
Definition: rvm_utils.c:1745
void clear_log_status(log_t *log)
Definition: rvm_logstatus.c:536
void free_log_buf(log_t *log)
Definition: rvm_logrecovr.c:157
rvm_return_t locate_tail(log_t *log)
Definition: rvm_logrecovr.c:1178
#define trans_coalesces_len
Definition: rvm_statistics.h:63
#define range_overlaps_len
Definition: rvm_statistics.h:47
#define flush_times_len
Definition: rvm_statistics.h:35
#define range_elims_len
Definition: rvm_statistics.h:57
rvm_return_t rvm_statistics(const char *version, rvm_statistics_t *statistics)
Definition: rvm_status.c:250
#define range_lengths_len
Definition: rvm_statistics.h:43
#define truncation_times_len
Definition: rvm_statistics.h:39
#define trans_elims_len
Definition: rvm_statistics.h:60
struct QUEUE queue
Definition: rvm_private.h:105
unsigned long format
Definition: rvm_private.h:108
int radix
Definition: rvm_private.h:109
char * vmaddr
Definition: rvm_private.h:106
rvm_length_t length
Definition: rvm_private.h:107
Definition: rvm_private.h:539
Definition: rvm_private.h:643
Definition: codamergedump.cc:54
Definition: rvm_private.h:353
Definition: histo.h:34
Definition: rvm_private.h:1026
Definition: rvm_private.h:318
long length
Definition: rvm_private.h:323
rvm_bool_t is_hdr
Definition: rvm_private.h:326
struct_id_t struct_id
Definition: rvm_private.h:325
union list_entry_s::@54 list
struct list_entry_s * name
Definition: rvm_private.h:322
struct list_entry_s * preventry
Definition: rvm_private.h:320
struct list_entry_s * nextentry
Definition: rvm_private.h:319
Definition: rvm_private.h:877
Definition: rvm_private.h:913
Definition: rvm_private.h:842
Definition: rvm_private.h:606
Definition: rvm_private.h:617
Definition: rvm_private.h:713
Definition: rvm_private.h:925
Definition: rvm_private.h:637
Definition: rvm_private.h:551
Definition: cthreads.h:46
Definition: rvm_private.h:527
Definition: rvm_private.h:585
Definition: rvm_private.h:1015
Definition: rvm_private.h:629
Definition: rvm_private.h:566
Definition: rvm_private.h:995
seg_t * seg
Definition: rvm_private.h:999
list_entry_t links
Definition: rvm_private.h:996
rw_lock_t region_lock
Definition: rvm_private.h:998
rvm_length_t length
Definition: rvm_private.h:1004
rvm_bool_t dirty
Definition: rvm_private.h:1009
rvm_offset_t end_offset
Definition: rvm_private.h:1002
mem_region_t * mem_region
Definition: rvm_private.h:1000
rvm_bool_t no_copy
Definition: rvm_private.h:1005
RVM_MUTEX count_lock
Definition: rvm_private.h:1007
rvm_offset_t offset
Definition: rvm_private.h:1001
struct timeval unmap_ts
Definition: rvm_private.h:1011
long n_uncommit
Definition: rvm_private.h:1008
char * vmaddr
Definition: rvm_private.h:1003
Definition: rvm.h:145
Definition: rvm.h:269
Definition: rvm_private.h:1061
char * end
Definition: rvm_private.h:1063
struct rvm_page_entry * next
Definition: rvm_private.h:1065
char * start
Definition: rvm_private.h:1062
struct rvm_page_entry * prev
Definition: rvm_private.h:1064
Definition: rvm.h:319
Definition: rvm_statistics.h:67
Definition: rvm.h:251
Definition: rvm_private.h:420
Definition: rvm_private.h:429
Definition: rvm_private.h:983
seg_t * seg
Definition: rvm_private.h:985
tree_root_t mod_tree
Definition: rvm_private.h:988
long seg_code
Definition: rvm_private.h:987
device_t dev
Definition: rvm_private.h:986
struct_id_t struct_id
Definition: rvm_private.h:984
Definition: rvm_private.h:964
Definition: rvm_private.h:575
Definition: rvm_private.h:453
struct tree_node_s * lss
Definition: rvm_private.h:454
struct_id_t struct_id
Definition: rvm_private.h:457
struct tree_node_s * gtr
Definition: rvm_private.h:455
long bf
Definition: rvm_private.h:456
Definition: rvm_private.h:474
Definition: rvm_private.h:480
rvm_region_t * region
Definition: testrvm.c:34
rvm_bool_t in_recovery
Definition: testrvm.c:35