* Commits a log block to the L2ARC device. This routine is invoked from * l2arc_write_buffers when the log block fills up. * This function allocates some memory to temporarily hold the serialized * buffer to be written. This is then released in l2arc_write_done. */
| 10396 | * buffer to be written. This is then released in l2arc_write_done. |
| 10397 | */ |
| 10398 | static void |
| 10399 | l2arc_log_blk_commit(l2arc_dev_t *dev, zio_t *pio, l2arc_write_callback_t *cb) |
| 10400 | { |
| 10401 | l2arc_log_blk_phys_t *lb = &dev->l2ad_log_blk; |
| 10402 | l2arc_dev_hdr_phys_t *l2dhdr = dev->l2ad_dev_hdr; |
| 10403 | uint64_t psize, asize; |
| 10404 | zio_t *wzio; |
| 10405 | l2arc_lb_abd_buf_t *abd_buf; |
| 10406 | uint8_t *tmpbuf; |
| 10407 | l2arc_lb_ptr_buf_t *lb_ptr_buf; |
| 10408 | |
| 10409 | VERIFY3S(dev->l2ad_log_ent_idx, ==, dev->l2ad_log_entries); |
| 10410 | |
| 10411 | tmpbuf = zio_buf_alloc(sizeof (*lb)); |
| 10412 | abd_buf = zio_buf_alloc(sizeof (*abd_buf)); |
| 10413 | abd_buf->abd = abd_get_from_buf(lb, sizeof (*lb)); |
| 10414 | lb_ptr_buf = kmem_zalloc(sizeof (l2arc_lb_ptr_buf_t), KM_SLEEP); |
| 10415 | lb_ptr_buf->lb_ptr = kmem_zalloc(sizeof (l2arc_log_blkptr_t), KM_SLEEP); |
| 10416 | |
| 10417 | /* link the buffer into the block chain */ |
| 10418 | lb->lb_prev_lbp = l2dhdr->dh_start_lbps[1]; |
| 10419 | lb->lb_magic = L2ARC_LOG_BLK_MAGIC; |
| 10420 | |
| 10421 | /* |
| 10422 | * l2arc_log_blk_commit() may be called multiple times during a single |
| 10423 | * l2arc_write_buffers() call. Save the allocated abd buffers in a list |
| 10424 | * so we can free them in l2arc_write_done() later on. |
| 10425 | */ |
| 10426 | list_insert_tail(&cb->l2wcb_abd_list, abd_buf); |
| 10427 | |
| 10428 | /* try to compress the buffer */ |
| 10429 | psize = zio_compress_data(ZIO_COMPRESS_LZ4, |
| 10430 | abd_buf->abd, tmpbuf, sizeof (*lb), 0); |
| 10431 | |
| 10432 | /* a log block is never entirely zero */ |
| 10433 | ASSERT(psize != 0); |
| 10434 | asize = vdev_psize_to_asize(dev->l2ad_vdev, psize); |
| 10435 | ASSERT(asize <= sizeof (*lb)); |
| 10436 | |
| 10437 | /* |
| 10438 | * Update the start log block pointer in the device header to point |
| 10439 | * to the log block we're about to write. |
| 10440 | */ |
| 10441 | l2dhdr->dh_start_lbps[1] = l2dhdr->dh_start_lbps[0]; |
| 10442 | l2dhdr->dh_start_lbps[0].lbp_daddr = dev->l2ad_hand; |
| 10443 | l2dhdr->dh_start_lbps[0].lbp_payload_asize = |
| 10444 | dev->l2ad_log_blk_payload_asize; |
| 10445 | l2dhdr->dh_start_lbps[0].lbp_payload_start = |
| 10446 | dev->l2ad_log_blk_payload_start; |
| 10447 | _NOTE(CONSTCOND) |
| 10448 | L2BLK_SET_LSIZE( |
| 10449 | (&l2dhdr->dh_start_lbps[0])->lbp_prop, sizeof (*lb)); |
| 10450 | L2BLK_SET_PSIZE( |
| 10451 | (&l2dhdr->dh_start_lbps[0])->lbp_prop, asize); |
| 10452 | L2BLK_SET_CHECKSUM( |
| 10453 | (&l2dhdr->dh_start_lbps[0])->lbp_prop, |
| 10454 | ZIO_CHECKSUM_FLETCHER_4); |
| 10455 | if (asize < sizeof (*lb)) { |
no test coverage detected