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/queue.h> 4292d85f08STomohiro Kusumi #include <sys/mount.h> 4341ae0862STomohiro Kusumi #include <sys/wait.h> 44*1ebd8403STomohiro Kusumi #include <sys/ioctl.h> 4561aeeb33SMatthew Dillon 469c8b568eSTomohiro Kusumi #include <stdio.h> 479c8b568eSTomohiro Kusumi #include <stdlib.h> 489c8b568eSTomohiro Kusumi #include <stdarg.h> 499c8b568eSTomohiro Kusumi #include <stddef.h> 5041ae0862STomohiro Kusumi #include <string.h> 5141ae0862STomohiro Kusumi #include <ctype.h> 5241ae0862STomohiro Kusumi #include <dirent.h> 539c8b568eSTomohiro Kusumi #include <errno.h> 5441ae0862STomohiro Kusumi #include <err.h> 559c8b568eSTomohiro Kusumi #include <fcntl.h> 5641ae0862STomohiro Kusumi #include <libgen.h> 5741ae0862STomohiro Kusumi #include <limits.h> 5841ae0862STomohiro Kusumi #include <signal.h> 5941ae0862STomohiro Kusumi #include <time.h> 6041ae0862STomohiro Kusumi #include <unistd.h> 6141ae0862STomohiro Kusumi #include <assert.h> 629c8b568eSTomohiro Kusumi 63ed3afccaSMatthew Dillon #include <vfs/hammer/hammer_disk.h> 6492d85f08STomohiro Kusumi #include <vfs/hammer/hammer_ioctl.h> 6545643966STomohiro Kusumi #include <vfs/hammer/hammer_crc.h> 66ed3afccaSMatthew Dillon 67ba7b52c9SMatthew Dillon #define HAMMER_BUFLISTS 64 68ba7b52c9SMatthew Dillon #define HAMMER_BUFLISTMASK (HAMMER_BUFLISTS - 1) 69ba7b52c9SMatthew Dillon 70ed3afccaSMatthew Dillon /* 71f402100cSTomohiro Kusumi * These structures are used by hammer(8) and newfs_hammer(8) 72f402100cSTomohiro Kusumi * to track the filesystem buffers. 73684002f2STomohiro Kusumi * 74684002f2STomohiro Kusumi * vol_free_off and vol_free_end are zone-2 offsets. 75684002f2STomohiro Kusumi * These two are initialized only when newly creating a filesystem. 76ed3afccaSMatthew Dillon */ 772dba5fa7STomohiro Kusumi typedef struct volume_info { 7861aeeb33SMatthew Dillon TAILQ_ENTRY(volume_info) entry; 7921000e42STomohiro Kusumi const char *name; 8021000e42STomohiro Kusumi const char *type; 81684002f2STomohiro Kusumi int vol_no; 82684002f2STomohiro Kusumi int rdonly; 83ed3afccaSMatthew Dillon int fd; 84ed3afccaSMatthew Dillon off_t size; 85e0fb398bSTim off_t device_offset; 86ed3afccaSMatthew Dillon 87684002f2STomohiro Kusumi hammer_off_t vol_free_off; 88684002f2STomohiro Kusumi hammer_off_t vol_free_end; 89684002f2STomohiro Kusumi 90b419d3eeSTomohiro Kusumi hammer_volume_ondisk_t ondisk; 91ed3afccaSMatthew Dillon 92ba7b52c9SMatthew Dillon TAILQ_HEAD(, buffer_info) buffer_lists[HAMMER_BUFLISTS]; 932dba5fa7STomohiro Kusumi } *volume_info_t; 94ed3afccaSMatthew Dillon 9578418745STomohiro Kusumi typedef struct cache_info { 9691e559fdSTomohiro Kusumi TAILQ_ENTRY(cache_info) entry; 9791e559fdSTomohiro Kusumi int refs; /* structural references */ 9891e559fdSTomohiro Kusumi int modified; /* ondisk modified flag */ 9991e559fdSTomohiro Kusumi int delete; /* delete flag - delete on last ref */ 10078418745STomohiro Kusumi } *cache_info_t; 10191e559fdSTomohiro Kusumi 102c17fa600STomohiro Kusumi typedef struct buffer_info { 1037603683aSTomohiro Kusumi struct cache_info cache; /* must be at offset 0 */ 10461aeeb33SMatthew Dillon TAILQ_ENTRY(buffer_info) entry; 1050942cbbcSTomohiro Kusumi hammer_off_t zone2_offset; /* zone-2 offset */ 106b46b99bfSMatthew Dillon int64_t raw_offset; /* physical offset */ 1072dba5fa7STomohiro Kusumi volume_info_t volume; 10847197d71SMatthew Dillon void *ondisk; 109c17fa600STomohiro Kusumi } *buffer_info_t; 110ed3afccaSMatthew Dillon 111020339d5STomohiro Kusumi /* 112020339d5STomohiro Kusumi * Data structure for zone statistics. 113020339d5STomohiro Kusumi */ 11464321bafSTomohiro Kusumi typedef struct zone_stat { 11513846824STomohiro Kusumi int64_t blocks; /* number of big-blocks */ 11613846824STomohiro Kusumi int64_t items; /* number of items */ 11713846824STomohiro Kusumi int64_t used; /* bytes used */ 11864321bafSTomohiro Kusumi } *zone_stat_t; 119723806f4STomohiro Kusumi 12090da8fc8STomohiro Kusumi extern hammer_uuid_t Hammer_FSType; 12190da8fc8STomohiro Kusumi extern hammer_uuid_t Hammer_FSId; 12225ee129eSTomohiro Kusumi extern int UseReadBehind; 12325ee129eSTomohiro Kusumi extern int UseReadAhead; 124ba7b52c9SMatthew Dillon extern int DebugOpt; 1254c09d9c4SMatthew Dillon extern uint32_t HammerVersion; 126dce7ae2cSTomohiro Kusumi extern const char *zone_labels[]; 127ed3afccaSMatthew Dillon 1282dba5fa7STomohiro Kusumi volume_info_t init_volume(const char *filename, int oflags, int32_t vol_no); 1296f3c8414STomohiro Kusumi volume_info_t load_volume(const char *filename, int oflags, int verify_volume); 130e8a2b543STomohiro Kusumi int is_regfile(const volume_info_t volume); 131e8a2b543STomohiro Kusumi void assert_volume_offset(const volume_info_t volume); 1322dba5fa7STomohiro Kusumi volume_info_t get_volume(int32_t vol_no); 1332dba5fa7STomohiro Kusumi volume_info_t get_root_volume(void); 134c17fa600STomohiro Kusumi void rel_buffer(buffer_info_t buffer); 135c17fa600STomohiro Kusumi void *get_buffer_data(hammer_off_t buf_offset, buffer_info_t *bufferp, 13640043e7fSMatthew Dillon int isnew); 13791e559fdSTomohiro Kusumi hammer_node_ondisk_t alloc_btree_node(hammer_off_t *offp, 138c17fa600STomohiro Kusumi buffer_info_t *data_bufferp); 13991e559fdSTomohiro Kusumi void *alloc_meta_element(hammer_off_t *offp, int32_t data_len, 140c17fa600STomohiro Kusumi buffer_info_t *data_bufferp); 1412dba5fa7STomohiro Kusumi void format_blockmap(volume_info_t root_vol, int zone, hammer_off_t offset); 1422dba5fa7STomohiro Kusumi void format_freemap(volume_info_t root_vol); 1432dba5fa7STomohiro Kusumi int64_t initialize_freemap(volume_info_t volume); 144e8a2b543STomohiro Kusumi int64_t count_freemap(const volume_info_t volume); 1452dba5fa7STomohiro Kusumi void format_undomap(volume_info_t root_vol, int64_t *undo_buffer_size); 1462dba5fa7STomohiro Kusumi void print_blockmap(const volume_info_t volume); 14791e559fdSTomohiro Kusumi void flush_all_volumes(void); 1482dba5fa7STomohiro Kusumi void flush_volume(volume_info_t volume); 149c17fa600STomohiro Kusumi void flush_buffer(buffer_info_t buffer); 15091e559fdSTomohiro Kusumi int64_t init_boot_area_size(int64_t value, off_t avg_vol_size); 15191e559fdSTomohiro Kusumi int64_t init_memory_log_size(int64_t value, off_t avg_vol_size); 15261aeeb33SMatthew Dillon 1532dba5fa7STomohiro Kusumi hammer_off_t bootstrap_bigblock(volume_info_t volume); 1542dba5fa7STomohiro Kusumi hammer_off_t alloc_undo_bigblock(volume_info_t volume); 15586872a2aSTomohiro Kusumi void *alloc_blockmap(int zone, int bytes, hammer_off_t *result_offp, 156c17fa600STomohiro Kusumi buffer_info_t *bufferp); 1578b916bc2STomohiro Kusumi hammer_off_t blockmap_lookup(hammer_off_t bmap_off, int *errorp); 1588b916bc2STomohiro Kusumi hammer_off_t blockmap_lookup_save(hammer_off_t bmap_off, 15921e9e7d5STomohiro Kusumi hammer_blockmap_layer1_t layer1, 16021e9e7d5STomohiro Kusumi hammer_blockmap_layer2_t layer2, 1616ed4c886SMatthew Dillon int *errorp); 162f819215cSTomohiro Kusumi 16325ee129eSTomohiro Kusumi int hammer_parse_cache_size(const char *arg); 16478418745STomohiro Kusumi void hammer_cache_add(cache_info_t cache); 16578418745STomohiro Kusumi void hammer_cache_del(cache_info_t cache); 16678418745STomohiro Kusumi void hammer_cache_used(cache_info_t cache); 16761aeeb33SMatthew Dillon void hammer_cache_flush(void); 16861aeeb33SMatthew Dillon 169044711a6STomohiro Kusumi void hammer_key_beg_init(hammer_base_elm_t base); 170044711a6STomohiro Kusumi void hammer_key_end_init(hammer_base_elm_t base); 171f3f3fa72STomohiro Kusumi int getyn(void); 172f3f3fa72STomohiro Kusumi const char *sizetostr(off_t size); 173f3f3fa72STomohiro Kusumi int hammer_fs_to_vol(const char *fs, struct hammer_ioc_volume_list *iocp); 174f3f3fa72STomohiro Kusumi int hammer_fs_to_rootvol(const char *fs, char *buf, int len); 17564321bafSTomohiro Kusumi zone_stat_t hammer_init_zone_stat(void); 17664321bafSTomohiro Kusumi zone_stat_t hammer_init_zone_stat_bits(void); 17764321bafSTomohiro Kusumi void hammer_cleanup_zone_stat(zone_stat_t stats); 17864321bafSTomohiro Kusumi void hammer_add_zone_stat(zone_stat_t stats, hammer_off_t offset, int bytes); 17964321bafSTomohiro Kusumi void hammer_add_zone_stat_layer2(zone_stat_t stats, 18021e9e7d5STomohiro Kusumi hammer_blockmap_layer2_t layer2); 18164321bafSTomohiro Kusumi void hammer_print_zone_stat(const zone_stat_t stats); 182a74dc250STomohiro Kusumi 18390da8fc8STomohiro Kusumi void hammer_uuid_create(hammer_uuid_t *uuid); 18490da8fc8STomohiro Kusumi int hammer_uuid_from_string(const char *str, hammer_uuid_t *uuid); 18590da8fc8STomohiro Kusumi int hammer_uuid_to_string(const hammer_uuid_t *uuid, char **str); 186bbe85e92STomohiro Kusumi int hammer_uuid_name_lookup(hammer_uuid_t *uuid, const char *str); 18790da8fc8STomohiro Kusumi int hammer_uuid_compare(const hammer_uuid_t *uuid1, const hammer_uuid_t *uuid2); 1883cd578edSTomohiro Kusumi 18995f03e3eSTomohiro Kusumi #define hwarn(format, args...) warn("WARNING: "format,## args) 19095f03e3eSTomohiro Kusumi #define hwarnx(format, args...) warnx("WARNING: "format,## args) 19195f03e3eSTomohiro Kusumi 192a74dc250STomohiro Kusumi #endif /* !HAMMER_UTIL_H_ */ 193