]> git.proxmox.com Git - mirror_zfs-debian.git/blame - module/zfs/dsl_deadlist.c
New upstream version 0.7.2
[mirror_zfs-debian.git] / module / zfs / dsl_deadlist.c
CommitLineData
428870ff
BB
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
cae5b340 23 * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
e10b0808 24 * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
428870ff
BB
25 */
26
27#include <sys/dsl_dataset.h>
28#include <sys/dmu.h>
29#include <sys/refcount.h>
30#include <sys/zap.h>
31#include <sys/zfs_context.h>
32#include <sys/dsl_pool.h>
33
330d06f9
MA
34/*
35 * Deadlist concurrency:
36 *
37 * Deadlists can only be modified from the syncing thread.
38 *
39 * Except for dsl_deadlist_insert(), it can only be modified with the
40 * dp_config_rwlock held with RW_WRITER.
41 *
42 * The accessors (dsl_deadlist_space() and dsl_deadlist_space_range()) can
43 * be called concurrently, from open context, with the dl_config_rwlock held
44 * with RW_READER.
45 *
46 * Therefore, we only need to provide locking between dsl_deadlist_insert() and
47 * the accessors, protecting:
48 * dl_phys->dl_used,comp,uncomp
49 * and protecting the dl_tree from being loaded.
50 * The locking is provided by dl_lock. Note that locking on the bpobj_t
51 * provides its own locking, and dl_oldfmt is immutable.
52 */
53
428870ff
BB
54static int
55dsl_deadlist_compare(const void *arg1, const void *arg2)
56{
cae5b340
AX
57 const dsl_deadlist_entry_t *dle1 = (const dsl_deadlist_entry_t *)arg1;
58 const dsl_deadlist_entry_t *dle2 = (const dsl_deadlist_entry_t *)arg2;
428870ff 59
cae5b340 60 return (AVL_CMP(dle1->dle_mintxg, dle2->dle_mintxg));
428870ff
BB
61}
62
63static void
64dsl_deadlist_load_tree(dsl_deadlist_t *dl)
65{
66 zap_cursor_t zc;
67 zap_attribute_t za;
68
cae5b340
AX
69 ASSERT(MUTEX_HELD(&dl->dl_lock));
70
428870ff
BB
71 ASSERT(!dl->dl_oldfmt);
72 if (dl->dl_havetree)
73 return;
74
75 avl_create(&dl->dl_tree, dsl_deadlist_compare,
76 sizeof (dsl_deadlist_entry_t),
77 offsetof(dsl_deadlist_entry_t, dle_node));
78 for (zap_cursor_init(&zc, dl->dl_os, dl->dl_object);
79 zap_cursor_retrieve(&zc, &za) == 0;
80 zap_cursor_advance(&zc)) {
cae5b340
AX
81 dsl_deadlist_entry_t *dle = kmem_alloc(sizeof (*dle), KM_SLEEP);
82 dle->dle_mintxg = zfs_strtonum(za.za_name, NULL);
428870ff
BB
83 VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os,
84 za.za_first_integer));
85 avl_add(&dl->dl_tree, dle);
86 }
87 zap_cursor_fini(&zc);
88 dl->dl_havetree = B_TRUE;
89}
90
91void
92dsl_deadlist_open(dsl_deadlist_t *dl, objset_t *os, uint64_t object)
93{
94 dmu_object_info_t doi;
95
96 mutex_init(&dl->dl_lock, NULL, MUTEX_DEFAULT, NULL);
97 dl->dl_os = os;
98 dl->dl_object = object;
99 VERIFY3U(0, ==, dmu_bonus_hold(os, object, dl, &dl->dl_dbuf));
100 dmu_object_info_from_db(dl->dl_dbuf, &doi);
101 if (doi.doi_type == DMU_OT_BPOBJ) {
102 dmu_buf_rele(dl->dl_dbuf, dl);
103 dl->dl_dbuf = NULL;
104 dl->dl_oldfmt = B_TRUE;
105 VERIFY3U(0, ==, bpobj_open(&dl->dl_bpobj, os, object));
106 return;
107 }
108
109 dl->dl_oldfmt = B_FALSE;
110 dl->dl_phys = dl->dl_dbuf->db_data;
111 dl->dl_havetree = B_FALSE;
112}
113
114void
115dsl_deadlist_close(dsl_deadlist_t *dl)
116{
117 void *cookie = NULL;
118 dsl_deadlist_entry_t *dle;
119
e10b0808 120 dl->dl_os = NULL;
cae5b340 121 mutex_destroy(&dl->dl_lock);
e10b0808 122
428870ff
BB
123 if (dl->dl_oldfmt) {
124 dl->dl_oldfmt = B_FALSE;
125 bpobj_close(&dl->dl_bpobj);
126 return;
127 }
128
129 if (dl->dl_havetree) {
130 while ((dle = avl_destroy_nodes(&dl->dl_tree, &cookie))
131 != NULL) {
132 bpobj_close(&dle->dle_bpobj);
133 kmem_free(dle, sizeof (*dle));
134 }
135 avl_destroy(&dl->dl_tree);
136 }
137 dmu_buf_rele(dl->dl_dbuf, dl);
428870ff
BB
138 dl->dl_dbuf = NULL;
139 dl->dl_phys = NULL;
140}
141
142uint64_t
143dsl_deadlist_alloc(objset_t *os, dmu_tx_t *tx)
144{
145 if (spa_version(dmu_objset_spa(os)) < SPA_VERSION_DEADLISTS)
e10b0808 146 return (bpobj_alloc(os, SPA_OLD_MAXBLOCKSIZE, tx));
428870ff
BB
147 return (zap_create(os, DMU_OT_DEADLIST, DMU_OT_DEADLIST_HDR,
148 sizeof (dsl_deadlist_phys_t), tx));
149}
150
151void
152dsl_deadlist_free(objset_t *os, uint64_t dlobj, dmu_tx_t *tx)
153{
154 dmu_object_info_t doi;
155 zap_cursor_t zc;
156 zap_attribute_t za;
157
158 VERIFY3U(0, ==, dmu_object_info(os, dlobj, &doi));
159 if (doi.doi_type == DMU_OT_BPOBJ) {
160 bpobj_free(os, dlobj, tx);
161 return;
162 }
163
164 for (zap_cursor_init(&zc, os, dlobj);
165 zap_cursor_retrieve(&zc, &za) == 0;
753c3839
MA
166 zap_cursor_advance(&zc)) {
167 uint64_t obj = za.za_first_integer;
168 if (obj == dmu_objset_pool(os)->dp_empty_bpobj)
169 bpobj_decr_empty(os, tx);
170 else
171 bpobj_free(os, obj, tx);
172 }
428870ff
BB
173 zap_cursor_fini(&zc);
174 VERIFY3U(0, ==, dmu_object_free(os, dlobj, tx));
175}
176
753c3839
MA
177static void
178dle_enqueue(dsl_deadlist_t *dl, dsl_deadlist_entry_t *dle,
179 const blkptr_t *bp, dmu_tx_t *tx)
180{
cae5b340 181 ASSERT(MUTEX_HELD(&dl->dl_lock));
753c3839
MA
182 if (dle->dle_bpobj.bpo_object ==
183 dmu_objset_pool(dl->dl_os)->dp_empty_bpobj) {
e10b0808 184 uint64_t obj = bpobj_alloc(dl->dl_os, SPA_OLD_MAXBLOCKSIZE, tx);
753c3839
MA
185 bpobj_close(&dle->dle_bpobj);
186 bpobj_decr_empty(dl->dl_os, tx);
187 VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, obj));
188 VERIFY3U(0, ==, zap_update_int_key(dl->dl_os, dl->dl_object,
189 dle->dle_mintxg, obj, tx));
190 }
191 bpobj_enqueue(&dle->dle_bpobj, bp, tx);
192}
193
194static void
195dle_enqueue_subobj(dsl_deadlist_t *dl, dsl_deadlist_entry_t *dle,
196 uint64_t obj, dmu_tx_t *tx)
197{
cae5b340 198 ASSERT(MUTEX_HELD(&dl->dl_lock));
753c3839
MA
199 if (dle->dle_bpobj.bpo_object !=
200 dmu_objset_pool(dl->dl_os)->dp_empty_bpobj) {
201 bpobj_enqueue_subobj(&dle->dle_bpobj, obj, tx);
202 } else {
203 bpobj_close(&dle->dle_bpobj);
204 bpobj_decr_empty(dl->dl_os, tx);
205 VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, obj));
206 VERIFY3U(0, ==, zap_update_int_key(dl->dl_os, dl->dl_object,
207 dle->dle_mintxg, obj, tx));
208 }
209}
210
428870ff
BB
211void
212dsl_deadlist_insert(dsl_deadlist_t *dl, const blkptr_t *bp, dmu_tx_t *tx)
213{
214 dsl_deadlist_entry_t dle_tofind;
215 dsl_deadlist_entry_t *dle;
216 avl_index_t where;
217
218 if (dl->dl_oldfmt) {
219 bpobj_enqueue(&dl->dl_bpobj, bp, tx);
220 return;
221 }
222
cae5b340 223 mutex_enter(&dl->dl_lock);
428870ff
BB
224 dsl_deadlist_load_tree(dl);
225
226 dmu_buf_will_dirty(dl->dl_dbuf, tx);
428870ff
BB
227 dl->dl_phys->dl_used +=
228 bp_get_dsize_sync(dmu_objset_spa(dl->dl_os), bp);
229 dl->dl_phys->dl_comp += BP_GET_PSIZE(bp);
230 dl->dl_phys->dl_uncomp += BP_GET_UCSIZE(bp);
428870ff
BB
231
232 dle_tofind.dle_mintxg = bp->blk_birth;
233 dle = avl_find(&dl->dl_tree, &dle_tofind, &where);
234 if (dle == NULL)
235 dle = avl_nearest(&dl->dl_tree, where, AVL_BEFORE);
236 else
237 dle = AVL_PREV(&dl->dl_tree, dle);
cae5b340
AX
238
239 if (dle == NULL) {
240 zfs_panic_recover("blkptr at %p has invalid BLK_BIRTH %llu",
241 bp, (longlong_t)bp->blk_birth);
242 dle = avl_first(&dl->dl_tree);
243 }
244
245 ASSERT3P(dle, !=, NULL);
753c3839 246 dle_enqueue(dl, dle, bp, tx);
cae5b340 247 mutex_exit(&dl->dl_lock);
428870ff
BB
248}
249
250/*
251 * Insert new key in deadlist, which must be > all current entries.
252 * mintxg is not inclusive.
253 */
254void
255dsl_deadlist_add_key(dsl_deadlist_t *dl, uint64_t mintxg, dmu_tx_t *tx)
256{
257 uint64_t obj;
258 dsl_deadlist_entry_t *dle;
259
260 if (dl->dl_oldfmt)
261 return;
262
ea04106b 263 dle = kmem_alloc(sizeof (*dle), KM_SLEEP);
428870ff 264 dle->dle_mintxg = mintxg;
cae5b340
AX
265
266 mutex_enter(&dl->dl_lock);
267 dsl_deadlist_load_tree(dl);
268
e10b0808 269 obj = bpobj_alloc_empty(dl->dl_os, SPA_OLD_MAXBLOCKSIZE, tx);
428870ff
BB
270 VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, obj));
271 avl_add(&dl->dl_tree, dle);
272
273 VERIFY3U(0, ==, zap_add_int_key(dl->dl_os, dl->dl_object,
274 mintxg, obj, tx));
cae5b340 275 mutex_exit(&dl->dl_lock);
428870ff
BB
276}
277
278/*
279 * Remove this key, merging its entries into the previous key.
280 */
281void
282dsl_deadlist_remove_key(dsl_deadlist_t *dl, uint64_t mintxg, dmu_tx_t *tx)
283{
284 dsl_deadlist_entry_t dle_tofind;
285 dsl_deadlist_entry_t *dle, *dle_prev;
286
287 if (dl->dl_oldfmt)
288 return;
289
cae5b340 290 mutex_enter(&dl->dl_lock);
428870ff
BB
291 dsl_deadlist_load_tree(dl);
292
293 dle_tofind.dle_mintxg = mintxg;
294 dle = avl_find(&dl->dl_tree, &dle_tofind, NULL);
295 dle_prev = AVL_PREV(&dl->dl_tree, dle);
296
753c3839 297 dle_enqueue_subobj(dl, dle_prev, dle->dle_bpobj.bpo_object, tx);
428870ff
BB
298
299 avl_remove(&dl->dl_tree, dle);
300 bpobj_close(&dle->dle_bpobj);
301 kmem_free(dle, sizeof (*dle));
302
303 VERIFY3U(0, ==, zap_remove_int(dl->dl_os, dl->dl_object, mintxg, tx));
cae5b340 304 mutex_exit(&dl->dl_lock);
428870ff
BB
305}
306
307/*
308 * Walk ds's snapshots to regenerate generate ZAP & AVL.
309 */
310static void
311dsl_deadlist_regenerate(objset_t *os, uint64_t dlobj,
312 uint64_t mrs_obj, dmu_tx_t *tx)
313{
314 dsl_deadlist_t dl;
315 dsl_pool_t *dp = dmu_objset_pool(os);
316
317 dsl_deadlist_open(&dl, os, dlobj);
318 if (dl.dl_oldfmt) {
319 dsl_deadlist_close(&dl);
320 return;
321 }
322
323 while (mrs_obj != 0) {
324 dsl_dataset_t *ds;
325 VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, mrs_obj, FTAG, &ds));
e10b0808
AX
326 dsl_deadlist_add_key(&dl,
327 dsl_dataset_phys(ds)->ds_prev_snap_txg, tx);
328 mrs_obj = dsl_dataset_phys(ds)->ds_prev_snap_obj;
428870ff
BB
329 dsl_dataset_rele(ds, FTAG);
330 }
331 dsl_deadlist_close(&dl);
332}
333
334uint64_t
335dsl_deadlist_clone(dsl_deadlist_t *dl, uint64_t maxtxg,
336 uint64_t mrs_obj, dmu_tx_t *tx)
337{
338 dsl_deadlist_entry_t *dle;
339 uint64_t newobj;
340
341 newobj = dsl_deadlist_alloc(dl->dl_os, tx);
342
343 if (dl->dl_oldfmt) {
344 dsl_deadlist_regenerate(dl->dl_os, newobj, mrs_obj, tx);
345 return (newobj);
346 }
347
cae5b340 348 mutex_enter(&dl->dl_lock);
428870ff
BB
349 dsl_deadlist_load_tree(dl);
350
351 for (dle = avl_first(&dl->dl_tree); dle;
352 dle = AVL_NEXT(&dl->dl_tree, dle)) {
353 uint64_t obj;
354
355 if (dle->dle_mintxg >= maxtxg)
356 break;
357
e10b0808 358 obj = bpobj_alloc_empty(dl->dl_os, SPA_OLD_MAXBLOCKSIZE, tx);
428870ff
BB
359 VERIFY3U(0, ==, zap_add_int_key(dl->dl_os, newobj,
360 dle->dle_mintxg, obj, tx));
361 }
cae5b340 362 mutex_exit(&dl->dl_lock);
428870ff
BB
363 return (newobj);
364}
365
366void
367dsl_deadlist_space(dsl_deadlist_t *dl,
368 uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
369{
370 if (dl->dl_oldfmt) {
371 VERIFY3U(0, ==, bpobj_space(&dl->dl_bpobj,
372 usedp, compp, uncompp));
373 return;
374 }
375
376 mutex_enter(&dl->dl_lock);
377 *usedp = dl->dl_phys->dl_used;
378 *compp = dl->dl_phys->dl_comp;
379 *uncompp = dl->dl_phys->dl_uncomp;
380 mutex_exit(&dl->dl_lock);
381}
382
383/*
384 * return space used in the range (mintxg, maxtxg].
385 * Includes maxtxg, does not include mintxg.
386 * mintxg and maxtxg must both be keys in the deadlist (unless maxtxg is
330d06f9 387 * larger than any bp in the deadlist (eg. UINT64_MAX)).
428870ff
BB
388 */
389void
390dsl_deadlist_space_range(dsl_deadlist_t *dl, uint64_t mintxg, uint64_t maxtxg,
391 uint64_t *usedp, uint64_t *compp, uint64_t *uncompp)
392{
428870ff 393 dsl_deadlist_entry_t *dle;
330d06f9 394 dsl_deadlist_entry_t dle_tofind;
428870ff
BB
395 avl_index_t where;
396
397 if (dl->dl_oldfmt) {
398 VERIFY3U(0, ==, bpobj_space_range(&dl->dl_bpobj,
399 mintxg, maxtxg, usedp, compp, uncompp));
400 return;
401 }
402
428870ff
BB
403 *usedp = *compp = *uncompp = 0;
404
330d06f9
MA
405 mutex_enter(&dl->dl_lock);
406 dsl_deadlist_load_tree(dl);
428870ff
BB
407 dle_tofind.dle_mintxg = mintxg;
408 dle = avl_find(&dl->dl_tree, &dle_tofind, &where);
409 /*
410 * If we don't find this mintxg, there shouldn't be anything
411 * after it either.
412 */
413 ASSERT(dle != NULL ||
414 avl_nearest(&dl->dl_tree, where, AVL_AFTER) == NULL);
330d06f9 415
428870ff
BB
416 for (; dle && dle->dle_mintxg < maxtxg;
417 dle = AVL_NEXT(&dl->dl_tree, dle)) {
418 uint64_t used, comp, uncomp;
419
420 VERIFY3U(0, ==, bpobj_space(&dle->dle_bpobj,
421 &used, &comp, &uncomp));
422
423 *usedp += used;
424 *compp += comp;
425 *uncompp += uncomp;
426 }
330d06f9 427 mutex_exit(&dl->dl_lock);
428870ff
BB
428}
429
430static void
431dsl_deadlist_insert_bpobj(dsl_deadlist_t *dl, uint64_t obj, uint64_t birth,
432 dmu_tx_t *tx)
433{
434 dsl_deadlist_entry_t dle_tofind;
435 dsl_deadlist_entry_t *dle;
436 avl_index_t where;
437 uint64_t used, comp, uncomp;
438 bpobj_t bpo;
439
cae5b340
AX
440 ASSERT(MUTEX_HELD(&dl->dl_lock));
441
428870ff
BB
442 VERIFY3U(0, ==, bpobj_open(&bpo, dl->dl_os, obj));
443 VERIFY3U(0, ==, bpobj_space(&bpo, &used, &comp, &uncomp));
444 bpobj_close(&bpo);
445
446 dsl_deadlist_load_tree(dl);
447
448 dmu_buf_will_dirty(dl->dl_dbuf, tx);
428870ff
BB
449 dl->dl_phys->dl_used += used;
450 dl->dl_phys->dl_comp += comp;
451 dl->dl_phys->dl_uncomp += uncomp;
428870ff
BB
452
453 dle_tofind.dle_mintxg = birth;
454 dle = avl_find(&dl->dl_tree, &dle_tofind, &where);
455 if (dle == NULL)
456 dle = avl_nearest(&dl->dl_tree, where, AVL_BEFORE);
753c3839 457 dle_enqueue_subobj(dl, dle, obj, tx);
428870ff
BB
458}
459
460static int
461dsl_deadlist_insert_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
462{
463 dsl_deadlist_t *dl = arg;
464 dsl_deadlist_insert(dl, bp, tx);
465 return (0);
466}
467
468/*
469 * Merge the deadlist pointed to by 'obj' into dl. obj will be left as
470 * an empty deadlist.
471 */
472void
473dsl_deadlist_merge(dsl_deadlist_t *dl, uint64_t obj, dmu_tx_t *tx)
474{
475 zap_cursor_t zc;
476 zap_attribute_t za;
477 dmu_buf_t *bonus;
478 dsl_deadlist_phys_t *dlp;
479 dmu_object_info_t doi;
480
481 VERIFY3U(0, ==, dmu_object_info(dl->dl_os, obj, &doi));
482 if (doi.doi_type == DMU_OT_BPOBJ) {
483 bpobj_t bpo;
484 VERIFY3U(0, ==, bpobj_open(&bpo, dl->dl_os, obj));
485 VERIFY3U(0, ==, bpobj_iterate(&bpo,
486 dsl_deadlist_insert_cb, dl, tx));
487 bpobj_close(&bpo);
488 return;
489 }
490
cae5b340 491 mutex_enter(&dl->dl_lock);
428870ff
BB
492 for (zap_cursor_init(&zc, dl->dl_os, obj);
493 zap_cursor_retrieve(&zc, &za) == 0;
494 zap_cursor_advance(&zc)) {
cae5b340 495 uint64_t mintxg = zfs_strtonum(za.za_name, NULL);
428870ff
BB
496 dsl_deadlist_insert_bpobj(dl, za.za_first_integer, mintxg, tx);
497 VERIFY3U(0, ==, zap_remove_int(dl->dl_os, obj, mintxg, tx));
498 }
499 zap_cursor_fini(&zc);
500
501 VERIFY3U(0, ==, dmu_bonus_hold(dl->dl_os, obj, FTAG, &bonus));
502 dlp = bonus->db_data;
503 dmu_buf_will_dirty(bonus, tx);
504 bzero(dlp, sizeof (*dlp));
505 dmu_buf_rele(bonus, FTAG);
cae5b340 506 mutex_exit(&dl->dl_lock);
428870ff
BB
507}
508
509/*
510 * Remove entries on dl that are >= mintxg, and put them on the bpobj.
511 */
512void
513dsl_deadlist_move_bpobj(dsl_deadlist_t *dl, bpobj_t *bpo, uint64_t mintxg,
514 dmu_tx_t *tx)
515{
516 dsl_deadlist_entry_t dle_tofind;
517 dsl_deadlist_entry_t *dle;
518 avl_index_t where;
519
520 ASSERT(!dl->dl_oldfmt);
cae5b340
AX
521
522 mutex_enter(&dl->dl_lock);
428870ff
BB
523 dmu_buf_will_dirty(dl->dl_dbuf, tx);
524 dsl_deadlist_load_tree(dl);
525
526 dle_tofind.dle_mintxg = mintxg;
527 dle = avl_find(&dl->dl_tree, &dle_tofind, &where);
528 if (dle == NULL)
529 dle = avl_nearest(&dl->dl_tree, where, AVL_AFTER);
530 while (dle) {
531 uint64_t used, comp, uncomp;
532 dsl_deadlist_entry_t *dle_next;
533
534 bpobj_enqueue_subobj(bpo, dle->dle_bpobj.bpo_object, tx);
535
536 VERIFY3U(0, ==, bpobj_space(&dle->dle_bpobj,
537 &used, &comp, &uncomp));
428870ff
BB
538 ASSERT3U(dl->dl_phys->dl_used, >=, used);
539 ASSERT3U(dl->dl_phys->dl_comp, >=, comp);
540 ASSERT3U(dl->dl_phys->dl_uncomp, >=, uncomp);
541 dl->dl_phys->dl_used -= used;
542 dl->dl_phys->dl_comp -= comp;
543 dl->dl_phys->dl_uncomp -= uncomp;
428870ff
BB
544
545 VERIFY3U(0, ==, zap_remove_int(dl->dl_os, dl->dl_object,
546 dle->dle_mintxg, tx));
547
548 dle_next = AVL_NEXT(&dl->dl_tree, dle);
549 avl_remove(&dl->dl_tree, dle);
550 bpobj_close(&dle->dle_bpobj);
551 kmem_free(dle, sizeof (*dle));
552 dle = dle_next;
553 }
cae5b340 554 mutex_exit(&dl->dl_lock);
428870ff 555}