15cabbc6Prashanth Sreenivasa/*
25cabbc6Prashanth Sreenivasa * CDDL HEADER START
35cabbc6Prashanth Sreenivasa *
45cabbc6Prashanth Sreenivasa * This file and its contents are supplied under the terms of the
55cabbc6Prashanth Sreenivasa * Common Development and Distribution License ("CDDL"), version 1.0.
65cabbc6Prashanth Sreenivasa * You may only use this file in accordance with the terms of version
75cabbc6Prashanth Sreenivasa * 1.0 of the CDDL.
85cabbc6Prashanth Sreenivasa *
95cabbc6Prashanth Sreenivasa * A full copy of the text of the CDDL should have accompanied this
105cabbc6Prashanth Sreenivasa * source.  A copy of the CDDL is also available via the Internet at
115cabbc6Prashanth Sreenivasa * http://www.illumos.org/license/CDDL.
125cabbc6Prashanth Sreenivasa *
135cabbc6Prashanth Sreenivasa * CDDL HEADER END
145cabbc6Prashanth Sreenivasa */
155cabbc6Prashanth Sreenivasa
165cabbc6Prashanth Sreenivasa/*
175cabbc6Prashanth Sreenivasa * Copyright (c) 2015 by Delphix. All rights reserved.
185cabbc6Prashanth Sreenivasa */
195cabbc6Prashanth Sreenivasa
205cabbc6Prashanth Sreenivasa#ifndef	_SYS_VDEV_INDIRECT_MAPPING_H
215cabbc6Prashanth Sreenivasa#define	_SYS_VDEV_INDIRECT_MAPPING_H
225cabbc6Prashanth Sreenivasa
235cabbc6Prashanth Sreenivasa#include <sys/dmu.h>
245cabbc6Prashanth Sreenivasa#include <sys/list.h>
255cabbc6Prashanth Sreenivasa#include <sys/spa.h>
265cabbc6Prashanth Sreenivasa#include <sys/space_map.h>
275cabbc6Prashanth Sreenivasa
285cabbc6Prashanth Sreenivasa#ifdef	__cplusplus
295cabbc6Prashanth Sreenivasaextern "C" {
305cabbc6Prashanth Sreenivasa#endif
315cabbc6Prashanth Sreenivasa
325cabbc6Prashanth Sreenivasatypedef struct vdev_indirect_mapping_entry_phys {
335cabbc6Prashanth Sreenivasa	/*
345cabbc6Prashanth Sreenivasa	 * Decode with DVA_MAPPING_* macros.
355cabbc6Prashanth Sreenivasa	 * Contains:
365cabbc6Prashanth Sreenivasa	 *   the source offset (low 63 bits)
375cabbc6Prashanth Sreenivasa	 *   the one-bit "mark", used for garbage collection (by zdb)
385cabbc6Prashanth Sreenivasa	 */
395cabbc6Prashanth Sreenivasa	uint64_t vimep_src;
405cabbc6Prashanth Sreenivasa
415cabbc6Prashanth Sreenivasa	/*
425cabbc6Prashanth Sreenivasa	 * Note: the DVA's asize is 24 bits, and can thus store ranges
435cabbc6Prashanth Sreenivasa	 * up to 8GB.
445cabbc6Prashanth Sreenivasa	 */
455cabbc6Prashanth Sreenivasa	dva_t	vimep_dst;
465cabbc6Prashanth Sreenivasa} vdev_indirect_mapping_entry_phys_t;
475cabbc6Prashanth Sreenivasa
485cabbc6Prashanth Sreenivasa#define	DVA_MAPPING_GET_SRC_OFFSET(vimep)	\
495cabbc6Prashanth Sreenivasa	BF64_GET_SB((vimep)->vimep_src, 0, 63, SPA_MINBLOCKSHIFT, 0)
505cabbc6Prashanth Sreenivasa#define	DVA_MAPPING_SET_SRC_OFFSET(vimep, x)	\
515cabbc6Prashanth Sreenivasa	BF64_SET_SB((vimep)->vimep_src, 0, 63, SPA_MINBLOCKSHIFT, 0, x)
525cabbc6Prashanth Sreenivasa
535cabbc6Prashanth Sreenivasatypedef struct vdev_indirect_mapping_entry {
545cabbc6Prashanth Sreenivasa	vdev_indirect_mapping_entry_phys_t	vime_mapping;
555cabbc6Prashanth Sreenivasa	uint32_t				vime_obsolete_count;
565cabbc6Prashanth Sreenivasa	list_node_t				vime_node;
575cabbc6Prashanth Sreenivasa} vdev_indirect_mapping_entry_t;
585cabbc6Prashanth Sreenivasa
595cabbc6Prashanth Sreenivasa/*
605cabbc6Prashanth Sreenivasa * This is stored in the bonus buffer of the mapping object, see comment of
615cabbc6Prashanth Sreenivasa * vdev_indirect_config for more details.
625cabbc6Prashanth Sreenivasa */
635cabbc6Prashanth Sreenivasatypedef struct vdev_indirect_mapping_phys {
645cabbc6Prashanth Sreenivasa	uint64_t	vimp_max_offset;
655cabbc6Prashanth Sreenivasa	uint64_t	vimp_bytes_mapped;
665cabbc6Prashanth Sreenivasa	uint64_t	vimp_num_entries; /* number of v_i_m_entry_phys_t's */
675cabbc6Prashanth Sreenivasa
685cabbc6Prashanth Sreenivasa	/*
695cabbc6Prashanth Sreenivasa	 * For each entry in the mapping object, this object contains an
705cabbc6Prashanth Sreenivasa	 * entry representing the number of bytes of that mapping entry
715cabbc6Prashanth Sreenivasa	 * that were no longer in use by the pool at the time this indirect
725cabbc6Prashanth Sreenivasa	 * vdev was last condensed.
735cabbc6Prashanth Sreenivasa	 */
745cabbc6Prashanth Sreenivasa	uint64_t	vimp_counts_object;
755cabbc6Prashanth Sreenivasa} vdev_indirect_mapping_phys_t;
765cabbc6Prashanth Sreenivasa
775cabbc6Prashanth Sreenivasa#define	VDEV_INDIRECT_MAPPING_SIZE_V0	(3 * sizeof (uint64_t))
785cabbc6Prashanth Sreenivasa
795cabbc6Prashanth Sreenivasatypedef struct vdev_indirect_mapping {
805cabbc6Prashanth Sreenivasa	uint64_t	vim_object;
815cabbc6Prashanth Sreenivasa	boolean_t	vim_havecounts;
825cabbc6Prashanth Sreenivasa
835cabbc6Prashanth Sreenivasa	/*
845cabbc6Prashanth Sreenivasa	 * An ordered array of all mapping entries, sorted by source offset.
855cabbc6Prashanth Sreenivasa	 * Note that vim_entries is needed during a removal (and contains
865cabbc6Prashanth Sreenivasa	 * mappings that have been synced to disk so far) to handle frees
875cabbc6Prashanth Sreenivasa	 * from the removing device.
885cabbc6Prashanth Sreenivasa	 */
895cabbc6Prashanth Sreenivasa	vdev_indirect_mapping_entry_phys_t *vim_entries;
905cabbc6Prashanth Sreenivasa
915cabbc6Prashanth Sreenivasa	objset_t	*vim_objset;
925cabbc6Prashanth Sreenivasa
935cabbc6Prashanth Sreenivasa	dmu_buf_t	*vim_dbuf;
945cabbc6Prashanth Sreenivasa	vdev_indirect_mapping_phys_t	*vim_phys;
955cabbc6Prashanth Sreenivasa} vdev_indirect_mapping_t;
965cabbc6Prashanth Sreenivasa
975cabbc6Prashanth Sreenivasaextern vdev_indirect_mapping_t *vdev_indirect_mapping_open(objset_t *os,
985cabbc6Prashanth Sreenivasa    uint64_t object);
995cabbc6Prashanth Sreenivasaextern void vdev_indirect_mapping_close(vdev_indirect_mapping_t *vim);
1005cabbc6Prashanth Sreenivasaextern uint64_t vdev_indirect_mapping_alloc(objset_t *os, dmu_tx_t *tx);
1015cabbc6Prashanth Sreenivasaextern void vdev_indirect_mapping_free(objset_t *os, uint64_t obj,
1025cabbc6Prashanth Sreenivasa    dmu_tx_t *tx);
1035cabbc6Prashanth Sreenivasa
1045cabbc6Prashanth Sreenivasaextern uint64_t vdev_indirect_mapping_num_entries(vdev_indirect_mapping_t *vim);
1055cabbc6Prashanth Sreenivasaextern uint64_t vdev_indirect_mapping_max_offset(vdev_indirect_mapping_t *vim);
1065cabbc6Prashanth Sreenivasaextern uint64_t vdev_indirect_mapping_object(vdev_indirect_mapping_t *vim);
1075cabbc6Prashanth Sreenivasaextern uint64_t vdev_indirect_mapping_bytes_mapped(
1085cabbc6Prashanth Sreenivasa    vdev_indirect_mapping_t *vim);
1095cabbc6Prashanth Sreenivasaextern uint64_t vdev_indirect_mapping_size(vdev_indirect_mapping_t *vim);
1105cabbc6Prashanth Sreenivasa
1115cabbc6Prashanth Sreenivasa/*
1125cabbc6Prashanth Sreenivasa * Writes the given list of vdev_indirect_mapping_entry_t to the mapping
1135cabbc6Prashanth Sreenivasa * then updates internal state.
1145cabbc6Prashanth Sreenivasa */
1155cabbc6Prashanth Sreenivasaextern void vdev_indirect_mapping_add_entries(vdev_indirect_mapping_t *vim,
1165cabbc6Prashanth Sreenivasa    list_t *vime_list, dmu_tx_t *tx);
1175cabbc6Prashanth Sreenivasa
1185cabbc6Prashanth Sreenivasaextern vdev_indirect_mapping_entry_phys_t *
1195cabbc6Prashanth Sreenivasa    vdev_indirect_mapping_entry_for_offset(vdev_indirect_mapping_t *vim,
1205cabbc6Prashanth Sreenivasa    uint64_t offset);
1215cabbc6Prashanth Sreenivasa
1225cabbc6Prashanth Sreenivasaextern vdev_indirect_mapping_entry_phys_t *
1235cabbc6Prashanth Sreenivasa    vdev_indirect_mapping_entry_for_offset_or_next(vdev_indirect_mapping_t *vim,
1245cabbc6Prashanth Sreenivasa    uint64_t offset);
1255cabbc6Prashanth Sreenivasa
1265cabbc6Prashanth Sreenivasaextern uint32_t *vdev_indirect_mapping_load_obsolete_counts(
1275cabbc6Prashanth Sreenivasa    vdev_indirect_mapping_t *vim);
1285cabbc6Prashanth Sreenivasaextern void vdev_indirect_mapping_load_obsolete_spacemap(
1295cabbc6Prashanth Sreenivasa    vdev_indirect_mapping_t *vim,
1305cabbc6Prashanth Sreenivasa    uint32_t *counts, space_map_t *obsolete_space_sm);
1315cabbc6Prashanth Sreenivasaextern void vdev_indirect_mapping_increment_obsolete_count(
1325cabbc6Prashanth Sreenivasa    vdev_indirect_mapping_t *vim,
1335cabbc6Prashanth Sreenivasa    uint64_t offset, uint64_t asize, uint32_t *counts);
1345cabbc6Prashanth Sreenivasaextern void vdev_indirect_mapping_free_obsolete_counts(
1355cabbc6Prashanth Sreenivasa    vdev_indirect_mapping_t *vim, uint32_t *counts);
1365cabbc6Prashanth Sreenivasa
1375cabbc6Prashanth Sreenivasa#ifdef	__cplusplus
1385cabbc6Prashanth Sreenivasa}
1395cabbc6Prashanth Sreenivasa#endif
1405cabbc6Prashanth Sreenivasa
1415cabbc6Prashanth Sreenivasa#endif	/* _SYS_VDEV_INDIRECT_MAPPING_H */
142