Print this page
expandable RAID-Z


 163         right_over = (ss->ss_end != end);
 164 
 165         if (left_over && right_over) {
 166                 newseg = kmem_alloc(sizeof (*newseg), KM_SLEEP);
 167                 newseg->ss_start = end;
 168                 newseg->ss_end = ss->ss_end;
 169                 ss->ss_end = start;
 170                 avl_insert_here(&sm->sm_root, newseg, ss, AVL_AFTER);
 171         } else if (left_over) {
 172                 ss->ss_end = start;
 173         } else if (right_over) {
 174                 ss->ss_start = end;
 175         } else {
 176                 avl_remove(&sm->sm_root, ss);
 177                 kmem_free(ss, sizeof (*ss));
 178         }
 179 
 180         sm->sm_space -= size;
 181 }
 182 


 183 int




















 184 space_map_contains(space_map_t *sm, uint64_t start, uint64_t size)
 185 {
 186         avl_index_t where;
 187         space_seg_t ssearch, *ss;
 188         uint64_t end = start + size;
 189 
 190         ASSERT(MUTEX_HELD(sm->sm_lock));
 191         VERIFY(size != 0);
 192         VERIFY(P2PHASE(start, 1ULL << sm->sm_shift) == 0);
 193         VERIFY(P2PHASE(size, 1ULL << sm->sm_shift) == 0);
 194 
 195         ssearch.ss_start = start;
 196         ssearch.ss_end = end;
 197         ss = avl_find(&sm->sm_root, &ssearch, &where);
 198 
 199         return (ss != NULL && ss->ss_start <= start && ss->ss_end >= end);
 200 }
 201 
 202 void
 203 space_map_vacate(space_map_t *sm, space_map_func_t *func, space_map_t *mdest)


 328         mutex_enter(sm->sm_lock);
 329 
 330         for (offset = 0; offset < end; offset += bufsize) {
 331                 size = MIN(end - offset, bufsize);
 332                 VERIFY(P2PHASE(size, sizeof (uint64_t)) == 0);
 333                 VERIFY(size != 0);
 334 
 335                 dprintf("object=%llu  offset=%llx  size=%llx\n",
 336                     smo->smo_object, offset, size);
 337 
 338                 mutex_exit(sm->sm_lock);
 339                 error = dmu_read(os, smo->smo_object, offset, size, entry_map);
 340                 mutex_enter(sm->sm_lock);
 341                 if (error != 0)
 342                         break;
 343 
 344                 entry_map_end = entry_map + (size / sizeof (uint64_t));
 345                 for (entry = entry_map; entry < entry_map_end; entry++) {
 346                         uint64_t e = *entry;
 347 
 348                         if (SM_DEBUG_DECODE(e))         /* Skip debug entries */
 349                                 continue;
 350 









 351                         (SM_TYPE_DECODE(e) == maptype ?
 352                             space_map_add : space_map_remove)(sm,
 353                             (SM_OFFSET_DECODE(e) << sm->sm_shift) + mapstart,
 354                             SM_RUN_DECODE(e) << sm->sm_shift);
 355                 }
 356         }
 357 
 358         if (error == 0) {
 359                 VERIFY3U(sm->sm_space, ==, space);
 360 
 361                 sm->sm_loaded = B_TRUE;
 362                 sm->sm_ops = ops;
 363                 if (ops != NULL)
 364                         ops->smop_load(sm);
 365         } else {
 366                 space_map_vacate(sm, NULL, NULL);
 367         }
 368 
 369         zio_buf_free(entry_map, bufsize);
 370 




 163         right_over = (ss->ss_end != end);
 164 
 165         if (left_over && right_over) {
 166                 newseg = kmem_alloc(sizeof (*newseg), KM_SLEEP);
 167                 newseg->ss_start = end;
 168                 newseg->ss_end = ss->ss_end;
 169                 ss->ss_end = start;
 170                 avl_insert_here(&sm->sm_root, newseg, ss, AVL_AFTER);
 171         } else if (left_over) {
 172                 ss->ss_end = start;
 173         } else if (right_over) {
 174                 ss->ss_start = end;
 175         } else {
 176                 avl_remove(&sm->sm_root, ss);
 177                 kmem_free(ss, sizeof (*ss));
 178         }
 179 
 180         sm->sm_space -= size;
 181 }
 182 
 183 
 184 
 185 int
 186 space_map_fold(space_map_t *sm, uint8_t oldwidth, uint8_t newwidth)
 187 {
 188         space_seg_t *ss;
 189         uint64_t d, r;
 190 
 191         ASSERT(MUTEX_HELD(sm->sm_lock));
 192 
 193         for (ss = avl_first(&sm->sm_root); ss != NULL;
 194             ss = AVL_NEXT(&sm->sm_root, ss)) {
 195                 d = ss->ss_start / oldwidth;
 196                 r = ss->ss_start % oldwidth;
 197                 ss->ss_start = d * newwidth + r;
 198 
 199                 d = ss->ss_end / oldwidth;
 200                 r = ss->ss_end % oldwidth;
 201                 ss->ss_end = d * newwidth + r;
 202         }
 203 }
 204 
 205 int
 206 space_map_contains(space_map_t *sm, uint64_t start, uint64_t size)
 207 {
 208         avl_index_t where;
 209         space_seg_t ssearch, *ss;
 210         uint64_t end = start + size;
 211 
 212         ASSERT(MUTEX_HELD(sm->sm_lock));
 213         VERIFY(size != 0);
 214         VERIFY(P2PHASE(start, 1ULL << sm->sm_shift) == 0);
 215         VERIFY(P2PHASE(size, 1ULL << sm->sm_shift) == 0);
 216 
 217         ssearch.ss_start = start;
 218         ssearch.ss_end = end;
 219         ss = avl_find(&sm->sm_root, &ssearch, &where);
 220 
 221         return (ss != NULL && ss->ss_start <= start && ss->ss_end >= end);
 222 }
 223 
 224 void
 225 space_map_vacate(space_map_t *sm, space_map_func_t *func, space_map_t *mdest)


 350         mutex_enter(sm->sm_lock);
 351 
 352         for (offset = 0; offset < end; offset += bufsize) {
 353                 size = MIN(end - offset, bufsize);
 354                 VERIFY(P2PHASE(size, sizeof (uint64_t)) == 0);
 355                 VERIFY(size != 0);
 356 
 357                 dprintf("object=%llu  offset=%llx  size=%llx\n",
 358                     smo->smo_object, offset, size);
 359 
 360                 mutex_exit(sm->sm_lock);
 361                 error = dmu_read(os, smo->smo_object, offset, size, entry_map);
 362                 mutex_enter(sm->sm_lock);
 363                 if (error != 0)
 364                         break;
 365 
 366                 entry_map_end = entry_map + (size / sizeof (uint64_t));
 367                 for (entry = entry_map; entry < entry_map_end; entry++) {
 368                         uint64_t e = *entry;
 369 
 370                         if (SM_IS_DEBUG(e))             /* Skip debug entries */
 371                                 continue;
 372 
 373                         if (SM_IS_SPECIAL(e)) {
 374                                 uint8_t oldwidth, newwidth;
 375                                 ASSERT(SM_SPECIAL_ACTION_DECODE(e) == SM_FOLD);
 376                                 oldwidth = BF64_ENCODE(e, 0, 8);
 377                                 newwidth = BF64_ENCODE(e, 8, 8);
 378                                 space_map_fold(sm, oldwidth, newwidth);
 379                                 continue;
 380                         }
 381 
 382                         (SM_TYPE_DECODE(e) == maptype ?
 383                             space_map_add : space_map_remove)(sm,
 384                             (SM_OFFSET_DECODE(e) << sm->sm_shift) + mapstart,
 385                             SM_RUN_DECODE(e) << sm->sm_shift);
 386                 }
 387         }
 388 
 389         if (error == 0) {
 390                 VERIFY3U(sm->sm_space, ==, space);
 391 
 392                 sm->sm_loaded = B_TRUE;
 393                 sm->sm_ops = ops;
 394                 if (ops != NULL)
 395                         ops->smop_load(sm);
 396         } else {
 397                 space_map_vacate(sm, NULL, NULL);
 398         }
 399 
 400         zio_buf_free(entry_map, bufsize);
 401