1 /* BLURB lgpl 2 3 Coda File System 4 Release 5 5 6 Copyright (c) 1987-1999 Carnegie Mellon University 7 Additional copyrights listed below 8 9 This code is distributed "AS IS" without warranty of any kind under 10 the terms of the GNU Library General Public Licence Version 2, as 11 shown in the file LICENSE. The technical and financial contributors to 12 Coda are listed in the file CREDITS. 13 14 Additional copyrights 15 none currently 16 17 #*/ 18 19 /* 20 * Definitions for RVM 21 * 22 * 23 */ 24 25 /*LINTLIBRARY*/ 26 27 /* permit multiple includes */ 28 #ifndef RVM_VERSION 29 30 /* Version string for initialization */ 31 #define RVM_VERSION "RVM Interface Version 1.3 7 Mar 1994" 32 #define RVM_VERSION_MAX 128 /* 128 char maximum version str length */ 33 34 /* be sure parallel libraries are used */ 35 #ifndef _PARALLEL_LIBRARIES 36 #define _PARALLEL_LIBRARIES 1 37 #endif 38 39 /* get timestamp structures and system constants */ 40 #include <sys/time.h> 41 #include <sys/param.h> 42 43 /* define bool, TRUE, and FALSE */ 44 45 #ifndef TRUE 46 #define TRUE 1 47 #endif 48 49 #ifndef FALSE 50 #define FALSE 0 51 #endif 52 53 /* RVM's use of false, true and bool causes trouble with versions of gcc 54 above 2.6 or so; because of this, the names of RVM's definitions 55 have been changed to rvm_{false,true,bool_t}. (Originally changed 56 in rvm.h by Satya (7/31/96); propogated to the rest of the RVM code 57 8/23/96 by tilt */ 58 59 typedef enum { rvm_false = 0, rvm_true = 1 } rvm_bool_t; 60 61 /* structure identifiers: rvm_struct_id_t 62 codes placed in the first field of each 63 structure instance to identify the object. 64 */ 65 typedef enum 66 { 67 rvm_first_struct_id = 39, /* internal use only */ 68 69 rvm_region_id, /* identifier for rvm_region's */ 70 rvm_options_id, /* identifier for rvm_options */ 71 rvm_tid_id, /* identifier for rvm_tid's */ 72 rvm_statistics_id, /* identifier for rvm_statistics rec's */ 73 rvm_last_struct_id /* internal use only */ 74 } 75 rvm_struct_id_t; 76 77 /* Transaction mode codes: rvm_mode_t */ 78 typedef enum 79 { 80 rvm_first_mode = 139, /* internal use only */ 81 82 restore, /* restore memory on abort */ 83 no_restore, /* do not restore memory on abort */ 84 flush, /* flush records to logdev on commit */ 85 no_flush, /* do not flush records on commit */ 86 87 rvm_last_mode /* internal use only */ 88 } 89 rvm_mode_t; 90 91 /* Function return codes: rvm_return_t */ 92 typedef int rvm_return_t; 93 #define RVM_SUCCESS 0 /* success return code */ 94 #define rvm_first_code 199 /* internal use only */ 95 #define RVM_EINIT 200 /* RVM not initialized */ 96 #define RVM_EINTERNAL 201 /* internal error, see rvm_errmsg */ 97 #define RVM_EIO 202 /* I/O error, see errno */ 98 #define RVM_ELOG 204 /* invalid log device */ 99 #define RVM_ELOG_VERSION_SKEW 205 /* RVM log format version skew */ 100 #define RVM_EMODE 206 /* invalid transaction begin/end mode */ 101 #define RVM_ENAME_TOO_LONG 207 /* device name longer than 1023 chars */ 102 #define RVM_ENO_MEMORY 208 /* heap exhausted */ 103 #define RVM_ENOT_MAPPED 209 /* designated region not mapped */ 104 #define RVM_EOFFSET 210 /* invalid segment offset */ 105 #define RVM_EOPTIONS 211 /* invalid options record or pointer */ 106 #define RVM_EOVERLAP 212 /* region overlaps existing seg mapping */ 107 #define RVM_EPAGER 213 /* invalid external pager */ 108 #define RVM_ERANGE 214 /* invalid virtual memory address */ 109 #define RVM_EREGION 215 /* invalid region descriptor or pointer */ 110 #define RVM_EREGION_DEF 216 /* invalid region definition descriptor */ 111 #define RVM_ESRC 217 /* invalid address range for new values */ 112 #define RVM_ESTATISTICS 218 /* invalid statistics record */ 113 #define RVM_ESTAT_VERSION_SKEW 219 /* RVM statistics format version skew */ 114 #define RVM_ETERMINATED 220 /* terminated by error already reported */ 115 #define RVM_ETHREADS 221 /* illegal C Thread library */ 116 #define RVM_ETID 222 /* invalid transaction identifier or ptr */ 117 #define RVM_ETOO_BIG 223 /* internal resouces exceeded */ 118 #define RVM_EUNCOMMIT 224 /* uncommitted transaction(s) pending */ 119 #define RVM_EVERSION_SKEW 225 /* RVM library version skew */ 120 #define RVM_EVM_OVERLAP 226 /* region overlaps existing vm mapping */ 121 #define rvm_last_code 227 /* internal use only */ 122 123 /* Enumeration type print name functions */ 124 extern char *rvm_return(rvm_return_t code); 125 extern char *rvm_mode(rvm_mode_t mode); 126 extern char *rvm_type(rvm_struct_id_t id); 127 128 129 /* RVM basic length and offset types: 130 these types are used throughout RVM to hide machine-dependent 131 representations of maximum virtual memory region lengths and 132 64 bit offsets. Do not use internal types or fields or 133 portability can be compromised 134 */ 135 /* region length: rvm_length_t 136 size must be >= sizeof(char *), 137 type must be unsigned arithmetic */ 138 139 typedef unsigned long rvm_length_t; 140 141 /* region offset descriptor: rvm_offset_t supports 64 bit unsigned integers 142 struct unecessary if machine has 64-bit ops */ 143 144 typedef struct 145 { /* INTERNAL FIELDS static */ 146 rvm_length_t high; /* private */ 147 rvm_length_t low; /* private */ 148 } 149 rvm_offset_t; 150 151 /* construct offset from two rvm_length_t sized quantities x,y 152 -- this will construct an offset from two lengths even if 153 8*sizeof(rvm_length_t) is > sizeof(rvm_offset_t); the "extra" 154 bits, the highest order bits of parameter y, will be discarded */ 155 #define RVM_MK_OFFSET(x,y) rvm_mk_offset((rvm_length_t)(x), \ 156 (rvm_length_t)(y)) 157 158 /* offset initializer -- same as RVM_MK_OFFSET, but compile time */ 159 #define RVM_OFFSET_INITIALIZER(x,y) {(x),(y)} 160 161 /* Zero an offset: create a zero offset and assign it to the parameter. */ 162 #define RVM_ZERO_OFFSET(x) (x) = RVM_MK_OFFSET(0,0) 163 164 /* offset and length conversion macros */ 165 166 /* return low-order bits of offset x as length 167 -- "low-order bits" are the lowest numerically valued bits 168 of the same size as rvm_length_t */ 169 #define RVM_OFFSET_TO_LENGTH(x) ((x).low) 170 171 /* return high order bits of offset x as length 172 -- "high-order bits" are defined as the highest ordered 173 bits remaining after the low-order bits are extracted 174 they are returned as rvm_length_t */ 175 #define RVM_OFFSET_HIGH_BITS_TO_LENGTH(x) ((x).high) 176 177 /* return length x as rvm_offset_t */ 178 #define RVM_LENGTH_TO_OFFSET(x) RVM_MK_OFFSET(0,(x)) 179 180 /* rvm_offset_t and rvm_length_t arithmetic support */ 181 182 /* add rvm_offset to rvm_offset; returns result (x+y) 183 implemented as function call -- or simple add if 184 machine has 64-bit integer operations */ 185 #define RVM_ADD_OFFSETS(x,y) \ 186 rvm_add_offsets(&(x),&(y)) 187 188 /* add rvm_length to rvm_offset; return result (length+offset) 189 as rvm_offset_t 190 implemented as function call -- or simple add if 191 machine has 64-bit integer operations */ 192 #define RVM_ADD_LENGTH_TO_OFFSET(x,y) \ 193 rvm_add_length_to_offset(&(x),(y)) 194 195 /* add rvm_length_t to vm address; returns address (char *) 196 always implemented as simple add */ 197 #define RVM_ADD_LENGTH_TO_ADDR(length,vmaddr) \ 198 ((char *)((rvm_length_t)(length)+(rvm_length_t)(vmaddr))) 199 200 /* subtract rvm_offset from rvm_offset; return result (x-y) as rvm_offset_t 201 implemented as function call -- or simple subtract if 202 machine has 64-bit integer operations */ 203 #define RVM_SUB_OFFSETS(x,y) \ 204 rvm_sub_offsets(&(x),&(y)) 205 206 /* subtract rvm_length from rvm_offset; return result (offset-length) 207 as rvm_offset_t 208 implemented as function call or simple subtract if 209 machine has 64-bit integer operations */ 210 #define RVM_SUB_LENGTH_FROM_OFFSET(x,y) \ 211 rvm_sub_length_from_offset(&(x),(y)) 212 213 /* subtract rvm_length_t from vm address; returns address (char *) 214 always implemented as simple subtract */ 215 #define RVM_SUB_LENGTH_FROM_ADDR(vmaddr,length) \ 216 ((char *)((rvm_length_t)(vmaddr)-(rvm_length_t)(length))) 217 218 /* rvm_offset_t comparison macros */ 219 #define RVM_OFFSET_LSS(x,y) (((x).high < (y).high) || \ 220 ((((x).high == (y).high) && \ 221 ((x).low < (y).low)))) 222 #define RVM_OFFSET_GTR(x,y) (((x).high > (y).high) || \ 223 ((((x).high == (y).high) && \ 224 ((x).low > (y).low)))) 225 #define RVM_OFFSET_LEQ(x,y) (!RVM_OFFSET_GTR((x),(y))) 226 #define RVM_OFFSET_GEQ(x,y) (!RVM_OFFSET_LSS((x),(y))) 227 #define RVM_OFFSET_EQL(x,y) (((x).high == (y).high) && \ 228 ((x).low == (y).low)) 229 #define RVM_OFFSET_EQL_ZERO(x) (((x).high == 0) && ((x).low == 0)) 230 231 /* page-size rounding macros */ 232 233 /* return page size as rvm_length_t */ 234 #define RVM_PAGE_SIZE rvm_page_size() 235 236 /* return rvm_length x rounded up to next integral page-size length */ 237 #define RVM_ROUND_LENGTH_UP_TO_PAGE_SIZE(x) ((rvm_length_t)( \ 238 ((rvm_length_t)(x)+rvm_page_size()-1) & rvm_page_mask())) 239 240 /* return rvm_length x rounded down to integral page-size length */ 241 #define RVM_ROUND_LENGTH_DOWN_TO_PAGE_SIZE(x) ((rvm_length_t)( \ 242 (rvm_length_t)(x) & rvm_page_mask())) 243 244 /* return address x rounded up to next page boundary */ 245 #define RVM_ROUND_ADDR_UP_TO_PAGE_SIZE(x) ((char *)( \ 246 ((rvm_length_t)(x)+rvm_page_size()-1) & rvm_page_mask())) 247 248 /* return address x rounded down to page boundary */ 249 #define RVM_ROUND_ADDR_DOWN_TO_PAGE_SIZE(x) ((char *)( \ 250 (rvm_length_t)(x) & rvm_page_mask())) 251 252 /* return rvm_offset x rounded up to next integral page-size offset */ 253 #define RVM_ROUND_OFFSET_UP_TO_PAGE_SIZE(x) \ 254 rvm_rnd_offset_up_to_page(&(x)) 255 256 /* return rvm_offset x rounded down to integral page-size offset */ 257 #define RVM_ROUND_OFFSET_DOWN_TO_PAGE_SIZE(x) \ 258 rvm_rnd_offset_dn_to_page(&(x)) 259 260 /* transaction identifier descriptor */ 261 typedef struct 262 { 263 rvm_struct_id_t struct_id; /* self-identifier, do not change */ 264 rvm_bool_t from_heap; /* true if heap allocated; 265 do not change */ 266 struct timeval uname; /* unique name (timestamp) */ 267 268 void *tid; /* internal use only */ 269 rvm_length_t reserved; /* internal use only */ 270 } 271 rvm_tid_t; 272 273 /* rvm_tid_t initializer, copier & finalizer */ 274 275 extern rvm_tid_t *rvm_malloc_tid (); 276 277 extern void rvm_init_tid(rvm_tid_t *tid); /* pointer to record to initialize */ 278 extern rvm_tid_t *rvm_copy_tid(rvm_tid_t *tid); /* pointer to record to be copied */ 279 extern void rvm_free_tid(rvm_tid_t *tid); /* pointer to record to be copied */ 280 281 /* options descriptor: rvm_options_t */ 282 typedef struct 283 { 284 rvm_struct_id_t struct_id; /* self-identifier, do not change */ 285 rvm_bool_t from_heap; /* true if heap allocated; 286 do not change */ 287 288 char *log_dev; /* device name */ 289 long truncate; /* truncation threshold, % of log */ 290 rvm_length_t recovery_buf_len; /* length of recovery buffer */ 291 rvm_length_t flush_buf_len; /* length of flush buffer (partitions only) */ 292 rvm_length_t max_read_len; /* maximum single read length */ 293 rvm_bool_t log_empty; /* TRUE ==> log empty */ 294 char *pager; /* char array for external pager name */ 295 long n_uncommit; /* length of uncommitted tid array */ 296 rvm_tid_t *tid_array; /* ptr to array of uncommitted tid's */ 297 298 rvm_length_t flags; /* bit vector for optimization and 299 other flags */ 300 rvm_bool_t create_log_file; /* TRUE ==> create the log file */ 301 rvm_offset_t create_log_size; /* when creating a new log file, this 302 is the wanted size */ 303 long create_log_mode; /* when creating a new log file, this 304 is the wanted mode */ 305 } 306 rvm_options_t; 307 308 /* rvm_options default values and other constants */ 309 310 #define TRUNCATE 50 /* 50% default truncation threshold */ 311 #define RECOVERY_BUF_LEN (256*1024) /* default recovery buffer length */ 312 #define MIN_RECOVERY_BUF_LEN (64*1024) /* minimum recovery buffer length */ 313 #define FLUSH_BUF_LEN (256*1024) /* default flush buffer length */ 314 #define MIN_FLUSH_BUF_LEN (64*1024) /* minimum flush buffer length */ 315 #define MAX_READ_LEN (512*1024) /* default maximum single read length */ 316 317 #define RVM_COALESCE_RANGES 1 /* coalesce adjacent or shadowed 318 ranges within a transaction */ 319 #define RVM_COALESCE_TRANS 2 /* coalesce adjacent or shadowed ranges 320 within no_flush transactions */ 321 322 #define RVM_ALL_OPTIMIZATIONS (RVM_COALESCE_RANGES | RVM_COALESCE_TRANS) 323 324 /* Other flags */ 325 326 #define RVM_MAP_PRIVATE 8 /* Use private mapping, if available */ 327 328 /* rvm_options_t initializer, copier & finalizer */ 329 330 extern rvm_options_t *rvm_malloc_options(); 331 332 extern void rvm_init_options(rvm_options_t *options); 333 extern rvm_options_t *rvm_copy_options(rvm_options_t *options); 334 extern void rvm_free_options(rvm_options_t *options); 335 336 /* region descriptor: rvm_region_t */ 337 typedef struct 338 { 339 rvm_struct_id_t struct_id; /* self-identifier, do not change */ 340 rvm_bool_t from_heap; /* true if heap allocated; 341 do not change */ 342 343 char *data_dev; /* device name */ 344 rvm_offset_t dev_length; /* maximum device length */ 345 rvm_offset_t offset; /* offset of region in segment */ 346 char *vmaddr; /* vm address of region/range */ 347 rvm_length_t length; /* length of region/range */ 348 rvm_bool_t no_copy; /* do not copy mapped data if true */ 349 } 350 rvm_region_t; 351 352 /* rvm_region_t allocator, initializer, copier & finalizer */ 353 extern rvm_region_t *rvm_malloc_region (); 354 extern void rvm_init_region(rvm_region_t *region); 355 /* note: copier copies pointers to the char arrays */ 356 extern rvm_region_t *rvm_copy_region(rvm_region_t *region); 357 extern void rvm_free_region(rvm_region_t *region); 358 359 /* 360 Main Function Declarations 361 */ 362 363 /* RVM initialization: pass version and optional options 364 descriptor */ 365 extern rvm_return_t rvm_initialize(const char *version, rvm_options_t *opts); 366 /* init macro */ 367 #define RVM_INIT(options) rvm_initialize(RVM_VERSION,(options)) 368 369 /* shutdown RVM */ 370 extern rvm_return_t rvm_terminate (void); /* no parameters */ 371 372 /* map recoverable storage */ 373 extern rvm_return_t rvm_map( 374 rvm_region_t *region, /* pointer to region descriptor */ 375 rvm_options_t *options /* optional ptr to option descriptor */ 376 ); 377 378 /* unmap recoverable storage */ 379 extern rvm_return_t rvm_unmap(rvm_region_t *region); 380 381 /* set RVM options */ 382 extern rvm_return_t rvm_set_options(rvm_options_t *options); 383 384 /* query RVM options */ 385 extern rvm_return_t rvm_query( 386 rvm_options_t *options, /* address of pointer to option 387 descriptor [out] */ 388 rvm_region_t *region /* optional pointer to region descriptor */ 389 ); 390 391 /* begin a transaction */ 392 extern rvm_return_t rvm_begin_transaction( 393 rvm_tid_t *tid, /* pointer to transaction identifier */ 394 rvm_mode_t mode /* transaction begin mode */ 395 ); 396 397 /* declare a modification region for a transaction */ 398 extern rvm_return_t rvm_set_range( 399 rvm_tid_t *tid, /* pointer to transaction identifier */ 400 void *dest, /* base address of modification range */ 401 rvm_length_t length /* length of modification range */ 402 ); 403 404 /* modification of a region for a transaction */ 405 extern rvm_return_t rvm_modify_bytes( 406 rvm_tid_t *tid, /* pointer to transaction identifier */ 407 void *dest, /* base address of modification range */ 408 const void *src, /* base address of source range */ 409 rvm_length_t length /* length of modification range */ 410 ); 411 412 /* abort a transaction */ 413 extern rvm_return_t rvm_abort_transaction( 414 rvm_tid_t *tid /* pointer to transaction identifier */ 415 ); 416 417 /* commit a transaction */ 418 extern rvm_return_t rvm_end_transaction( 419 rvm_tid_t *tid, /* pointer to transaction identifier */ 420 rvm_mode_t mode /* transaction commit mode */ 421 ); 422 423 /* flush log cache buffer to log device */ 424 extern rvm_return_t rvm_flush(); /* no parameters */ 425 426 /* apply logged changes to segments and garbage collect the log device */ 427 extern rvm_return_t rvm_truncate(); /* no parameters */ 428 429 /* initialize log */ 430 extern rvm_return_t rvm_create_log( 431 rvm_options_t *rvm_options, /* ptr to options record */ 432 rvm_offset_t *log_len, /* length of log data area */ 433 long mode /* file creation protection mode */ 434 ); 435 436 /* underlying support functions for length, offset, and rounding macros 437 438 *** use outside of the macros can compromise portability *** 439 440 these functions will not be implemented on machines with 64-bit 441 integer formats since their operations will be available in the 442 native instruction set 443 */ 444 extern rvm_offset_t rvm_mk_offset( 445 rvm_length_t x, 446 rvm_length_t y 447 ); 448 extern rvm_offset_t rvm_add_offsets( 449 rvm_offset_t *x, 450 rvm_offset_t *y 451 ); 452 extern rvm_offset_t rvm_add_length_to_offset( 453 rvm_offset_t *offset, 454 rvm_length_t length 455 ); 456 extern rvm_offset_t rvm_sub_offsets( 457 rvm_offset_t *x, 458 rvm_offset_t *y 459 ); 460 extern rvm_offset_t rvm_sub_length_from_offset( 461 rvm_offset_t *offset, 462 rvm_length_t length 463 ); 464 465 /* private functions to support page rounding */ 466 467 extern rvm_length_t rvm_page_size (); 468 extern rvm_length_t rvm_page_mask (); 469 extern rvm_offset_t rvm_rnd_offset_up_to_page(rvm_offset_t *x); 470 extern rvm_offset_t rvm_rnd_offset_dn_to_page(rvm_offset_t *x); 471 472 #endif /* RVM_VERSION */ 473