1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2022 The FreeBSD Foundation 5 * 6 * This software was developed by Mark Johnston under sponsorship from 7 * the FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions are 11 * met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #ifndef _MAKEFS_ZFS_H_ 32 #define _MAKEFS_ZFS_H_ 33 34 #include <sys/types.h> 35 #include <sys/endian.h> 36 #include <sys/queue.h> 37 38 #include <bitstring.h> 39 #include <stdalign.h> 40 #include <stdbool.h> 41 42 #include "makefs.h" 43 44 #include "zfs/nvlist.h" 45 #define ASSERT assert 46 #include "zfs/zfsimpl.h" 47 48 #define MAXBLOCKSHIFT 17 /* 128KB */ 49 #define MAXBLOCKSIZE ((off_t)(1 << MAXBLOCKSHIFT)) 50 _Static_assert(MAXBLOCKSIZE == SPA_OLDMAXBLOCKSIZE, ""); 51 #define MINBLOCKSHIFT 9 /* 512B */ 52 #define MINBLOCKSIZE ((off_t)(1 << MINBLOCKSHIFT)) 53 _Static_assert(MINBLOCKSIZE == SPA_MINBLOCKSIZE, ""); 54 #define MINDEVSIZE ((off_t)SPA_MINDEVSIZE) 55 56 /* All data was written in this transaction group. */ 57 #define TXG 4 58 #define TXG_SIZE 4 59 60 typedef struct zfs_dsl_dataset zfs_dsl_dataset_t; 61 typedef struct zfs_dsl_dir zfs_dsl_dir_t; 62 typedef struct zfs_objset zfs_objset_t; 63 typedef struct zfs_zap zfs_zap_t; 64 65 struct dataset_desc { 66 char *params; 67 STAILQ_ENTRY(dataset_desc) next; 68 }; 69 70 typedef struct { 71 /* 72 * Block buffer, needs to be aligned for various on-disk structures, 73 * ZAPs, etc.. 74 */ 75 char filebuf[MAXBLOCKSIZE] __aligned(alignof(uint64_t)); 76 77 bool nowarn; /* ignored */ 78 79 /* Pool parameters. */ 80 const char *poolname; 81 char *rootpath; /* implicit mount point prefix */ 82 char *vdevpath; /* vdev path, pool property */ 83 char *bootfs; /* bootable dataset, pool property */ 84 int ashift; /* vdev block size */ 85 uint64_t mssize; /* metaslab size */ 86 STAILQ_HEAD(, dataset_desc) datasetdescs; /* non-root dataset descrs */ 87 bool verify_txgs; /* verify data upon import */ 88 89 /* Pool state. */ 90 uint64_t poolguid; /* pool and root vdev GUID */ 91 zfs_zap_t *poolprops; 92 93 /* MOS state. */ 94 zfs_objset_t *mos; /* meta object set */ 95 uint64_t objarrid; /* space map object array */ 96 97 /* DSL state. */ 98 zfs_dsl_dir_t *rootdsldir; /* root DSL directory */ 99 zfs_dsl_dataset_t *rootds; 100 zfs_dsl_dir_t *origindsldir; /* $ORIGIN */ 101 zfs_dsl_dataset_t *originds; 102 zfs_dsl_dataset_t *snapds; 103 zfs_zap_t *cloneszap; 104 zfs_dsl_dir_t *freedsldir; /* $FREE */ 105 zfs_dsl_dir_t *mosdsldir; /* $MOS */ 106 107 /* vdev state. */ 108 int fd; /* vdev disk fd */ 109 uint64_t vdevguid; /* disk vdev GUID */ 110 off_t vdevsize; /* vdev size, including labels */ 111 off_t asize; /* vdev size, excluding labels */ 112 bitstr_t *spacemap; /* space allocation tracking */ 113 int spacemapbits; /* one bit per ashift-sized block */ 114 uint64_t msshift; /* log2(metaslab size) */ 115 uint64_t mscount; /* number of metaslabs for this vdev */ 116 } zfs_opt_t; 117 118 /* dsl.c */ 119 void dsl_init(zfs_opt_t *); 120 const char *dsl_dir_fullname(const zfs_dsl_dir_t *); 121 uint64_t dsl_dir_id(zfs_dsl_dir_t *); 122 uint64_t dsl_dir_dataset_id(zfs_dsl_dir_t *); 123 void dsl_dir_foreach(zfs_opt_t *, zfs_dsl_dir_t *, 124 void (*)(zfs_opt_t *, zfs_dsl_dir_t *, void *), void *); 125 int dsl_dir_get_canmount(zfs_dsl_dir_t *, uint64_t *); 126 char *dsl_dir_get_mountpoint(zfs_opt_t *, zfs_dsl_dir_t *); 127 bool dsl_dir_has_dataset(zfs_dsl_dir_t *); 128 bool dsl_dir_dataset_has_objset(zfs_dsl_dir_t *); 129 void dsl_dir_dataset_write(zfs_opt_t *, zfs_objset_t *, zfs_dsl_dir_t *); 130 void dsl_dir_root_finalize(zfs_opt_t *, uint64_t); 131 void dsl_write(zfs_opt_t *); 132 133 /* fs.c */ 134 void fs_build(zfs_opt_t *, int, fsnode *); 135 136 /* objset.c */ 137 zfs_objset_t *objset_alloc(zfs_opt_t *zfs, uint64_t type); 138 off_t objset_space_alloc(zfs_opt_t *, zfs_objset_t *, off_t *); 139 dnode_phys_t *objset_dnode_alloc(zfs_objset_t *, uint8_t, uint64_t *); 140 dnode_phys_t *objset_dnode_bonus_alloc(zfs_objset_t *, uint8_t, uint8_t, 141 uint16_t, uint64_t *); 142 dnode_phys_t *objset_dnode_lookup(zfs_objset_t *, uint64_t); 143 void objset_root_blkptr_copy(const zfs_objset_t *, blkptr_t *); 144 uint64_t objset_space(const zfs_objset_t *); 145 void objset_write(zfs_opt_t *zfs, zfs_objset_t *os); 146 147 /* vdev.c */ 148 void vdev_init(zfs_opt_t *, const char *); 149 off_t vdev_space_alloc(zfs_opt_t *zfs, off_t *lenp); 150 void vdev_pwrite_data(zfs_opt_t *zfs, uint8_t datatype, uint8_t cksumtype, 151 uint8_t level, uint64_t fill, const void *data, off_t sz, off_t loc, 152 blkptr_t *bp); 153 void vdev_pwrite_dnode_indir(zfs_opt_t *zfs, dnode_phys_t *dnode, uint8_t level, 154 uint64_t fill, const void *data, off_t sz, off_t loc, blkptr_t *bp); 155 void vdev_pwrite_dnode_data(zfs_opt_t *zfs, dnode_phys_t *dnode, const void *data, 156 off_t sz, off_t loc); 157 void vdev_label_write(zfs_opt_t *zfs, int ind, const vdev_label_t *labelp); 158 void vdev_spacemap_write(zfs_opt_t *); 159 void vdev_fini(zfs_opt_t *zfs); 160 161 /* zap.c */ 162 zfs_zap_t *zap_alloc(zfs_objset_t *, dnode_phys_t *); 163 void zap_add(zfs_zap_t *, const char *, size_t, size_t, const uint8_t *); 164 void zap_add_uint64(zfs_zap_t *, const char *, uint64_t); 165 void zap_add_uint64_self(zfs_zap_t *, uint64_t); 166 void zap_add_string(zfs_zap_t *, const char *, const char *); 167 bool zap_entry_exists(zfs_zap_t *, const char *); 168 void zap_write(zfs_opt_t *, zfs_zap_t *); 169 170 /* zfs.c */ 171 struct dnode_cursor *dnode_cursor_init(zfs_opt_t *, zfs_objset_t *, 172 dnode_phys_t *, off_t, off_t); 173 blkptr_t *dnode_cursor_next(zfs_opt_t *, struct dnode_cursor *, off_t); 174 void dnode_cursor_finish(zfs_opt_t *, struct dnode_cursor *); 175 uint64_t randomguid(void); 176 177 #endif /* !_MAKEFS_ZFS_H_ */ 178