#ifndef _MAKEFS_ZFS_H_
#define _MAKEFS_ZFS_H_
#include <sys/types.h>
#include <sys/endian.h>
#include <sys/queue.h>
#include <bitstring.h>
#include <stdalign.h>
#include <stdbool.h>
#include "makefs.h"
#include "zfs/nvlist.h"
#define ASSERT assert
#include "zfs/zfsimpl.h"
#define MAXBLOCKSHIFT 17
#define MAXBLOCKSIZE ((off_t)(1 << MAXBLOCKSHIFT))
_Static_assert(MAXBLOCKSIZE == SPA_OLDMAXBLOCKSIZE, "");
#define MINBLOCKSHIFT 9
#define MINBLOCKSIZE ((off_t)(1 << MINBLOCKSHIFT))
_Static_assert(MINBLOCKSIZE == SPA_MINBLOCKSIZE, "");
#define MINDEVSIZE ((off_t)SPA_MINDEVSIZE)
#define TXG 4
#define TXG_SIZE 4
typedef struct zfs_dsl_dataset zfs_dsl_dataset_t;
typedef struct zfs_dsl_dir zfs_dsl_dir_t;
typedef struct zfs_objset zfs_objset_t;
typedef struct zfs_zap zfs_zap_t;
struct dataset_desc {
char *params;
STAILQ_ENTRY(dataset_desc) next;
};
typedef struct {
char filebuf[MAXBLOCKSIZE] __aligned(alignof(uint64_t));
bool nowarn;
const char *poolname;
char *rootpath;
char *bootfs;
int ashift;
uint64_t mssize;
STAILQ_HEAD(, dataset_desc) datasetdescs;
bool verify_txgs;
uint64_t poolguid;
zfs_zap_t *poolprops;
zfs_objset_t *mos;
uint64_t objarrid;
zfs_dsl_dir_t *rootdsldir;
zfs_dsl_dataset_t *rootds;
zfs_dsl_dir_t *origindsldir;
zfs_dsl_dataset_t *originds;
zfs_dsl_dataset_t *snapds;
zfs_zap_t *cloneszap;
zfs_dsl_dir_t *freedsldir;
zfs_dsl_dir_t *mosdsldir;
int fd;
uint64_t vdevguid;
off_t vdevsize;
off_t asize;
bitstr_t *spacemap;
int spacemapbits;
uint64_t msshift;
uint64_t mscount;
} zfs_opt_t;
void dsl_init(zfs_opt_t *);
const char *dsl_dir_fullname(const zfs_dsl_dir_t *);
uint64_t dsl_dir_id(zfs_dsl_dir_t *);
uint64_t dsl_dir_dataset_id(zfs_dsl_dir_t *);
void dsl_dir_foreach(zfs_opt_t *, zfs_dsl_dir_t *,
void (*)(zfs_opt_t *, zfs_dsl_dir_t *, void *), void *);
int dsl_dir_get_canmount(zfs_dsl_dir_t *, uint64_t *);
char *dsl_dir_get_mountpoint(zfs_opt_t *, zfs_dsl_dir_t *);
bool dsl_dir_has_dataset(zfs_dsl_dir_t *);
bool dsl_dir_dataset_has_objset(zfs_dsl_dir_t *);
void dsl_dir_dataset_write(zfs_opt_t *, zfs_objset_t *, zfs_dsl_dir_t *);
void dsl_dir_root_finalize(zfs_opt_t *, uint64_t);
void dsl_write(zfs_opt_t *);
void fs_build(zfs_opt_t *, int, fsnode *);
zfs_objset_t *objset_alloc(zfs_opt_t *zfs, uint64_t type);
off_t objset_space_alloc(zfs_opt_t *, zfs_objset_t *, off_t *);
dnode_phys_t *objset_dnode_alloc(zfs_objset_t *, uint8_t, uint64_t *);
dnode_phys_t *objset_dnode_bonus_alloc(zfs_objset_t *, uint8_t, uint8_t,
uint16_t, uint64_t *);
dnode_phys_t *objset_dnode_lookup(zfs_objset_t *, uint64_t);
void objset_root_blkptr_copy(const zfs_objset_t *, blkptr_t *);
uint64_t objset_space(const zfs_objset_t *);
void objset_write(zfs_opt_t *zfs, zfs_objset_t *os);
void vdev_init(zfs_opt_t *, const char *);
off_t vdev_space_alloc(zfs_opt_t *zfs, off_t *lenp);
void vdev_pwrite_data(zfs_opt_t *zfs, uint8_t datatype, uint8_t cksumtype,
uint8_t level, uint64_t fill, const void *data, off_t sz, off_t loc,
blkptr_t *bp);
void vdev_pwrite_dnode_indir(zfs_opt_t *zfs, dnode_phys_t *dnode, uint8_t level,
uint64_t fill, const void *data, off_t sz, off_t loc, blkptr_t *bp);
void vdev_pwrite_dnode_data(zfs_opt_t *zfs, dnode_phys_t *dnode, const void *data,
off_t sz, off_t loc);
void vdev_label_write(zfs_opt_t *zfs, int ind, const vdev_label_t *labelp);
void vdev_spacemap_write(zfs_opt_t *);
void vdev_fini(zfs_opt_t *zfs);
zfs_zap_t *zap_alloc(zfs_objset_t *, dnode_phys_t *);
void zap_add(zfs_zap_t *, const char *, size_t, size_t, const uint8_t *);
void zap_add_uint64(zfs_zap_t *, const char *, uint64_t);
void zap_add_uint64_self(zfs_zap_t *, uint64_t);
void zap_add_string(zfs_zap_t *, const char *, const char *);
bool zap_entry_exists(zfs_zap_t *, const char *);
void zap_write(zfs_opt_t *, zfs_zap_t *);
struct dnode_cursor *dnode_cursor_init(zfs_opt_t *, zfs_objset_t *,
dnode_phys_t *, off_t, off_t);
blkptr_t *dnode_cursor_next(zfs_opt_t *, struct dnode_cursor *, off_t);
void dnode_cursor_finish(zfs_opt_t *, struct dnode_cursor *);
uint64_t randomguid(void);
#endif