142 lines
4.4 KiB
C
142 lines
4.4 KiB
C
/*
|
|
* CDDL HEADER START
|
|
*
|
|
* This file and its contents are supplied under the terms of the
|
|
* Common Development and Distribution License ("CDDL"), version 1.0.
|
|
* You may only use this file in accordance with the terms of version
|
|
* 1.0 of the CDDL.
|
|
*
|
|
* A full copy of the text of the CDDL should have accompanied this
|
|
* source. A copy of the CDDL is also available via the Internet at
|
|
* http://www.illumos.org/license/CDDL.
|
|
*
|
|
* CDDL HEADER END
|
|
*/
|
|
|
|
/*
|
|
* Copyright (c) 2015 by Delphix. All rights reserved.
|
|
*/
|
|
|
|
#ifndef _SYS_VDEV_INDIRECT_MAPPING_H
|
|
#define _SYS_VDEV_INDIRECT_MAPPING_H
|
|
|
|
#include <sys/dmu.h>
|
|
#include <sys/list.h>
|
|
#include <sys/spa.h>
|
|
#include <sys/space_map.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
typedef struct vdev_indirect_mapping_entry_phys {
|
|
/*
|
|
* Decode with DVA_MAPPING_* macros.
|
|
* Contains:
|
|
* the source offset (low 63 bits)
|
|
* the one-bit "mark", used for garbage collection (by zdb)
|
|
*/
|
|
uint64_t vimep_src;
|
|
|
|
/*
|
|
* Note: the DVA's asize is 24 bits, and can thus store ranges
|
|
* up to 8GB.
|
|
*/
|
|
dva_t vimep_dst;
|
|
} vdev_indirect_mapping_entry_phys_t;
|
|
|
|
#define DVA_MAPPING_GET_SRC_OFFSET(vimep) \
|
|
BF64_GET_SB((vimep)->vimep_src, 0, 63, SPA_MINBLOCKSHIFT, 0)
|
|
#define DVA_MAPPING_SET_SRC_OFFSET(vimep, x) \
|
|
BF64_SET_SB((vimep)->vimep_src, 0, 63, SPA_MINBLOCKSHIFT, 0, x)
|
|
|
|
typedef struct vdev_indirect_mapping_entry {
|
|
vdev_indirect_mapping_entry_phys_t vime_mapping;
|
|
uint32_t vime_obsolete_count;
|
|
list_node_t vime_node;
|
|
} vdev_indirect_mapping_entry_t;
|
|
|
|
/*
|
|
* This is stored in the bonus buffer of the mapping object, see comment of
|
|
* vdev_indirect_config for more details.
|
|
*/
|
|
typedef struct vdev_indirect_mapping_phys {
|
|
uint64_t vimp_max_offset;
|
|
uint64_t vimp_bytes_mapped;
|
|
uint64_t vimp_num_entries; /* number of v_i_m_entry_phys_t's */
|
|
|
|
/*
|
|
* For each entry in the mapping object, this object contains an
|
|
* entry representing the number of bytes of that mapping entry
|
|
* that were no longer in use by the pool at the time this indirect
|
|
* vdev was last condensed.
|
|
*/
|
|
uint64_t vimp_counts_object;
|
|
} vdev_indirect_mapping_phys_t;
|
|
|
|
#define VDEV_INDIRECT_MAPPING_SIZE_V0 (3 * sizeof (uint64_t))
|
|
|
|
typedef struct vdev_indirect_mapping {
|
|
uint64_t vim_object;
|
|
boolean_t vim_havecounts;
|
|
|
|
/*
|
|
* An ordered array of all mapping entries, sorted by source offset.
|
|
* Note that vim_entries is needed during a removal (and contains
|
|
* mappings that have been synced to disk so far) to handle frees
|
|
* from the removing device.
|
|
*/
|
|
vdev_indirect_mapping_entry_phys_t *vim_entries;
|
|
|
|
objset_t *vim_objset;
|
|
|
|
dmu_buf_t *vim_dbuf;
|
|
vdev_indirect_mapping_phys_t *vim_phys;
|
|
} vdev_indirect_mapping_t;
|
|
|
|
extern vdev_indirect_mapping_t *vdev_indirect_mapping_open(objset_t *os,
|
|
uint64_t object);
|
|
extern void vdev_indirect_mapping_close(vdev_indirect_mapping_t *vim);
|
|
extern uint64_t vdev_indirect_mapping_alloc(objset_t *os, dmu_tx_t *tx);
|
|
extern void vdev_indirect_mapping_free(objset_t *os, uint64_t obj,
|
|
dmu_tx_t *tx);
|
|
|
|
extern uint64_t vdev_indirect_mapping_num_entries(vdev_indirect_mapping_t *vim);
|
|
extern uint64_t vdev_indirect_mapping_max_offset(vdev_indirect_mapping_t *vim);
|
|
extern uint64_t vdev_indirect_mapping_object(vdev_indirect_mapping_t *vim);
|
|
extern uint64_t vdev_indirect_mapping_bytes_mapped(
|
|
vdev_indirect_mapping_t *vim);
|
|
extern uint64_t vdev_indirect_mapping_size(vdev_indirect_mapping_t *vim);
|
|
|
|
/*
|
|
* Writes the given list of vdev_indirect_mapping_entry_t to the mapping
|
|
* then updates internal state.
|
|
*/
|
|
extern void vdev_indirect_mapping_add_entries(vdev_indirect_mapping_t *vim,
|
|
list_t *vime_list, dmu_tx_t *tx);
|
|
|
|
extern vdev_indirect_mapping_entry_phys_t *
|
|
vdev_indirect_mapping_entry_for_offset(vdev_indirect_mapping_t *vim,
|
|
uint64_t offset);
|
|
|
|
extern vdev_indirect_mapping_entry_phys_t *
|
|
vdev_indirect_mapping_entry_for_offset_or_next(vdev_indirect_mapping_t *vim,
|
|
uint64_t offset);
|
|
|
|
extern uint32_t *vdev_indirect_mapping_load_obsolete_counts(
|
|
vdev_indirect_mapping_t *vim);
|
|
extern void vdev_indirect_mapping_load_obsolete_spacemap(
|
|
vdev_indirect_mapping_t *vim,
|
|
uint32_t *counts, space_map_t *obsolete_space_sm);
|
|
extern void vdev_indirect_mapping_increment_obsolete_count(
|
|
vdev_indirect_mapping_t *vim,
|
|
uint64_t offset, uint64_t asize, uint32_t *counts);
|
|
extern void vdev_indirect_mapping_free_obsolete_counts(
|
|
vdev_indirect_mapping_t *vim, uint32_t *counts);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* _SYS_VDEV_INDIRECT_MAPPING_H */
|