]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_indirect_mapping.h
MFV r329502: 7614 zfs device evacuation/removal
[FreeBSD/FreeBSD.git] / sys / cddl / contrib / opensolaris / uts / common / fs / zfs / sys / vdev_indirect_mapping.h
1 /*
2  * CDDL HEADER START
3  *
4  * This file and its contents are supplied under the terms of the
5  * Common Development and Distribution License ("CDDL"), version 1.0.
6  * You may only use this file in accordance with the terms of version
7  * 1.0 of the CDDL.
8  *
9  * A full copy of the text of the CDDL should have accompanied this
10  * source.  A copy of the CDDL is also available via the Internet at
11  * http://www.illumos.org/license/CDDL.
12  *
13  * CDDL HEADER END
14  */
15
16 /*
17  * Copyright (c) 2015 by Delphix. All rights reserved.
18  */
19
20 #ifndef _SYS_VDEV_INDIRECT_MAPPING_H
21 #define _SYS_VDEV_INDIRECT_MAPPING_H
22
23 #include <sys/dmu.h>
24 #include <sys/list.h>
25 #include <sys/spa.h>
26 #include <sys/space_map.h>
27
28 #ifdef  __cplusplus
29 extern "C" {
30 #endif
31
32 typedef struct vdev_indirect_mapping_entry_phys {
33         /*
34          * Decode with DVA_MAPPING_* macros.
35          * Contains:
36          *   the source offset (low 63 bits)
37          *   the one-bit "mark", used for garbage collection (by zdb)
38          */
39         uint64_t vimep_src;
40
41         /*
42          * Note: the DVA's asize is 24 bits, and can thus store ranges
43          * up to 8GB.
44          */
45         dva_t   vimep_dst;
46 } vdev_indirect_mapping_entry_phys_t;
47
48 #define DVA_MAPPING_GET_SRC_OFFSET(vimep)       \
49         BF64_GET_SB((vimep)->vimep_src, 0, 63, SPA_MINBLOCKSHIFT, 0)
50 #define DVA_MAPPING_SET_SRC_OFFSET(vimep, x)    \
51         BF64_SET_SB((vimep)->vimep_src, 0, 63, SPA_MINBLOCKSHIFT, 0, x)
52
53 typedef struct vdev_indirect_mapping_entry {
54         vdev_indirect_mapping_entry_phys_t      vime_mapping;
55         uint32_t                                vime_obsolete_count;
56         list_node_t                             vime_node;
57 } vdev_indirect_mapping_entry_t;
58
59 /*
60  * This is stored in the bonus buffer of the mapping object, see comment of
61  * vdev_indirect_config for more details.
62  */
63 typedef struct vdev_indirect_mapping_phys {
64         uint64_t        vimp_max_offset;
65         uint64_t        vimp_bytes_mapped;
66         uint64_t        vimp_num_entries; /* number of v_i_m_entry_phys_t's */
67
68         /*
69          * For each entry in the mapping object, this object contains an
70          * entry representing the number of bytes of that mapping entry
71          * that were no longer in use by the pool at the time this indirect
72          * vdev was last condensed.
73          */
74         uint64_t        vimp_counts_object;
75 } vdev_indirect_mapping_phys_t;
76
77 #define VDEV_INDIRECT_MAPPING_SIZE_V0   (3 * sizeof (uint64_t))
78
79 typedef struct vdev_indirect_mapping {
80         uint64_t        vim_object;
81         boolean_t       vim_havecounts;
82
83         /*
84          * An ordered array of all mapping entries, sorted by source offset.
85          * Note that vim_entries is needed during a removal (and contains
86          * mappings that have been synced to disk so far) to handle frees
87          * from the removing device.
88          */
89         vdev_indirect_mapping_entry_phys_t *vim_entries;
90
91         objset_t        *vim_objset;
92
93         dmu_buf_t       *vim_dbuf;
94         vdev_indirect_mapping_phys_t    *vim_phys;
95 } vdev_indirect_mapping_t;
96
97 extern vdev_indirect_mapping_t *vdev_indirect_mapping_open(objset_t *os,
98     uint64_t object);
99 extern void vdev_indirect_mapping_close(vdev_indirect_mapping_t *vim);
100 extern uint64_t vdev_indirect_mapping_alloc(objset_t *os, dmu_tx_t *tx);
101 extern void vdev_indirect_mapping_free(objset_t *os, uint64_t obj,
102     dmu_tx_t *tx);
103
104 extern uint64_t vdev_indirect_mapping_num_entries(vdev_indirect_mapping_t *vim);
105 extern uint64_t vdev_indirect_mapping_max_offset(vdev_indirect_mapping_t *vim);
106 extern uint64_t vdev_indirect_mapping_object(vdev_indirect_mapping_t *vim);
107 extern uint64_t vdev_indirect_mapping_bytes_mapped(
108     vdev_indirect_mapping_t *vim);
109 extern uint64_t vdev_indirect_mapping_size(vdev_indirect_mapping_t *vim);
110
111 /*
112  * Writes the given list of vdev_indirect_mapping_entry_t to the mapping
113  * then updates internal state.
114  */
115 extern void vdev_indirect_mapping_add_entries(vdev_indirect_mapping_t *vim,
116     list_t *vime_list, dmu_tx_t *tx);
117
118 extern vdev_indirect_mapping_entry_phys_t *
119     vdev_indirect_mapping_entry_for_offset(vdev_indirect_mapping_t *vim,
120     uint64_t offset);
121
122 extern vdev_indirect_mapping_entry_phys_t *
123     vdev_indirect_mapping_entry_for_offset_or_next(vdev_indirect_mapping_t *vim,
124     uint64_t offset);
125
126 extern uint32_t *vdev_indirect_mapping_load_obsolete_counts(
127     vdev_indirect_mapping_t *vim);
128 extern void vdev_indirect_mapping_load_obsolete_spacemap(
129     vdev_indirect_mapping_t *vim,
130     uint32_t *counts, space_map_t *obsolete_space_sm);
131 extern void vdev_indirect_mapping_increment_obsolete_count(
132     vdev_indirect_mapping_t *vim,
133     uint64_t offset, uint64_t asize, uint32_t *counts);
134 extern void vdev_indirect_mapping_free_obsolete_counts(
135     vdev_indirect_mapping_t *vim, uint32_t *counts);
136
137 #ifdef  __cplusplus
138 }
139 #endif
140
141 #endif  /* _SYS_VDEV_INDIRECT_MAPPING_H */