mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-27 11:29:36 +03:00
OpenZFS 5220 - L2ARC does not support devices that do not provide 512B access
Authored by: Andriy Gapon <avg@FreeBSD.org> Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Dan Kimmel <dan.kimmel@delphix.com> Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com> Approved by: Dan McDonald <danmcd@joyent.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Ported-by: Giuseppe Di Natale <dinatale2@llnl.gov> OpenZFS-issue: https://www.illumos.org/issues/5220 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/403a8da Closes #6260
This commit is contained in:
parent
d12f91fde3
commit
82710e993a
@ -956,6 +956,7 @@ typedef struct l2arc_read_callback {
|
|||||||
blkptr_t l2rcb_bp; /* original blkptr */
|
blkptr_t l2rcb_bp; /* original blkptr */
|
||||||
zbookmark_phys_t l2rcb_zb; /* original bookmark */
|
zbookmark_phys_t l2rcb_zb; /* original bookmark */
|
||||||
int l2rcb_flags; /* original flags */
|
int l2rcb_flags; /* original flags */
|
||||||
|
abd_t *l2rcb_abd; /* temporary buffer */
|
||||||
} l2arc_read_callback_t;
|
} l2arc_read_callback_t;
|
||||||
|
|
||||||
typedef struct l2arc_data_free {
|
typedef struct l2arc_data_free {
|
||||||
@ -5355,6 +5356,8 @@ top:
|
|||||||
!HDR_L2_WRITING(hdr) && !HDR_L2_EVICTED(hdr) &&
|
!HDR_L2_WRITING(hdr) && !HDR_L2_EVICTED(hdr) &&
|
||||||
!(l2arc_noprefetch && HDR_PREFETCH(hdr))) {
|
!(l2arc_noprefetch && HDR_PREFETCH(hdr))) {
|
||||||
l2arc_read_callback_t *cb;
|
l2arc_read_callback_t *cb;
|
||||||
|
abd_t *abd;
|
||||||
|
uint64_t asize;
|
||||||
|
|
||||||
DTRACE_PROBE1(l2arc__hit, arc_buf_hdr_t *, hdr);
|
DTRACE_PROBE1(l2arc__hit, arc_buf_hdr_t *, hdr);
|
||||||
ARCSTAT_BUMP(arcstat_l2_hits);
|
ARCSTAT_BUMP(arcstat_l2_hits);
|
||||||
@ -5367,8 +5370,17 @@ top:
|
|||||||
cb->l2rcb_zb = *zb;
|
cb->l2rcb_zb = *zb;
|
||||||
cb->l2rcb_flags = zio_flags;
|
cb->l2rcb_flags = zio_flags;
|
||||||
|
|
||||||
|
asize = vdev_psize_to_asize(vd, size);
|
||||||
|
if (asize != size) {
|
||||||
|
abd = abd_alloc_for_io(asize,
|
||||||
|
HDR_ISTYPE_METADATA(hdr));
|
||||||
|
cb->l2rcb_abd = abd;
|
||||||
|
} else {
|
||||||
|
abd = hdr->b_l1hdr.b_pabd;
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT(addr >= VDEV_LABEL_START_SIZE &&
|
ASSERT(addr >= VDEV_LABEL_START_SIZE &&
|
||||||
addr + lsize < vd->vdev_psize -
|
addr + asize <= vd->vdev_psize -
|
||||||
VDEV_LABEL_END_SIZE);
|
VDEV_LABEL_END_SIZE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5380,7 +5392,7 @@ top:
|
|||||||
ASSERT3U(HDR_GET_COMPRESS(hdr), !=,
|
ASSERT3U(HDR_GET_COMPRESS(hdr), !=,
|
||||||
ZIO_COMPRESS_EMPTY);
|
ZIO_COMPRESS_EMPTY);
|
||||||
rzio = zio_read_phys(pio, vd, addr,
|
rzio = zio_read_phys(pio, vd, addr,
|
||||||
size, hdr->b_l1hdr.b_pabd,
|
asize, abd,
|
||||||
ZIO_CHECKSUM_OFF,
|
ZIO_CHECKSUM_OFF,
|
||||||
l2arc_read_done, cb, priority,
|
l2arc_read_done, cb, priority,
|
||||||
zio_flags | ZIO_FLAG_DONT_CACHE |
|
zio_flags | ZIO_FLAG_DONT_CACHE |
|
||||||
@ -7045,6 +7057,33 @@ l2arc_read_done(zio_t *zio)
|
|||||||
mutex_enter(hash_lock);
|
mutex_enter(hash_lock);
|
||||||
ASSERT3P(hash_lock, ==, HDR_LOCK(hdr));
|
ASSERT3P(hash_lock, ==, HDR_LOCK(hdr));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the data was read into a temporary buffer,
|
||||||
|
* move it and free the buffer.
|
||||||
|
*/
|
||||||
|
if (cb->l2rcb_abd != NULL) {
|
||||||
|
ASSERT3U(arc_hdr_size(hdr), <, zio->io_size);
|
||||||
|
if (zio->io_error == 0) {
|
||||||
|
abd_copy(hdr->b_l1hdr.b_pabd, cb->l2rcb_abd,
|
||||||
|
arc_hdr_size(hdr));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following must be done regardless of whether
|
||||||
|
* there was an error:
|
||||||
|
* - free the temporary buffer
|
||||||
|
* - point zio to the real ARC buffer
|
||||||
|
* - set zio size accordingly
|
||||||
|
* These are required because zio is either re-used for
|
||||||
|
* an I/O of the block in the case of the error
|
||||||
|
* or the zio is passed to arc_read_done() and it
|
||||||
|
* needs real data.
|
||||||
|
*/
|
||||||
|
abd_free(cb->l2rcb_abd);
|
||||||
|
zio->io_size = zio->io_orig_size = arc_hdr_size(hdr);
|
||||||
|
zio->io_abd = zio->io_orig_abd = hdr->b_l1hdr.b_pabd;
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT3P(zio->io_abd, !=, NULL);
|
ASSERT3P(zio->io_abd, !=, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -7391,22 +7430,32 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
|
|||||||
* Normally the L2ARC can use the hdr's data, but if
|
* Normally the L2ARC can use the hdr's data, but if
|
||||||
* we're sharing data between the hdr and one of its
|
* we're sharing data between the hdr and one of its
|
||||||
* bufs, L2ARC needs its own copy of the data so that
|
* bufs, L2ARC needs its own copy of the data so that
|
||||||
* the ZIO below can't race with the buf consumer. To
|
* the ZIO below can't race with the buf consumer.
|
||||||
* ensure that this copy will be available for the
|
* Another case where we need to create a copy of the
|
||||||
|
* data is when the buffer size is not device-aligned
|
||||||
|
* and we need to pad the block to make it such.
|
||||||
|
* That also keeps the clock hand suitably aligned.
|
||||||
|
*
|
||||||
|
* To ensure that the copy will be available for the
|
||||||
* lifetime of the ZIO and be cleaned up afterwards, we
|
* lifetime of the ZIO and be cleaned up afterwards, we
|
||||||
* add it to the l2arc_free_on_write queue.
|
* add it to the l2arc_free_on_write queue.
|
||||||
*/
|
*/
|
||||||
if (!HDR_SHARED_DATA(hdr)) {
|
asize = vdev_psize_to_asize(dev->l2ad_vdev, size);
|
||||||
|
if (!HDR_SHARED_DATA(hdr) && size == asize) {
|
||||||
to_write = hdr->b_l1hdr.b_pabd;
|
to_write = hdr->b_l1hdr.b_pabd;
|
||||||
} else {
|
} else {
|
||||||
to_write = abd_alloc_for_io(size,
|
to_write = abd_alloc_for_io(asize,
|
||||||
HDR_ISTYPE_METADATA(hdr));
|
HDR_ISTYPE_METADATA(hdr));
|
||||||
abd_copy(to_write, hdr->b_l1hdr.b_pabd, size);
|
abd_copy(to_write, hdr->b_l1hdr.b_pabd, size);
|
||||||
|
if (asize != size) {
|
||||||
|
abd_zero_off(to_write, size,
|
||||||
|
asize - size);
|
||||||
|
}
|
||||||
l2arc_free_abd_on_write(to_write, size,
|
l2arc_free_abd_on_write(to_write, size,
|
||||||
arc_buf_type(hdr));
|
arc_buf_type(hdr));
|
||||||
}
|
}
|
||||||
wzio = zio_write_phys(pio, dev->l2ad_vdev,
|
wzio = zio_write_phys(pio, dev->l2ad_vdev,
|
||||||
hdr->b_l2hdr.b_daddr, size, to_write,
|
hdr->b_l2hdr.b_daddr, asize, to_write,
|
||||||
ZIO_CHECKSUM_OFF, NULL, hdr,
|
ZIO_CHECKSUM_OFF, NULL, hdr,
|
||||||
ZIO_PRIORITY_ASYNC_WRITE,
|
ZIO_PRIORITY_ASYNC_WRITE,
|
||||||
ZIO_FLAG_CANFAIL, B_FALSE);
|
ZIO_FLAG_CANFAIL, B_FALSE);
|
||||||
@ -7416,10 +7465,6 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
|
|||||||
zio_t *, wzio);
|
zio_t *, wzio);
|
||||||
|
|
||||||
write_asize += size;
|
write_asize += size;
|
||||||
/*
|
|
||||||
* Keep the clock hand suitably device-aligned.
|
|
||||||
*/
|
|
||||||
asize = vdev_psize_to_asize(dev->l2ad_vdev, size);
|
|
||||||
write_psize += asize;
|
write_psize += asize;
|
||||||
dev->l2ad_hand += asize;
|
dev->l2ad_hand += asize;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user