22
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
22
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23
23
* Use is subject to license terms.
26
26
#include <sys/bplist.h>
27
27
#include <sys/zfs_context.h>
30
bplist_init(bplist_t *bpl)
32
bzero(bpl, sizeof (*bpl));
33
mutex_init(&bpl->bpl_lock, NULL, MUTEX_DEFAULT, NULL);
34
mutex_init(&bpl->bpl_q_lock, NULL, MUTEX_DEFAULT, NULL);
35
list_create(&bpl->bpl_queue, sizeof (bplist_q_t),
36
offsetof(bplist_q_t, bpq_node));
40
bplist_fini(bplist_t *bpl)
42
ASSERT(list_is_empty(&bpl->bpl_queue));
43
list_destroy(&bpl->bpl_queue);
44
mutex_destroy(&bpl->bpl_q_lock);
45
mutex_destroy(&bpl->bpl_lock);
30
49
bplist_hold(bplist_t *bpl)
73
92
ASSERT(bpl->bpl_dbuf == NULL);
74
93
ASSERT(bpl->bpl_phys == NULL);
75
94
ASSERT(bpl->bpl_cached_dbuf == NULL);
76
ASSERT(bpl->bpl_queue == NULL);
95
ASSERT(list_is_empty(&bpl->bpl_queue));
77
96
ASSERT(object != 0);
78
97
ASSERT3U(doi.doi_type, ==, DMU_OT_BPLIST);
79
98
ASSERT3U(doi.doi_bonus_type, ==, DMU_OT_BPLIST_HDR);
94
113
mutex_enter(&bpl->bpl_lock);
96
ASSERT(bpl->bpl_queue == NULL);
115
ASSERT(list_is_empty(&bpl->bpl_queue));
98
117
if (bpl->bpl_cached_dbuf) {
99
118
dmu_buf_rele(bpl->bpl_cached_dbuf, bpl);
208
227
bparray[off].blk_fill = 0;
210
229
/* The bplist will compress better if we can leave off the checksum */
211
bzero(&bparray[off].blk_cksum, sizeof (bparray[off].blk_cksum));
230
if (!BP_GET_DEDUP(&bparray[off]))
231
bzero(&bparray[off].blk_cksum, sizeof (bparray[off].blk_cksum));
213
233
dmu_buf_will_dirty(bpl->bpl_dbuf, tx);
214
234
bpl->bpl_phys->bpl_entries++;
215
235
bpl->bpl_phys->bpl_bytes +=
216
bp_get_dasize(dmu_objset_spa(bpl->bpl_mos), bp);
236
bp_get_dsize_sync(dmu_objset_spa(bpl->bpl_mos), bp);
217
237
if (bpl->bpl_havecomp) {
218
238
bpl->bpl_phys->bpl_comp += BP_GET_PSIZE(bp);
219
239
bpl->bpl_phys->bpl_uncomp += BP_GET_UCSIZE(bp);
247
bplist_enqueue_cb(void *bpl, const blkptr_t *bp, dmu_tx_t *tx)
249
VERIFY(bplist_enqueue(bpl, bp, tx) == 0);
227
* Deferred entry; will be written later by bplist_sync().
253
* Deferred entry; will be processed later by bplist_sync().
230
256
bplist_enqueue_deferred(bplist_t *bpl, const blkptr_t *bp)
232
258
bplist_q_t *bpq = kmem_alloc(sizeof (*bpq), KM_SLEEP);
234
260
ASSERT(!BP_IS_HOLE(bp));
235
mutex_enter(&bpl->bpl_lock);
261
mutex_enter(&bpl->bpl_q_lock);
236
262
bpq->bpq_blk = *bp;
237
bpq->bpq_next = bpl->bpl_queue;
238
bpl->bpl_queue = bpq;
239
mutex_exit(&bpl->bpl_lock);
263
list_insert_tail(&bpl->bpl_queue, bpq);
264
mutex_exit(&bpl->bpl_q_lock);
243
bplist_sync(bplist_t *bpl, dmu_tx_t *tx)
268
bplist_sync(bplist_t *bpl, bplist_sync_cb_t *func, void *arg, dmu_tx_t *tx)
247
mutex_enter(&bpl->bpl_lock);
248
while ((bpq = bpl->bpl_queue) != NULL) {
249
bpl->bpl_queue = bpq->bpq_next;
250
mutex_exit(&bpl->bpl_lock);
251
VERIFY(0 == bplist_enqueue(bpl, &bpq->bpq_blk, tx));
272
mutex_enter(&bpl->bpl_q_lock);
273
while (bpq = list_head(&bpl->bpl_queue)) {
274
list_remove(&bpl->bpl_queue, bpq);
275
mutex_exit(&bpl->bpl_q_lock);
276
func(arg, &bpq->bpq_blk, tx);
252
277
kmem_free(bpq, sizeof (*bpq));
253
mutex_enter(&bpl->bpl_lock);
278
mutex_enter(&bpl->bpl_q_lock);
255
mutex_exit(&bpl->bpl_lock);
280
mutex_exit(&bpl->bpl_q_lock);
259
284
bplist_vacate(bplist_t *bpl, dmu_tx_t *tx)
261
286
mutex_enter(&bpl->bpl_lock);
262
ASSERT3P(bpl->bpl_queue, ==, NULL);
287
ASSERT(list_is_empty(&bpl->bpl_queue));
263
288
VERIFY(0 == bplist_hold(bpl));
264
289
dmu_buf_will_dirty(bpl->bpl_dbuf, tx);
265
290
VERIFY(0 == dmu_free_range(bpl->bpl_mos,
314
* Return (in *dasizep) the amount of space on the deadlist which is:
339
* Return (in *dsizep) the amount of space on the deadlist which is:
315
340
* mintxg < blk_birth <= maxtxg
318
343
bplist_space_birthrange(bplist_t *bpl, uint64_t mintxg, uint64_t maxtxg,
321
346
uint64_t size = 0;
322
347
uint64_t itor = 0;
331
356
mutex_enter(&bpl->bpl_lock);
332
357
err = bplist_hold(bpl);
334
*dasizep = bpl->bpl_phys->bpl_bytes;
359
*dsizep = bpl->bpl_phys->bpl_bytes;
335
360
mutex_exit(&bpl->bpl_lock);
339
364
while ((err = bplist_iterate(bpl, &itor, &bp)) == 0) {
340
365
if (bp.blk_birth > mintxg && bp.blk_birth <= maxtxg) {
342
bp_get_dasize(dmu_objset_spa(bpl->bpl_mos), &bp);
366
size += bp_get_dsize(dmu_objset_spa(bpl->bpl_mos), &bp);
345
369
if (err == ENOENT)