| 9526 | } |
| 9527 | |
| 9528 | void |
| 9529 | l2arc_rebuild_vdev(vdev_t *vd, boolean_t reopen) |
| 9530 | { |
| 9531 | l2arc_dev_t *dev = NULL; |
| 9532 | l2arc_dev_hdr_phys_t *l2dhdr; |
| 9533 | uint64_t l2dhdr_asize; |
| 9534 | spa_t *spa; |
| 9535 | |
| 9536 | dev = l2arc_vdev_get(vd); |
| 9537 | ASSERT3P(dev, !=, NULL); |
| 9538 | spa = dev->l2ad_spa; |
| 9539 | l2dhdr = dev->l2ad_dev_hdr; |
| 9540 | l2dhdr_asize = dev->l2ad_dev_hdr_asize; |
| 9541 | |
| 9542 | /* |
| 9543 | * The L2ARC has to hold at least the payload of one log block for |
| 9544 | * them to be restored (persistent L2ARC). The payload of a log block |
| 9545 | * depends on the amount of its log entries. We always write log blocks |
| 9546 | * with 1022 entries. How many of them are committed or restored depends |
| 9547 | * on the size of the L2ARC device. Thus the maximum payload of |
| 9548 | * one log block is 1022 * SPA_MAXBLOCKSIZE = 16GB. If the L2ARC device |
| 9549 | * is less than that, we reduce the amount of committed and restored |
| 9550 | * log entries per block so as to enable persistence. |
| 9551 | */ |
| 9552 | if (dev->l2ad_end < l2arc_rebuild_blocks_min_l2size) { |
| 9553 | dev->l2ad_log_entries = 0; |
| 9554 | } else { |
| 9555 | dev->l2ad_log_entries = MIN((dev->l2ad_end - |
| 9556 | dev->l2ad_start) >> SPA_MAXBLOCKSHIFT, |
| 9557 | L2ARC_LOG_BLK_MAX_ENTRIES); |
| 9558 | } |
| 9559 | |
| 9560 | /* |
| 9561 | * Read the device header, if an error is returned do not rebuild L2ARC. |
| 9562 | */ |
| 9563 | if (l2arc_dev_hdr_read(dev) == 0 && dev->l2ad_log_entries > 0) { |
| 9564 | /* |
| 9565 | * If we are onlining a cache device (vdev_reopen) that was |
| 9566 | * still present (l2arc_vdev_present()) and rebuild is enabled, |
| 9567 | * we should evict all ARC buffers and pointers to log blocks |
| 9568 | * and reclaim their space before restoring its contents to |
| 9569 | * L2ARC. |
| 9570 | */ |
| 9571 | if (reopen) { |
| 9572 | if (!l2arc_rebuild_enabled) { |
| 9573 | return; |
| 9574 | } else { |
| 9575 | l2arc_evict(dev, 0, B_TRUE); |
| 9576 | /* start a new log block */ |
| 9577 | dev->l2ad_log_ent_idx = 0; |
| 9578 | dev->l2ad_log_blk_payload_asize = 0; |
| 9579 | dev->l2ad_log_blk_payload_start = 0; |
| 9580 | } |
| 9581 | } |
| 9582 | /* |
| 9583 | * Just mark the device as pending for a rebuild. We won't |
| 9584 | * be starting a rebuild in line here as it would block pool |
| 9585 | * import. Instead spa_load_impl will hand that off to an |
no test coverage detected