1 /* 2 * Copyright (c) 2007 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Matthew Dillon <dillon@backplane.com> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * $DragonFly: src/sys/vfs/hammer/hammer.h,v 1.47 2008/04/22 19:00:14 dillon Exp $ 35 */ 36 /* 37 * This header file contains structures used internally by the HAMMERFS 38 * implementation. See hammer_disk.h for on-disk structures. 39 */ 40 41 #include <sys/param.h> 42 #include <sys/types.h> 43 #include <sys/kernel.h> 44 #include <sys/conf.h> 45 #include <sys/systm.h> 46 #include <sys/tree.h> 47 #include <sys/malloc.h> 48 #include <sys/mount.h> 49 #include <sys/mountctl.h> 50 #include <sys/vnode.h> 51 #include <sys/proc.h> 52 #include <sys/globaldata.h> 53 #include <sys/lockf.h> 54 #include <sys/buf.h> 55 #include <sys/queue.h> 56 #include <sys/globaldata.h> 57 58 #include <sys/buf2.h> 59 #include <sys/signal2.h> 60 #include "hammer_disk.h" 61 #include "hammer_mount.h" 62 #include "hammer_ioctl.h" 63 64 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) 65 66 MALLOC_DECLARE(M_HAMMER); 67 68 struct hammer_mount; 69 70 /* 71 * Key structure used for custom RB tree inode lookups. This prototypes 72 * the function hammer_ino_rb_tree_RB_LOOKUP_INFO(root, info). 73 */ 74 typedef struct hammer_inode_info { 75 int64_t obj_id; /* (key) object identifier */ 76 hammer_tid_t obj_asof; /* (key) snapshot transid or 0 */ 77 } *hammer_inode_info_t; 78 79 /* 80 * HAMMER Transaction tracking 81 */ 82 struct hammer_transaction { 83 struct hammer_mount *hmp; 84 hammer_tid_t tid; 85 hammer_seq_t seq; 86 struct hammer_volume *rootvol; 87 /* TAILQ_HEAD(, hammer_io) recycle_list;*/ 88 }; 89 90 typedef struct hammer_transaction *hammer_transaction_t; 91 92 /* 93 * HAMMER locks 94 */ 95 struct hammer_lock { 96 int refs; /* active references delay writes */ 97 int lockcount; /* lock count for exclusive/shared access */ 98 int wanted; 99 struct thread *locktd; 100 }; 101 102 static __inline int 103 hammer_islocked(struct hammer_lock *lock) 104 { 105 return(lock->lockcount != 0); 106 } 107 108 static __inline int 109 hammer_isactive(struct hammer_lock *lock) 110 { 111 return(lock->refs != 0); 112 } 113 114 static __inline int 115 hammer_islastref(struct hammer_lock *lock) 116 { 117 return(lock->refs == 1); 118 } 119 120 /* 121 * Return if we specifically own the lock exclusively. 122 */ 123 static __inline int 124 hammer_lock_excl_owned(struct hammer_lock *lock, thread_t td) 125 { 126 if (lock->lockcount > 0 && lock->locktd == td) 127 return(1); 128 return(0); 129 } 130 131 /* 132 * Structure used to represent an inode in-memory. 133 * 134 * The record and data associated with an inode may be out of sync with 135 * the disk (xDIRTY flags), or not even on the disk at all (ONDISK flag 136 * clear). 137 * 138 * An inode may also hold a cache of unsynchronized records, used for 139 * database and directories only. Unsynchronized regular file data is 140 * stored in the buffer cache. 141 * 142 * NOTE: A file which is created and destroyed within the initial 143 * synchronization period can wind up not doing any disk I/O at all. 144 * 145 * Finally, an inode may cache numerous disk-referencing B-Tree cursors. 146 */ 147 struct hammer_ino_rb_tree; 148 struct hammer_inode; 149 RB_HEAD(hammer_ino_rb_tree, hammer_inode); 150 RB_PROTOTYPEX(hammer_ino_rb_tree, INFO, hammer_inode, rb_node, 151 hammer_ino_rb_compare, hammer_inode_info_t); 152 153 struct hammer_rec_rb_tree; 154 struct hammer_record; 155 RB_HEAD(hammer_rec_rb_tree, hammer_record); 156 RB_PROTOTYPEX(hammer_rec_rb_tree, INFO, hammer_record, rb_node, 157 hammer_rec_rb_compare, hammer_base_elm_t); 158 159 TAILQ_HEAD(hammer_node_list, hammer_node); 160 161 struct hammer_inode { 162 RB_ENTRY(hammer_inode) rb_node; 163 TAILQ_HEAD(, bio) bio_list; /* BIOs to flush out */ 164 TAILQ_ENTRY(hammer_inode) flush_entry; 165 u_int64_t obj_id; /* (key) object identifier */ 166 hammer_tid_t obj_asof; /* (key) snapshot transid or 0 */ 167 hammer_tid_t last_tid; /* last modified tid (for fsync) */ 168 hammer_tid_t sync_tid; /* last inode tid synced to disk */ 169 struct hammer_mount *hmp; 170 int flags; 171 int error; /* flush error */ 172 int cursor_ip_refs; /* sanity */ 173 struct vnode *vp; 174 struct lockf advlock; 175 struct hammer_lock lock; 176 struct hammer_inode_record ino_rec; 177 struct hammer_inode_data ino_data; 178 struct hammer_rec_rb_tree rec_tree; /* red-black record tree */ 179 struct hammer_node *cache[2]; /* search initiate cache */ 180 }; 181 182 typedef struct hammer_inode *hammer_inode_t; 183 184 #define VTOI(vp) ((struct hammer_inode *)(vp)->v_data) 185 186 #define HAMMER_INODE_DDIRTY 0x0001 /* in-memory ino_data is dirty */ 187 #define HAMMER_INODE_RDIRTY 0x0002 /* in-memory ino_rec is dirty */ 188 #define HAMMER_INODE_ITIMES 0x0004 /* in-memory mtime/atime modified */ 189 #define HAMMER_INODE_XDIRTY 0x0008 /* in-memory records/flsbufs present */ 190 #define HAMMER_INODE_ONDISK 0x0010 /* inode is on-disk (else not yet) */ 191 #define HAMMER_INODE_FLUSH 0x0020 /* flush on last ref */ 192 #define HAMMER_INODE_DELETED 0x0080 /* inode ready for deletion */ 193 #define HAMMER_INODE_DELONDISK 0x0100 /* delete synchronized to disk */ 194 #define HAMMER_INODE_RO 0x0200 /* read-only (because of as-of) */ 195 #define HAMMER_INODE_GONE 0x0400 /* delete flushed out */ 196 #define HAMMER_INODE_DONDISK 0x0800 /* data records may be on disk */ 197 #define HAMMER_INODE_BUFS 0x1000 /* dirty high level bps present */ 198 #define HAMMER_INODE_TIDLOCKED 0x2000 /* tid locked until inode synced */ 199 #define HAMMER_INODE_FLUSHQ 0x4000 /* On flush queue */ 200 #define HAMMER_INODE_FLUSHW 0x8000 /* Someone waiting for flush */ 201 202 #define HAMMER_INODE_MODMASK (HAMMER_INODE_DDIRTY|HAMMER_INODE_RDIRTY| \ 203 HAMMER_INODE_XDIRTY|HAMMER_INODE_BUFS| \ 204 HAMMER_INODE_ITIMES|HAMMER_INODE_DELETED) 205 206 #define HAMMER_MAX_INODE_CURSORS 4 207 208 /* 209 * Structure used to represent an unsynchronized record in-memory. This 210 * structure is orgranized in a per-inode RB-tree. If the inode is not 211 * on disk then neither are any records and the in-memory record tree 212 * represents the entire contents of the inode. If the inode is on disk 213 * then the on-disk B-Tree is scanned in parallel with the in-memory 214 * RB-Tree to synthesize the current state of the file. 215 * 216 * Only current (delete_tid == 0) unsynchronized records are kept in-memory. 217 * 218 * blocked is the count of the number of cursors (ip_first/ip_next) blocked 219 * on the record waiting for a synchronization to complete. 220 */ 221 struct hammer_record { 222 RB_ENTRY(hammer_record) rb_node; 223 struct hammer_lock lock; 224 struct hammer_inode *ip; 225 union hammer_record_ondisk rec; 226 union hammer_data_ondisk *data; 227 int flags; 228 int blocked; 229 }; 230 231 typedef struct hammer_record *hammer_record_t; 232 233 #define HAMMER_RECF_ALLOCDATA 0x0001 234 #define HAMMER_RECF_ONRBTREE 0x0002 235 #define HAMMER_RECF_DELETED 0x0004 236 #define HAMMER_RECF_INBAND 0x0008 237 #define HAMMER_RECF_SYNCING 0x0010 238 #define HAMMER_RECF_WANTED 0x0020 239 240 /* 241 * In-memory structures representing on-disk structures. 242 */ 243 struct hammer_volume; 244 struct hammer_buffer; 245 struct hammer_node; 246 RB_HEAD(hammer_vol_rb_tree, hammer_volume); 247 RB_HEAD(hammer_buf_rb_tree, hammer_buffer); 248 RB_HEAD(hammer_nod_rb_tree, hammer_node); 249 250 RB_PROTOTYPE2(hammer_vol_rb_tree, hammer_volume, rb_node, 251 hammer_vol_rb_compare, int32_t); 252 RB_PROTOTYPE2(hammer_buf_rb_tree, hammer_buffer, rb_node, 253 hammer_buf_rb_compare, hammer_off_t); 254 RB_PROTOTYPE2(hammer_nod_rb_tree, hammer_node, rb_node, 255 hammer_nod_rb_compare, hammer_off_t); 256 257 /* 258 * IO management - embedded at the head of various in-memory structures 259 */ 260 enum hammer_io_type { HAMMER_STRUCTURE_VOLUME, 261 HAMMER_STRUCTURE_BUFFER }; 262 263 union hammer_io_structure; 264 struct hammer_io; 265 266 struct worklist { 267 LIST_ENTRY(worklist) node; 268 }; 269 270 /*TAILQ_HEAD(hammer_dep_list, hammer_dep);*/ 271 272 struct hammer_io { 273 struct worklist worklist; 274 struct hammer_lock lock; 275 enum hammer_io_type type; 276 struct buf *bp; 277 int64_t offset; 278 int loading; /* loading/unloading interlock */ 279 u_int modified : 1; /* bp's data was modified */ 280 u_int released : 1; /* bp released (w/ B_LOCKED set) */ 281 u_int running : 1; /* bp write IO in progress */ 282 u_int waiting : 1; /* someone is waiting on us */ 283 u_int validated : 1; /* ondisk has been validated */ 284 u_int flush : 1; /* flush on last release */ 285 u_int waitdep : 1; /* flush waits for dependancies */ 286 }; 287 288 typedef struct hammer_io *hammer_io_t; 289 290 /* 291 * In-memory volume representing on-disk buffer 292 */ 293 struct hammer_volume { 294 struct hammer_io io; 295 RB_ENTRY(hammer_volume) rb_node; 296 struct hammer_buf_rb_tree rb_bufs_root; 297 struct hammer_volume_ondisk *ondisk; 298 int32_t vol_no; 299 int64_t nblocks; /* note: special calculation for statfs */ 300 int64_t buffer_base; /* base offset of buffer 0 */ 301 hammer_off_t maxbuf_off; /* Maximum buffer offset */ 302 char *vol_name; 303 struct vnode *devvp; 304 struct hammer_mount *hmp; 305 int vol_flags; 306 }; 307 308 typedef struct hammer_volume *hammer_volume_t; 309 310 /* 311 * In-memory buffer (other then volume, super-cluster, or cluster), 312 * representing an on-disk buffer. 313 */ 314 struct hammer_buffer { 315 struct hammer_io io; 316 RB_ENTRY(hammer_buffer) rb_node; 317 void *ondisk; 318 struct hammer_volume *volume; 319 hammer_off_t zone2_offset; 320 hammer_off_t zoneX_offset; 321 struct hammer_node_list clist; 322 }; 323 324 typedef struct hammer_buffer *hammer_buffer_t; 325 326 /* 327 * In-memory B-Tree node, representing an on-disk B-Tree node. 328 * 329 * This is a hang-on structure which is backed by a hammer_buffer, 330 * indexed by a hammer_cluster, and used for fine-grained locking of 331 * B-Tree nodes in order to properly control lock ordering. A hammer_buffer 332 * can contain multiple nodes representing wildly disassociated portions 333 * of the B-Tree so locking cannot be done on a buffer-by-buffer basis. 334 * 335 * This structure uses a cluster-relative index to reduce the number 336 * of layers required to access it, and also because all on-disk B-Tree 337 * references are cluster-relative offsets. 338 */ 339 struct hammer_node { 340 struct hammer_lock lock; /* node-by-node lock */ 341 TAILQ_ENTRY(hammer_node) entry; /* per-buffer linkage */ 342 RB_ENTRY(hammer_node) rb_node; /* per-cluster linkage */ 343 hammer_off_t node_offset; /* full offset spec */ 344 struct hammer_mount *hmp; 345 struct hammer_buffer *buffer; /* backing buffer */ 346 hammer_node_ondisk_t ondisk; /* ptr to on-disk structure */ 347 struct hammer_node **cache1; /* passive cache(s) */ 348 struct hammer_node **cache2; 349 int flags; 350 int loading; /* load interlock */ 351 }; 352 353 #define HAMMER_NODE_DELETED 0x0001 354 #define HAMMER_NODE_FLUSH 0x0002 355 356 typedef struct hammer_node *hammer_node_t; 357 358 /* 359 * List of locked nodes. 360 */ 361 struct hammer_node_locklist { 362 struct hammer_node_locklist *next; 363 hammer_node_t node; 364 }; 365 366 typedef struct hammer_node_locklist *hammer_node_locklist_t; 367 368 369 /* 370 * Common I/O management structure - embedded in in-memory structures 371 * which are backed by filesystem buffers. 372 */ 373 union hammer_io_structure { 374 struct hammer_io io; 375 struct hammer_volume volume; 376 struct hammer_buffer buffer; 377 }; 378 379 typedef union hammer_io_structure *hammer_io_structure_t; 380 381 /* 382 * Allocation holes are recorded for a short period of time in an attempt 383 * to use up the space. 384 */ 385 386 #define HAMMER_MAX_HOLES 8 387 388 struct hammer_hole; 389 390 struct hammer_holes { 391 TAILQ_HEAD(, hammer_hole) list; 392 int count; 393 }; 394 395 typedef struct hammer_holes *hammer_holes_t; 396 397 struct hammer_hole { 398 TAILQ_ENTRY(hammer_hole) entry; 399 hammer_off_t offset; 400 int bytes; 401 }; 402 403 typedef struct hammer_hole *hammer_hole_t; 404 405 #include "hammer_cursor.h" 406 407 /* 408 * Internal hammer mount data structure 409 */ 410 struct hammer_mount { 411 struct mount *mp; 412 /*struct vnode *rootvp;*/ 413 struct hammer_ino_rb_tree rb_inos_root; 414 struct hammer_vol_rb_tree rb_vols_root; 415 struct hammer_nod_rb_tree rb_nods_root; 416 struct hammer_volume *rootvol; 417 struct hammer_base_elm root_btree_beg; 418 struct hammer_base_elm root_btree_end; 419 char *zbuf; /* HAMMER_BUFSIZE bytes worth of all-zeros */ 420 int hflags; 421 int ronly; 422 int nvolumes; 423 int volume_iterator; 424 int flusher_seq; 425 int flusher_act; 426 int flusher_exiting; 427 thread_t flusher_td; 428 u_int check_interrupt; 429 uuid_t fsid; 430 udev_t fsid_udev; 431 hammer_tid_t asof; 432 u_int32_t namekey_iterator; 433 hammer_off_t zone_limits[HAMMER_MAX_ZONES]; 434 struct netexport export; 435 struct lock blockmap_lock; 436 struct hammer_holes holes[HAMMER_MAX_ZONES]; 437 TAILQ_HEAD(, hammer_inode) flush_list; 438 }; 439 440 typedef struct hammer_mount *hammer_mount_t; 441 442 struct hammer_sync_info { 443 int error; 444 int waitfor; 445 }; 446 447 #endif 448 449 #if defined(_KERNEL) 450 451 extern struct vop_ops hammer_vnode_vops; 452 extern struct vop_ops hammer_spec_vops; 453 extern struct vop_ops hammer_fifo_vops; 454 extern struct bio_ops hammer_bioops; 455 456 extern int hammer_debug_general; 457 extern int hammer_debug_locks; 458 extern int hammer_debug_btree; 459 extern int hammer_debug_tid; 460 extern int hammer_debug_recover; 461 extern int hammer_debug_recover_faults; 462 extern int hammer_count_inodes; 463 extern int hammer_count_records; 464 extern int hammer_count_record_datas; 465 extern int hammer_count_volumes; 466 extern int hammer_count_buffers; 467 extern int hammer_count_nodes; 468 extern int64_t hammer_contention_count; 469 470 int hammer_vop_inactive(struct vop_inactive_args *); 471 int hammer_vop_reclaim(struct vop_reclaim_args *); 472 int hammer_get_vnode(struct hammer_inode *ip, int lktype, 473 struct vnode **vpp); 474 struct hammer_inode *hammer_get_inode(hammer_transaction_t trans, 475 struct hammer_node **cache, 476 u_int64_t obj_id, hammer_tid_t asof, int flags, 477 int *errorp); 478 void hammer_put_inode(struct hammer_inode *ip); 479 void hammer_put_inode_ref(struct hammer_inode *ip); 480 481 int hammer_unload_inode(hammer_inode_t ip, void *data); 482 int hammer_unload_volume(hammer_volume_t volume, void *data __unused); 483 int hammer_unload_buffer(hammer_buffer_t buffer, void *data __unused); 484 int hammer_install_volume(hammer_mount_t hmp, const char *volname); 485 486 int hammer_ip_lookup(hammer_cursor_t cursor, hammer_inode_t ip); 487 int hammer_ip_first(hammer_cursor_t cursor, hammer_inode_t ip); 488 int hammer_ip_next(hammer_cursor_t cursor); 489 int hammer_ip_resolve_record_and_data(hammer_cursor_t cursor); 490 int hammer_ip_resolve_data(hammer_cursor_t cursor); 491 int hammer_ip_delete_record(hammer_cursor_t cursor, hammer_tid_t tid); 492 int hammer_delete_at_cursor(hammer_cursor_t cursor, int64_t *stat_bytes); 493 int hammer_ip_check_directory_empty(hammer_transaction_t trans, 494 hammer_inode_t ip); 495 int hammer_sync_hmp(hammer_mount_t hmp, int waitfor); 496 int hammer_sync_volume(hammer_volume_t volume, void *data); 497 int hammer_sync_buffer(hammer_buffer_t buffer, void *data); 498 499 hammer_record_t 500 hammer_alloc_mem_record(hammer_inode_t ip); 501 void hammer_rel_mem_record(hammer_record_t record); 502 503 int hammer_cursor_up(hammer_cursor_t cursor); 504 int hammer_cursor_down(hammer_cursor_t cursor); 505 int hammer_cursor_upgrade(hammer_cursor_t cursor); 506 void hammer_cursor_downgrade(hammer_cursor_t cursor); 507 int hammer_cursor_seek(hammer_cursor_t cursor, hammer_node_t node, 508 int index); 509 void hammer_lock_ex(struct hammer_lock *lock); 510 int hammer_lock_ex_try(struct hammer_lock *lock); 511 void hammer_lock_sh(struct hammer_lock *lock); 512 int hammer_lock_upgrade(struct hammer_lock *lock); 513 void hammer_lock_downgrade(struct hammer_lock *lock); 514 void hammer_unlock(struct hammer_lock *lock); 515 void hammer_ref(struct hammer_lock *lock); 516 void hammer_unref(struct hammer_lock *lock); 517 518 u_int32_t hammer_to_unix_xid(uuid_t *uuid); 519 void hammer_guid_to_uuid(uuid_t *uuid, u_int32_t guid); 520 void hammer_to_timespec(hammer_tid_t tid, struct timespec *ts); 521 hammer_tid_t hammer_timespec_to_transid(struct timespec *ts); 522 hammer_tid_t hammer_alloc_tid(hammer_transaction_t trans); 523 hammer_tid_t hammer_now_tid(void); 524 hammer_tid_t hammer_str_to_tid(const char *str); 525 526 enum vtype hammer_get_vnode_type(u_int8_t obj_type); 527 int hammer_get_dtype(u_int8_t obj_type); 528 u_int8_t hammer_get_obj_type(enum vtype vtype); 529 int64_t hammer_directory_namekey(void *name, int len); 530 531 int hammer_init_cursor(hammer_transaction_t trans, hammer_cursor_t cursor, 532 struct hammer_node **cache); 533 534 void hammer_done_cursor(hammer_cursor_t cursor); 535 void hammer_mem_done(hammer_cursor_t cursor); 536 537 int hammer_btree_lookup(hammer_cursor_t cursor); 538 int hammer_btree_first(hammer_cursor_t cursor); 539 int hammer_btree_last(hammer_cursor_t cursor); 540 int hammer_btree_extract(hammer_cursor_t cursor, int flags); 541 int hammer_btree_iterate(hammer_cursor_t cursor); 542 int hammer_btree_iterate_reverse(hammer_cursor_t cursor); 543 int hammer_btree_insert(hammer_cursor_t cursor, hammer_btree_elm_t elm); 544 int hammer_btree_delete(hammer_cursor_t cursor); 545 int hammer_btree_cmp(hammer_base_elm_t key1, hammer_base_elm_t key2); 546 int hammer_btree_chkts(hammer_tid_t ts, hammer_base_elm_t key); 547 int hammer_btree_correct_rhb(hammer_cursor_t cursor, hammer_tid_t tid); 548 int hammer_btree_correct_lhb(hammer_cursor_t cursor, hammer_tid_t tid); 549 550 551 int hammer_btree_lock_children(hammer_cursor_t cursor, 552 struct hammer_node_locklist **locklistp); 553 554 void hammer_print_btree_node(hammer_node_ondisk_t ondisk); 555 void hammer_print_btree_elm(hammer_btree_elm_t elm, u_int8_t type, int i); 556 557 void *hammer_bread(struct hammer_mount *hmp, hammer_off_t off, 558 int *errorp, struct hammer_buffer **bufferp); 559 void *hammer_bnew(struct hammer_mount *hmp, hammer_off_t off, 560 int *errorp, struct hammer_buffer **bufferp); 561 562 hammer_volume_t hammer_get_root_volume(hammer_mount_t hmp, int *errorp); 563 int hammer_dowrite(hammer_transaction_t trans, hammer_inode_t ip, 564 struct bio *bio); 565 566 hammer_volume_t hammer_get_volume(hammer_mount_t hmp, 567 int32_t vol_no, int *errorp); 568 hammer_buffer_t hammer_get_buffer(hammer_mount_t hmp, 569 hammer_off_t buf_offset, int isnew, int *errorp); 570 void hammer_uncache_buffer(struct hammer_mount *hmp, hammer_off_t off); 571 572 int hammer_ref_volume(hammer_volume_t volume); 573 int hammer_ref_buffer(hammer_buffer_t buffer); 574 void hammer_flush_buffer_nodes(hammer_buffer_t buffer); 575 576 void hammer_rel_volume(hammer_volume_t volume, int flush); 577 void hammer_rel_buffer(hammer_buffer_t buffer, int flush); 578 579 int hammer_vfs_export(struct mount *mp, int op, 580 const struct export_args *export); 581 hammer_node_t hammer_get_node(hammer_mount_t hmp, 582 hammer_off_t node_offset, int *errorp); 583 void hammer_ref_node(hammer_node_t node); 584 hammer_node_t hammer_ref_node_safe(struct hammer_mount *hmp, 585 struct hammer_node **cache, int *errorp); 586 void hammer_rel_node(hammer_node_t node); 587 void hammer_delete_node(hammer_transaction_t trans, 588 hammer_node_t node); 589 void hammer_cache_node(hammer_node_t node, 590 struct hammer_node **cache); 591 void hammer_uncache_node(struct hammer_node **cache); 592 void hammer_flush_node(hammer_node_t node); 593 594 void hammer_dup_buffer(struct hammer_buffer **bufferp, 595 struct hammer_buffer *buffer); 596 hammer_node_t hammer_alloc_btree(hammer_transaction_t trans, int *errorp); 597 void *hammer_alloc_record(hammer_transaction_t trans, 598 hammer_off_t *rec_offp, u_int16_t rec_type, 599 struct hammer_buffer **rec_bufferp, 600 int32_t data_len, void **datap, 601 struct hammer_buffer **data_bufferp, int *errorp); 602 void *hammer_alloc_data(hammer_transaction_t trans, int32_t data_len, 603 hammer_off_t *data_offsetp, 604 struct hammer_buffer **data_bufferp, int *errorp); 605 606 int hammer_generate_undo(hammer_transaction_t trans, hammer_io_t io, 607 hammer_off_t zone1_offset, void *base, int len); 608 609 void hammer_put_volume(struct hammer_volume *volume, int flush); 610 void hammer_put_buffer(struct hammer_buffer *buffer, int flush); 611 612 hammer_off_t hammer_freemap_alloc(hammer_transaction_t trans, 613 hammer_off_t owner, int *errorp); 614 void hammer_freemap_free(hammer_transaction_t trans, hammer_off_t phys_offset, 615 hammer_off_t owner, int *errorp); 616 hammer_off_t hammer_blockmap_alloc(hammer_transaction_t trans, int zone, 617 int bytes, int *errorp); 618 void hammer_blockmap_free(hammer_transaction_t trans, 619 hammer_off_t bmap_off, int bytes); 620 int hammer_blockmap_getfree(hammer_mount_t hmp, hammer_off_t bmap_off, 621 int *curp, int *errorp); 622 hammer_off_t hammer_blockmap_lookup(hammer_mount_t hmp, hammer_off_t bmap_off, 623 int *errorp); 624 hammer_off_t hammer_undo_lookup(hammer_mount_t hmp, hammer_off_t bmap_off, 625 int *errorp); 626 627 void hammer_start_transaction(struct hammer_transaction *trans, 628 struct hammer_mount *hmp); 629 void hammer_simple_transaction(struct hammer_transaction *trans, 630 struct hammer_mount *hmp); 631 void hammer_start_transaction_tid(struct hammer_transaction *trans, 632 struct hammer_mount *hmp, hammer_tid_t tid); 633 void hammer_commit_transaction(struct hammer_transaction *trans); 634 void hammer_abort_transaction(struct hammer_transaction *trans); 635 636 void hammer_modify_inode(struct hammer_transaction *trans, 637 hammer_inode_t ip, int flags); 638 int hammer_create_inode(struct hammer_transaction *trans, struct vattr *vap, 639 struct ucred *cred, struct hammer_inode *dip, 640 struct hammer_inode **ipp); 641 void hammer_rel_inode(hammer_inode_t ip, int flush); 642 int hammer_sync_inode(hammer_inode_t ip, int waitfor, int handle_delete); 643 644 int hammer_ip_add_directory(struct hammer_transaction *trans, 645 hammer_inode_t dip, struct namecache *ncp, 646 hammer_inode_t nip); 647 int hammer_ip_del_directory(struct hammer_transaction *trans, 648 hammer_cursor_t cursor, hammer_inode_t dip, 649 hammer_inode_t ip); 650 int hammer_ip_add_record(struct hammer_transaction *trans, 651 hammer_record_t record); 652 int hammer_ip_delete_range(struct hammer_transaction *trans, 653 hammer_inode_t ip, int64_t ran_beg, int64_t ran_end); 654 int hammer_ip_delete_range_all(struct hammer_transaction *trans, 655 hammer_inode_t ip); 656 int hammer_ip_sync_data(struct hammer_transaction *trans, 657 hammer_inode_t ip, int64_t offset, 658 void *data, int bytes); 659 int hammer_ip_sync_record(hammer_transaction_t trans, hammer_record_t rec); 660 661 int hammer_ioctl(hammer_inode_t ip, u_long com, caddr_t data, int fflag, 662 struct ucred *cred); 663 664 void hammer_io_init(hammer_io_t io, enum hammer_io_type type); 665 int hammer_io_read(struct vnode *devvp, struct hammer_io *io); 666 int hammer_io_new(struct vnode *devvp, struct hammer_io *io); 667 void hammer_io_release(struct hammer_io *io); 668 void hammer_io_flush(struct hammer_io *io); 669 int hammer_io_checkflush(hammer_io_t io); 670 void hammer_io_clear_modify(struct hammer_io *io); 671 void hammer_io_waitdep(struct hammer_io *io); 672 673 void hammer_modify_volume(hammer_transaction_t trans, hammer_volume_t volume, 674 void *base, int len); 675 void hammer_modify_buffer(hammer_transaction_t trans, hammer_buffer_t buffer, 676 void *base, int len); 677 678 int hammer_ioc_reblock(hammer_transaction_t trans, hammer_inode_t ip, 679 struct hammer_ioc_reblock *reblock); 680 681 void hammer_init_holes(hammer_mount_t hmp, hammer_holes_t holes); 682 void hammer_free_holes(hammer_mount_t hmp, hammer_holes_t holes); 683 int hammer_signal_check(hammer_mount_t hmp); 684 685 void hammer_flusher_create(hammer_mount_t hmp); 686 void hammer_flusher_destroy(hammer_mount_t hmp); 687 void hammer_flusher_sync(hammer_mount_t hmp); 688 void hammer_flusher_async(hammer_mount_t hmp); 689 690 #endif 691 692 static __inline void 693 hammer_modify_node_noundo(hammer_transaction_t trans, hammer_node_t node) 694 { 695 hammer_modify_buffer(trans, node->buffer, NULL, 0); 696 } 697 698 static __inline void 699 hammer_modify_node_all(hammer_transaction_t trans, struct hammer_node *node) 700 { 701 hammer_modify_buffer(trans, node->buffer, 702 node->ondisk, sizeof(*node->ondisk)); 703 } 704 705 static __inline void 706 hammer_modify_node(hammer_transaction_t trans, hammer_node_t node, 707 void *base, int len) 708 { 709 KKASSERT((char *)base >= (char *)node->ondisk && 710 (char *)base + len <= 711 (char *)node->ondisk + sizeof(*node->ondisk)); 712 hammer_modify_buffer(trans, node->buffer, base, len); 713 } 714 715 static __inline void 716 hammer_modify_record(hammer_transaction_t trans, hammer_buffer_t buffer, 717 void *base, int len) 718 { 719 KKASSERT((char *)base >= (char *)buffer->ondisk && 720 (char *)base + len <= (char *)buffer->ondisk + HAMMER_BUFSIZE); 721 hammer_modify_buffer(trans, buffer, base, len); 722 } 723 724