1ed3afccaSMatthew Dillon /* 2ed3afccaSMatthew Dillon * Copyright (c) 2007 The DragonFly Project. All rights reserved. 3ed3afccaSMatthew Dillon * 4ed3afccaSMatthew Dillon * This code is derived from software contributed to The DragonFly Project 5ed3afccaSMatthew Dillon * by Matthew Dillon <dillon@backplane.com> 6ed3afccaSMatthew Dillon * 7ed3afccaSMatthew Dillon * Redistribution and use in source and binary forms, with or without 8ed3afccaSMatthew Dillon * modification, are permitted provided that the following conditions 9ed3afccaSMatthew Dillon * are met: 10ed3afccaSMatthew Dillon * 11ed3afccaSMatthew Dillon * 1. Redistributions of source code must retain the above copyright 12ed3afccaSMatthew Dillon * notice, this list of conditions and the following disclaimer. 13ed3afccaSMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright 14ed3afccaSMatthew Dillon * notice, this list of conditions and the following disclaimer in 15ed3afccaSMatthew Dillon * the documentation and/or other materials provided with the 16ed3afccaSMatthew Dillon * distribution. 17ed3afccaSMatthew Dillon * 3. Neither the name of The DragonFly Project nor the names of its 18ed3afccaSMatthew Dillon * contributors may be used to endorse or promote products derived 19ed3afccaSMatthew Dillon * from this software without specific, prior written permission. 20ed3afccaSMatthew Dillon * 21ed3afccaSMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22ed3afccaSMatthew Dillon * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23ed3afccaSMatthew Dillon * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24ed3afccaSMatthew Dillon * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25ed3afccaSMatthew Dillon * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26ed3afccaSMatthew Dillon * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27ed3afccaSMatthew Dillon * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28ed3afccaSMatthew Dillon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29ed3afccaSMatthew Dillon * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30ed3afccaSMatthew Dillon * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31ed3afccaSMatthew Dillon * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32ed3afccaSMatthew Dillon * SUCH DAMAGE. 33ed3afccaSMatthew Dillon */ 34ed3afccaSMatthew Dillon 35a74dc250STomohiro Kusumi #ifndef HAMMER_UTIL_H_ 36a74dc250STomohiro Kusumi #define HAMMER_UTIL_H_ 37a74dc250STomohiro Kusumi 38ed3afccaSMatthew Dillon #include <sys/types.h> 399c8b568eSTomohiro Kusumi #include <sys/stat.h> 409c8b568eSTomohiro Kusumi #include <sys/time.h> 4161aeeb33SMatthew Dillon #include <sys/tree.h> 4261aeeb33SMatthew Dillon #include <sys/queue.h> 4392d85f08STomohiro Kusumi #include <sys/mount.h> 4461aeeb33SMatthew Dillon 459c8b568eSTomohiro Kusumi #include <assert.h> 469c8b568eSTomohiro Kusumi #include <stdio.h> 479c8b568eSTomohiro Kusumi #include <stdlib.h> 489c8b568eSTomohiro Kusumi #include <stdarg.h> 499c8b568eSTomohiro Kusumi #include <string.h> 509c8b568eSTomohiro Kusumi #include <unistd.h> 519c8b568eSTomohiro Kusumi #include <stddef.h> 529c8b568eSTomohiro Kusumi #include <err.h> 539c8b568eSTomohiro Kusumi #include <errno.h> 549c8b568eSTomohiro Kusumi #include <fcntl.h> 559c8b568eSTomohiro Kusumi 56ed3afccaSMatthew Dillon #include <vfs/hammer/hammer_disk.h> 5792d85f08STomohiro Kusumi #include <vfs/hammer/hammer_ioctl.h> 5845643966STomohiro Kusumi #include <vfs/hammer/hammer_crc.h> 59ed3afccaSMatthew Dillon #include <uuid.h> 60ed3afccaSMatthew Dillon 6161aeeb33SMatthew Dillon struct cache_info { 6261aeeb33SMatthew Dillon TAILQ_ENTRY(cache_info) entry; 6361aeeb33SMatthew Dillon int refs; /* structural references */ 6461aeeb33SMatthew Dillon int modified; /* ondisk modified flag */ 6561aeeb33SMatthew Dillon int delete; /* delete flag - delete on last ref */ 6661aeeb33SMatthew Dillon }; 6761aeeb33SMatthew Dillon 68ba7b52c9SMatthew Dillon #define HAMMER_BUFLISTS 64 69ba7b52c9SMatthew Dillon #define HAMMER_BUFLISTMASK (HAMMER_BUFLISTS - 1) 70ba7b52c9SMatthew Dillon 71ed3afccaSMatthew Dillon /* 72f402100cSTomohiro Kusumi * These structures are used by hammer(8) and newfs_hammer(8) 73f402100cSTomohiro Kusumi * to track the filesystem buffers. 74684002f2STomohiro Kusumi * 75684002f2STomohiro Kusumi * vol_free_off and vol_free_end are zone-2 offsets. 76684002f2STomohiro Kusumi * These two are initialized only when newly creating a filesystem. 77ed3afccaSMatthew Dillon */ 78ed3afccaSMatthew Dillon struct volume_info { 7961aeeb33SMatthew Dillon TAILQ_ENTRY(volume_info) entry; 8021000e42STomohiro Kusumi const char *name; 8121000e42STomohiro Kusumi const char *type; 82684002f2STomohiro Kusumi int vol_no; 83684002f2STomohiro Kusumi int rdonly; 84ed3afccaSMatthew Dillon int fd; 85ed3afccaSMatthew Dillon off_t size; 86e0fb398bSTim off_t device_offset; 87ed3afccaSMatthew Dillon 88684002f2STomohiro Kusumi hammer_off_t vol_free_off; 89684002f2STomohiro Kusumi hammer_off_t vol_free_end; 90684002f2STomohiro Kusumi 91b419d3eeSTomohiro Kusumi hammer_volume_ondisk_t ondisk; 92ed3afccaSMatthew Dillon 93ba7b52c9SMatthew Dillon TAILQ_HEAD(, buffer_info) buffer_lists[HAMMER_BUFLISTS]; 94ed3afccaSMatthew Dillon }; 95ed3afccaSMatthew Dillon 96ed3afccaSMatthew Dillon struct buffer_info { 977603683aSTomohiro Kusumi struct cache_info cache; /* must be at offset 0 */ 9861aeeb33SMatthew Dillon TAILQ_ENTRY(buffer_info) entry; 99*0942cbbcSTomohiro Kusumi hammer_off_t zone2_offset; /* zone-2 offset */ 100b46b99bfSMatthew Dillon int64_t raw_offset; /* physical offset */ 101ed3afccaSMatthew Dillon struct volume_info *volume; 10247197d71SMatthew Dillon void *ondisk; 103ed3afccaSMatthew Dillon }; 104ed3afccaSMatthew Dillon 105020339d5STomohiro Kusumi /* 106020339d5STomohiro Kusumi * Data structure for zone statistics. 107020339d5STomohiro Kusumi */ 108723806f4STomohiro Kusumi struct zone_stat { 10913846824STomohiro Kusumi int64_t blocks; /* number of big-blocks */ 11013846824STomohiro Kusumi int64_t items; /* number of items */ 11113846824STomohiro Kusumi int64_t used; /* bytes used */ 112723806f4STomohiro Kusumi }; 113723806f4STomohiro Kusumi 114ed3afccaSMatthew Dillon extern uuid_t Hammer_FSType; 115ed3afccaSMatthew Dillon extern uuid_t Hammer_FSId; 11625ee129eSTomohiro Kusumi extern int UseReadBehind; 11725ee129eSTomohiro Kusumi extern int UseReadAhead; 118ba7b52c9SMatthew Dillon extern int DebugOpt; 119dce7ae2cSTomohiro Kusumi extern const char *zone_labels[]; 120ed3afccaSMatthew Dillon 121385a0260STomohiro Kusumi struct volume_info *init_volume(const char *filename, int oflags, int32_t vol_no); 122a1ef4f7eSTomohiro Kusumi struct volume_info *load_volume(const char *filename, int oflags, int verify); 1239221b598STomohiro Kusumi void assert_volume_offset(struct volume_info *vol); 124ed3afccaSMatthew Dillon struct volume_info *get_volume(int32_t vol_no); 12542700c9dSTomohiro Kusumi struct volume_info *get_root_volume(void); 12640043e7fSMatthew Dillon void *get_buffer_data(hammer_off_t buf_offset, struct buffer_info **bufferp, 12740043e7fSMatthew Dillon int isnew); 12861aeeb33SMatthew Dillon void rel_buffer(struct buffer_info *buffer); 12961aeeb33SMatthew Dillon 13030e8ae55STomohiro Kusumi hammer_off_t bootstrap_bigblock(struct volume_info *volume); 1319dfd60d1STomohiro Kusumi hammer_off_t alloc_undo_bigblock(struct volume_info *volume); 13286872a2aSTomohiro Kusumi void *alloc_blockmap(int zone, int bytes, hammer_off_t *result_offp, 13386872a2aSTomohiro Kusumi struct buffer_info **bufferp); 1348b916bc2STomohiro Kusumi hammer_off_t blockmap_lookup(hammer_off_t bmap_off, int *errorp); 1358b916bc2STomohiro Kusumi hammer_off_t blockmap_lookup_save(hammer_off_t bmap_off, 13621e9e7d5STomohiro Kusumi hammer_blockmap_layer1_t layer1, 13721e9e7d5STomohiro Kusumi hammer_blockmap_layer2_t layer2, 1386ed4c886SMatthew Dillon int *errorp); 1398303b848STomohiro Kusumi void format_undomap(struct volume_info *root_vol, int64_t *undo_buffer_size); 1403f673d5cSMatthew Dillon 14173eb8826STomohiro Kusumi hammer_node_ondisk_t alloc_btree_node(hammer_off_t *offp, 1424a2cb8bbSTomohiro Kusumi struct buffer_info **data_bufferp); 143baa8ac59STomohiro Kusumi void *alloc_meta_element(hammer_off_t *offp, int32_t data_len, 144baa8ac59STomohiro Kusumi struct buffer_info **data_bufferp); 14511ad5adeSMatthew Dillon 1465dca51beSTomohiro Kusumi void format_blockmap(struct volume_info *vol, int zone, hammer_off_t offset); 147a360b0f5STomohiro Kusumi void format_freemap(struct volume_info *root_vol); 148c3be93f2SMatthew Dillon int64_t initialize_freemap(struct volume_info *vol); 14992d0a1c8STomohiro Kusumi int64_t count_freemap(struct volume_info *vol); 150927812a6STomohiro Kusumi void print_blockmap(const struct volume_info *vol); 151c3be93f2SMatthew Dillon 152ed3afccaSMatthew Dillon void flush_all_volumes(void); 153ed3afccaSMatthew Dillon void flush_volume(struct volume_info *vol); 154ed3afccaSMatthew Dillon void flush_buffer(struct buffer_info *buf); 155ed3afccaSMatthew Dillon 156f819215cSTomohiro Kusumi int64_t init_boot_area_size(int64_t value, off_t avg_vol_size); 1573e7805d7STomohiro Kusumi int64_t init_memory_log_size(int64_t value, off_t avg_vol_size); 158f819215cSTomohiro Kusumi 15925ee129eSTomohiro Kusumi int hammer_parse_cache_size(const char *arg); 16019c60b7cSTomohiro Kusumi void hammer_cache_add(struct cache_info *cache); 16161aeeb33SMatthew Dillon void hammer_cache_del(struct cache_info *cache); 162b46b99bfSMatthew Dillon void hammer_cache_used(struct cache_info *cache); 16361aeeb33SMatthew Dillon void hammer_cache_flush(void); 16461aeeb33SMatthew Dillon 165044711a6STomohiro Kusumi void hammer_key_beg_init(hammer_base_elm_t base); 166044711a6STomohiro Kusumi void hammer_key_end_init(hammer_base_elm_t base); 167f3f3fa72STomohiro Kusumi int getyn(void); 168f3f3fa72STomohiro Kusumi const char *sizetostr(off_t size); 169f3f3fa72STomohiro Kusumi int hammer_fs_to_vol(const char *fs, struct hammer_ioc_volume_list *iocp); 170f3f3fa72STomohiro Kusumi int hammer_fs_to_rootvol(const char *fs, char *buf, int len); 171f3f3fa72STomohiro Kusumi 172020339d5STomohiro Kusumi struct zone_stat *hammer_init_zone_stat(void); 1732550036fSTomohiro Kusumi struct zone_stat *hammer_init_zone_stat_bits(void); 174020339d5STomohiro Kusumi void hammer_cleanup_zone_stat(struct zone_stat *stats); 175e9976f43STomohiro Kusumi void hammer_add_zone_stat(struct zone_stat *stats, hammer_off_t offset, 17613846824STomohiro Kusumi int bytes); 177020339d5STomohiro Kusumi void hammer_add_zone_stat_layer2(struct zone_stat *stats, 17821e9e7d5STomohiro Kusumi hammer_blockmap_layer2_t layer2); 179020339d5STomohiro Kusumi void hammer_print_zone_stat(const struct zone_stat *stats); 180a74dc250STomohiro Kusumi 18195f03e3eSTomohiro Kusumi #define hwarn(format, args...) warn("WARNING: "format,## args) 18295f03e3eSTomohiro Kusumi #define hwarnx(format, args...) warnx("WARNING: "format,## args) 18395f03e3eSTomohiro Kusumi 184a74dc250STomohiro Kusumi #endif /* !HAMMER_UTIL_H_ */ 185