32
32
#include <sys/zio.h>
33
33
#include <sys/space_map.h>
34
34
35
+ static kmem_cache_t * space_seg_cache ;
36
+
37
+ void
38
+ space_map_init (void )
39
+ {
40
+ ASSERT (space_seg_cache == NULL );
41
+ space_seg_cache = kmem_cache_create ("space_seg_cache" ,
42
+ sizeof (space_seg_t ), 0 , NULL , NULL , NULL , NULL , NULL , 0 );
43
+ }
44
+
45
+ void
46
+ space_map_fini (void )
47
+ {
48
+ kmem_cache_destroy (space_seg_cache );
49
+ space_seg_cache = NULL ;
50
+ }
51
+
35
52
/*
36
53
* Space map routines.
37
54
* NOTE: caller is responsible for all locking.
@@ -124,7 +141,7 @@ space_map_add(space_map_t *sm, uint64_t start, uint64_t size)
124
141
avl_remove (sm -> sm_pp_root , ss_after );
125
142
}
126
143
ss_after -> ss_start = ss_before -> ss_start ;
127
- kmem_free ( ss_before , sizeof ( * ss_before ) );
144
+ kmem_cache_free ( space_seg_cache , ss_before );
128
145
ss = ss_after ;
129
146
} else if (merge_before ) {
130
147
ss_before -> ss_end = end ;
@@ -137,7 +154,7 @@ space_map_add(space_map_t *sm, uint64_t start, uint64_t size)
137
154
avl_remove (sm -> sm_pp_root , ss_after );
138
155
ss = ss_after ;
139
156
} else {
140
- ss = kmem_alloc ( sizeof ( * ss ) , KM_SLEEP );
157
+ ss = kmem_cache_alloc ( space_seg_cache , KM_SLEEP );
141
158
ss -> ss_start = start ;
142
159
ss -> ss_end = end ;
143
160
avl_insert (& sm -> sm_root , ss , where );
@@ -184,7 +201,7 @@ space_map_remove(space_map_t *sm, uint64_t start, uint64_t size)
184
201
avl_remove (sm -> sm_pp_root , ss );
185
202
186
203
if (left_over && right_over ) {
187
- newseg = kmem_alloc ( sizeof ( * newseg ) , KM_SLEEP );
204
+ newseg = kmem_cache_alloc ( space_seg_cache , KM_SLEEP );
188
205
newseg -> ss_start = end ;
189
206
newseg -> ss_end = ss -> ss_end ;
190
207
ss -> ss_end = start ;
@@ -197,7 +214,7 @@ space_map_remove(space_map_t *sm, uint64_t start, uint64_t size)
197
214
ss -> ss_start = end ;
198
215
} else {
199
216
avl_remove (& sm -> sm_root , ss );
200
- kmem_free ( ss , sizeof ( * ss ) );
217
+ kmem_cache_free ( space_seg_cache , ss );
201
218
ss = NULL ;
202
219
}
203
220
@@ -237,7 +254,7 @@ space_map_vacate(space_map_t *sm, space_map_func_t *func, space_map_t *mdest)
237
254
while ((ss = avl_destroy_nodes (& sm -> sm_root , & cookie )) != NULL ) {
238
255
if (func != NULL )
239
256
func (mdest , ss -> ss_start , ss -> ss_end - ss -> ss_start );
240
- kmem_free ( ss , sizeof ( * ss ) );
257
+ kmem_cache_free ( space_seg_cache , ss );
241
258
}
242
259
sm -> sm_space = 0 ;
243
260
}
@@ -409,7 +426,7 @@ space_map_sync(space_map_t *sm, uint8_t maptype,
409
426
spa_t * spa = dmu_objset_spa (os );
410
427
void * cookie = NULL ;
411
428
space_seg_t * ss ;
412
- uint64_t bufsize , start , size , run_len ;
429
+ uint64_t bufsize , start , size , run_len , delta , sm_space ;
413
430
uint64_t * entry , * entry_map , * entry_map_end ;
414
431
415
432
ASSERT (MUTEX_HELD (sm -> sm_lock ));
@@ -438,11 +455,13 @@ space_map_sync(space_map_t *sm, uint8_t maptype,
438
455
SM_DEBUG_SYNCPASS_ENCODE (spa_sync_pass (spa )) |
439
456
SM_DEBUG_TXG_ENCODE (dmu_tx_get_txg (tx ));
440
457
458
+ delta = 0 ;
459
+ sm_space = sm -> sm_space ;
441
460
while ((ss = avl_destroy_nodes (& sm -> sm_root , & cookie )) != NULL ) {
442
461
size = ss -> ss_end - ss -> ss_start ;
443
462
start = (ss -> ss_start - sm -> sm_start ) >> sm -> sm_shift ;
444
463
445
- sm -> sm_space - = size ;
464
+ delta + = size ;
446
465
size >>= sm -> sm_shift ;
447
466
448
467
while (size ) {
@@ -464,7 +483,7 @@ space_map_sync(space_map_t *sm, uint8_t maptype,
464
483
start += run_len ;
465
484
size -= run_len ;
466
485
}
467
- kmem_free ( ss , sizeof ( * ss ) );
486
+ kmem_cache_free ( space_seg_cache , ss );
468
487
}
469
488
470
489
if (entry != entry_map ) {
@@ -476,8 +495,15 @@ space_map_sync(space_map_t *sm, uint8_t maptype,
476
495
smo -> smo_objsize += size ;
477
496
}
478
497
498
+ /*
499
+ * Ensure that the space_map's accounting wasn't changed
500
+ * while we were in the middle of writing it out.
501
+ */
502
+ VERIFY3U (sm -> sm_space , = = , sm_space );
503
+
479
504
zio_buf_free (entry_map , bufsize );
480
505
506
+ sm -> sm_space -= delta ;
481
507
VERIFY0 (sm -> sm_space );
482
508
}
483
509
0 commit comments