4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 #include "spdk/stdinc.h"
38 #include "spdk/bit_array.h"
39 #include "spdk/queue.h"
40 #include "spdk/bdev_zone.h"
46 /* Number of LBAs that could be stored in a single block */
47 #define FTL_NUM_LBA_IN_BLOCK (FTL_BLOCK_SIZE / sizeof(uint64_t))
50 struct ftl_lba_map_request
;
53 struct spdk_bdev_zone_info info
;
55 /* Indicates that there is inflight write */
58 CIRCLEQ_ENTRY(ftl_zone
) circleq
;
63 /* Metadata read failure */
67 /* UUID doesn't match */
69 /* UUID and version matches but CRC doesn't */
71 /* Vld or lba map size doesn't match */
75 enum ftl_lba_map_seg_state
{
76 FTL_LBA_MAP_SEG_CLEAR
,
77 FTL_LBA_MAP_SEG_PENDING
,
78 FTL_LBA_MAP_SEG_CACHED
82 /* LBA/vld map lock */
83 pthread_spinlock_t lock
;
85 /* Number of valid LBAs */
88 /* LBA map's reference count */
91 /* Bitmap of valid LBAs */
92 struct spdk_bit_array
*vld
;
94 /* LBA map (only valid for open/relocating bands) */
97 /* LBA map segment state map (clear, pending, cached) */
100 LIST_HEAD(, ftl_lba_map_request
) request_list
;
102 /* Metadata DMA buffer (only valid for open/relocating bands) */
106 enum ftl_band_state
{
109 FTL_BAND_STATE_OPENING
,
112 FTL_BAND_STATE_CLOSING
,
113 FTL_BAND_STATE_CLOSED
,
117 struct ftl_lba_map_request
{
118 /* Completion callback */
121 /* Completion callback context */
124 /* Bit array of requested segments */
125 struct spdk_bit_array
*segments
;
127 /* Number of pending segments to read */
130 LIST_ENTRY(ftl_lba_map_request
) list_entry
;
134 /* Device this band belongs to */
135 struct spdk_ftl_dev
*dev
;
137 /* Number of operational zones */
141 struct ftl_zone
*zone_buf
;
143 /* List of operational zones */
144 CIRCLEQ_HEAD(, ftl_zone
) zones
;
147 struct ftl_lba_map lba_map
;
150 enum ftl_band_state state
;
155 /* Latest merit calculation */
158 /* High defrag priority - means that the metadata should be copied and */
159 /* the band should be defragged immediately */
162 /* Sequence number */
165 /* Number of defrag cycles */
168 /* End metadata start addr */
169 struct ftl_addr tail_md_addr
;
171 /* Bitmap of all bands that have its data moved onto this band */
172 struct spdk_bit_array
*reloc_bitmap
;
173 /* Number of open bands containing data moved from this band */
174 size_t num_reloc_bands
;
175 /* Number of blocks currently being moved from this band */
176 size_t num_reloc_blocks
;
178 /* Free/shut bands' lists */
179 LIST_ENTRY(ftl_band
) list_entry
;
181 /* High priority queue link */
182 STAILQ_ENTRY(ftl_band
) prio_stailq
;
185 uint64_t ftl_band_block_offset_from_addr(struct ftl_band
*band
, struct ftl_addr addr
);
186 struct ftl_addr
ftl_band_addr_from_block_offset(struct ftl_band
*band
, uint64_t block_off
);
187 void ftl_band_set_state(struct ftl_band
*band
, enum ftl_band_state state
);
188 size_t ftl_band_age(const struct ftl_band
*band
);
189 void ftl_band_acquire_lba_map(struct ftl_band
*band
);
190 int ftl_band_alloc_lba_map(struct ftl_band
*band
);
191 void ftl_band_clear_lba_map(struct ftl_band
*band
);
192 void ftl_band_release_lba_map(struct ftl_band
*band
);
193 int ftl_band_read_lba_map(struct ftl_band
*band
,
194 size_t offset
, size_t lba_cnt
,
195 ftl_io_fn cb_fn
, void *cb_ctx
);
196 struct ftl_addr
ftl_band_next_xfer_addr(struct ftl_band
*band
, struct ftl_addr addr
,
198 struct ftl_addr
ftl_band_next_addr(struct ftl_band
*band
, struct ftl_addr addr
,
200 size_t ftl_band_num_usable_blocks(const struct ftl_band
*band
);
201 size_t ftl_band_user_blocks_left(const struct ftl_band
*band
, size_t offset
);
202 size_t ftl_band_user_blocks(const struct ftl_band
*band
);
203 void ftl_band_set_addr(struct ftl_band
*band
, uint64_t lba
,
204 struct ftl_addr addr
);
205 struct ftl_band
*ftl_band_from_addr(struct spdk_ftl_dev
*dev
, struct ftl_addr addr
);
206 struct ftl_zone
*ftl_band_zone_from_addr(struct ftl_band
*band
, struct ftl_addr
);
207 void ftl_band_md_clear(struct ftl_band
*band
);
208 int ftl_band_read_tail_md(struct ftl_band
*band
, struct ftl_addr
,
209 ftl_io_fn cb_fn
, void *cb_ctx
);
210 int ftl_band_read_head_md(struct ftl_band
*band
, ftl_io_fn cb_fn
, void *cb_ctx
);
211 int ftl_band_write_tail_md(struct ftl_band
*band
, ftl_io_fn cb
);
212 int ftl_band_write_head_md(struct ftl_band
*band
, ftl_io_fn cb
);
213 struct ftl_addr
ftl_band_tail_md_addr(struct ftl_band
*band
);
214 struct ftl_addr
ftl_band_head_md_addr(struct ftl_band
*band
);
215 void ftl_band_write_failed(struct ftl_band
*band
);
216 int ftl_band_full(struct ftl_band
*band
, size_t offset
);
217 int ftl_band_write_prep(struct ftl_band
*band
);
218 struct ftl_zone
*ftl_band_next_operational_zone(struct ftl_band
*band
,
219 struct ftl_zone
*zone
);
220 size_t ftl_lba_map_pool_elem_size(struct spdk_ftl_dev
*dev
);
221 void ftl_band_remove_zone(struct ftl_band
*band
, struct ftl_zone
*zone
);
225 ftl_band_empty(const struct ftl_band
*band
)
227 return band
->lba_map
.num_vld
== 0;
230 static inline struct ftl_zone
*
231 ftl_band_next_zone(struct ftl_band
*band
, struct ftl_zone
*zone
)
233 assert(zone
->info
.state
!= SPDK_BDEV_ZONE_STATE_OFFLINE
);
234 return CIRCLEQ_LOOP_NEXT(&band
->zones
, zone
, circleq
);
238 ftl_band_set_next_state(struct ftl_band
*band
)
240 ftl_band_set_state(band
, (band
->state
+ 1) % FTL_BAND_STATE_MAX
);
244 ftl_band_state_changing(struct ftl_band
*band
)
246 return band
->state
== FTL_BAND_STATE_OPENING
||
247 band
->state
== FTL_BAND_STATE_CLOSING
;
251 ftl_band_block_offset_valid(struct ftl_band
*band
, size_t block_off
)
253 struct ftl_lba_map
*lba_map
= &band
->lba_map
;
255 pthread_spin_lock(&lba_map
->lock
);
256 if (spdk_bit_array_get(lba_map
->vld
, block_off
)) {
257 pthread_spin_unlock(&lba_map
->lock
);
261 pthread_spin_unlock(&lba_map
->lock
);
266 ftl_band_zone_is_last(struct ftl_band
*band
, struct ftl_zone
*zone
)
268 return zone
== CIRCLEQ_LAST(&band
->zones
);
272 ftl_band_zone_is_first(struct ftl_band
*band
, struct ftl_zone
*zone
)
274 return zone
== CIRCLEQ_FIRST(&band
->zones
);
278 ftl_zone_is_writable(const struct spdk_ftl_dev
*dev
, const struct ftl_zone
*zone
)
280 bool busy
= ftl_is_append_supported(dev
) ? false : zone
->busy
;
282 return (zone
->info
.state
== SPDK_BDEV_ZONE_STATE_OPEN
||
283 zone
->info
.state
== SPDK_BDEV_ZONE_STATE_EMPTY
) &&
287 #endif /* FTL_BAND_H */