I'm very pleased to announce the release of our new website and documentation using the new toolchain with Hugo and AsciiDoctor. To get more information about the new toolchain please read the FreeBSD Documentation Project Primer[1], Hugo docs[2] and AsciiDoctor docs[3]. Acknowledgment: Benedict Reuschling <bcr@> Glen Barber <gjb@> Hiroki Sato <hrs@> Li-Wen Hsu <lwhsu@> Sean Chittenden <seanc@> The FreeBSD Foundation [1] https://docs.FreeBSD.org/en/books/fdp-primer/ [2] https://gohugo.io/documentation/ [3] https://docs.asciidoctor.org/home/ Approved by: doceng, core
256 lines
9.3 KiB
Diff
256 lines
9.3 KiB
Diff
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
|
|
===================================================================
|
|
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c (revision 284174)
|
|
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c (working copy)
|
|
@@ -344,6 +344,7 @@ typedef struct arc_stats {
|
|
kstat_named_t arcstat_l2_evict_lock_retry;
|
|
kstat_named_t arcstat_l2_evict_reading;
|
|
kstat_named_t arcstat_l2_free_on_write;
|
|
+ kstat_named_t arcstat_l2_cdata_free_on_write;
|
|
kstat_named_t arcstat_l2_abort_lowmem;
|
|
kstat_named_t arcstat_l2_cksum_bad;
|
|
kstat_named_t arcstat_l2_io_error;
|
|
@@ -421,6 +422,7 @@ static arc_stats_t arc_stats = {
|
|
{ "l2_evict_lock_retry", KSTAT_DATA_UINT64 },
|
|
{ "l2_evict_reading", KSTAT_DATA_UINT64 },
|
|
{ "l2_free_on_write", KSTAT_DATA_UINT64 },
|
|
+ { "l2_cdata_free_on_write", KSTAT_DATA_UINT64 },
|
|
{ "l2_abort_lowmem", KSTAT_DATA_UINT64 },
|
|
{ "l2_cksum_bad", KSTAT_DATA_UINT64 },
|
|
{ "l2_io_error", KSTAT_DATA_UINT64 },
|
|
@@ -1629,6 +1631,21 @@ arc_buf_add_ref(arc_buf_t *buf, void* tag)
|
|
data, metadata, hits);
|
|
}
|
|
|
|
+static void
|
|
+arc_buf_free_on_write(void *data, size_t size,
|
|
+ void (*free_func)(void *, size_t))
|
|
+{
|
|
+ l2arc_data_free_t *df;
|
|
+
|
|
+ df = kmem_alloc(sizeof (l2arc_data_free_t), KM_SLEEP);
|
|
+ df->l2df_data = data;
|
|
+ df->l2df_size = size;
|
|
+ df->l2df_func = free_func;
|
|
+ mutex_enter(&l2arc_free_on_write_mtx);
|
|
+ list_insert_head(l2arc_free_on_write, df);
|
|
+ mutex_exit(&l2arc_free_on_write_mtx);
|
|
+}
|
|
+
|
|
/*
|
|
* Free the arc data buffer. If it is an l2arc write in progress,
|
|
* the buffer is placed on l2arc_free_on_write to be freed later.
|
|
@@ -1639,14 +1656,7 @@ arc_buf_data_free(arc_buf_t *buf, void (*free_func
|
|
arc_buf_hdr_t *hdr = buf->b_hdr;
|
|
|
|
if (HDR_L2_WRITING(hdr)) {
|
|
- l2arc_data_free_t *df;
|
|
- df = kmem_alloc(sizeof (l2arc_data_free_t), KM_SLEEP);
|
|
- df->l2df_data = buf->b_data;
|
|
- df->l2df_size = hdr->b_size;
|
|
- df->l2df_func = free_func;
|
|
- mutex_enter(&l2arc_free_on_write_mtx);
|
|
- list_insert_head(l2arc_free_on_write, df);
|
|
- mutex_exit(&l2arc_free_on_write_mtx);
|
|
+ arc_buf_free_on_write(buf->b_data, hdr->b_size, free_func);
|
|
ARCSTAT_BUMP(arcstat_l2_free_on_write);
|
|
} else {
|
|
free_func(buf->b_data, hdr->b_size);
|
|
@@ -1658,6 +1668,23 @@ arc_buf_data_free(arc_buf_t *buf, void (*free_func
|
|
* arc_buf_t off of the the arc_buf_hdr_t's list and free it.
|
|
*/
|
|
static void
|
|
+arc_buf_l2_cdata_free(arc_buf_hdr_t *hdr)
|
|
+{
|
|
+ l2arc_buf_hdr_t *l2hdr = hdr->b_l2hdr;
|
|
+
|
|
+ ASSERT(MUTEX_HELD(&l2arc_buflist_mtx));
|
|
+
|
|
+ if (l2hdr->b_tmp_cdata == NULL)
|
|
+ return;
|
|
+
|
|
+ ASSERT(HDR_L2_WRITING(hdr));
|
|
+ arc_buf_free_on_write(l2hdr->b_tmp_cdata, hdr->b_size,
|
|
+ zio_data_buf_free);
|
|
+ ARCSTAT_BUMP(arcstat_l2_cdata_free_on_write);
|
|
+ l2hdr->b_tmp_cdata = NULL;
|
|
+}
|
|
+
|
|
+static void
|
|
arc_buf_destroy(arc_buf_t *buf, boolean_t recycle, boolean_t remove)
|
|
{
|
|
arc_buf_t **bufp;
|
|
@@ -1756,6 +1783,7 @@ arc_hdr_destroy(arc_buf_hdr_t *hdr)
|
|
trim_map_free(l2hdr->b_dev->l2ad_vdev, l2hdr->b_daddr,
|
|
hdr->b_size, 0);
|
|
list_remove(l2hdr->b_dev->l2ad_buflist, hdr);
|
|
+ arc_buf_l2_cdata_free(hdr);
|
|
ARCSTAT_INCR(arcstat_l2_size, -hdr->b_size);
|
|
ARCSTAT_INCR(arcstat_l2_asize, -l2hdr->b_asize);
|
|
vdev_space_update(l2hdr->b_dev->l2ad_vdev,
|
|
@@ -3605,6 +3633,7 @@ arc_release(arc_buf_t *buf, void *tag)
|
|
l2hdr = hdr->b_l2hdr;
|
|
if (l2hdr) {
|
|
mutex_enter(&l2arc_buflist_mtx);
|
|
+ arc_buf_l2_cdata_free(hdr);
|
|
hdr->b_l2hdr = NULL;
|
|
list_remove(l2hdr->b_dev->l2ad_buflist, hdr);
|
|
}
|
|
@@ -4895,6 +4924,11 @@ top:
|
|
ARCSTAT_INCR(arcstat_l2_asize, -abl2->b_asize);
|
|
bytes_evicted += abl2->b_asize;
|
|
ab->b_l2hdr = NULL;
|
|
+ /*
|
|
+ * We are destroying l2hdr, so ensure that
|
|
+ * its compressed buffer, if any, is not leaked.
|
|
+ */
|
|
+ ASSERT(abl2->b_tmp_cdata == NULL);
|
|
kmem_free(abl2, sizeof (l2arc_buf_hdr_t));
|
|
ARCSTAT_INCR(arcstat_l2_size, -ab->b_size);
|
|
}
|
|
@@ -5133,6 +5167,14 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev,
|
|
buf_data = l2hdr->b_tmp_cdata;
|
|
buf_sz = l2hdr->b_asize;
|
|
|
|
+ /*
|
|
+ * If the data has not been compressed, then clear b_tmp_cdata
|
|
+ * to make sure that it points only to a temporary compression
|
|
+ * buffer.
|
|
+ */
|
|
+ if (!L2ARC_IS_VALID_COMPRESS(l2hdr->b_compress))
|
|
+ l2hdr->b_tmp_cdata = NULL;
|
|
+
|
|
/* Compression may have squashed the buffer to zero length. */
|
|
if (buf_sz != 0) {
|
|
uint64_t buf_p_sz;
|
|
@@ -5323,7 +5365,8 @@ l2arc_release_cdata_buf(arc_buf_hdr_t *ab)
|
|
{
|
|
l2arc_buf_hdr_t *l2hdr = ab->b_l2hdr;
|
|
|
|
- if (l2hdr->b_compress == ZIO_COMPRESS_LZ4) {
|
|
+ ASSERT(L2ARC_IS_VALID_COMPRESS(l2hdr->b_compress));
|
|
+ if (l2hdr->b_compress != ZIO_COMPRESS_EMPTY) {
|
|
/*
|
|
* If the data was compressed, then we've allocated a
|
|
* temporary buffer for it, so now we need to release it.
|
|
@@ -5330,8 +5373,10 @@ l2arc_release_cdata_buf(arc_buf_hdr_t *ab)
|
|
*/
|
|
ASSERT(l2hdr->b_tmp_cdata != NULL);
|
|
zio_data_buf_free(l2hdr->b_tmp_cdata, ab->b_size);
|
|
+ l2hdr->b_tmp_cdata = NULL;
|
|
+ } else {
|
|
+ ASSERT(l2hdr->b_tmp_cdata == NULL);
|
|
}
|
|
- l2hdr->b_tmp_cdata = NULL;
|
|
}
|
|
|
|
/*
|
|
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c
|
|
===================================================================
|
|
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c (revision 284174)
|
|
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c (working copy)
|
|
@@ -155,11 +155,9 @@ trim_map_create(vdev_t *vd)
|
|
{
|
|
trim_map_t *tm;
|
|
|
|
- ASSERT(vd->vdev_ops->vdev_op_leaf);
|
|
+ ASSERT(zfs_trim_enabled && !vd->vdev_notrim &&
|
|
+ vd->vdev_ops->vdev_op_leaf);
|
|
|
|
- if (!zfs_trim_enabled)
|
|
- return;
|
|
-
|
|
tm = kmem_zalloc(sizeof (*tm), KM_SLEEP);
|
|
mutex_init(&tm->tm_lock, NULL, MUTEX_DEFAULT, NULL);
|
|
list_create(&tm->tm_head, sizeof (trim_seg_t),
|
|
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
|
|
===================================================================
|
|
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c (revision 284174)
|
|
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c (working copy)
|
|
@@ -1214,6 +1214,7 @@ vdev_open(vdev_t *vd)
|
|
vd->vdev_stat.vs_aux = VDEV_AUX_NONE;
|
|
vd->vdev_cant_read = B_FALSE;
|
|
vd->vdev_cant_write = B_FALSE;
|
|
+ vd->vdev_notrim = B_FALSE;
|
|
vd->vdev_min_asize = vdev_get_min_asize(vd);
|
|
|
|
/*
|
|
@@ -1283,10 +1284,8 @@ vdev_open(vdev_t *vd)
|
|
if (vd->vdev_ishole || vd->vdev_ops == &vdev_missing_ops)
|
|
return (0);
|
|
|
|
- if (vd->vdev_ops->vdev_op_leaf) {
|
|
- vd->vdev_notrim = B_FALSE;
|
|
+ if (zfs_trim_enabled && !vd->vdev_notrim && vd->vdev_ops->vdev_op_leaf)
|
|
trim_map_create(vd);
|
|
- }
|
|
|
|
for (int c = 0; c < vd->vdev_children; c++) {
|
|
if (vd->vdev_child[c]->vdev_state != VDEV_STATE_HEALTHY) {
|
|
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c
|
|
===================================================================
|
|
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c (revision 284174)
|
|
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c (working copy)
|
|
@@ -796,6 +796,8 @@ vdev_disk_io_start(zio_t *zio)
|
|
return (ZIO_PIPELINE_STOP);
|
|
}
|
|
|
|
+ ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE);
|
|
+
|
|
vb = kmem_alloc(sizeof (vdev_buf_t), KM_SLEEP);
|
|
|
|
vb->vb_io = zio;
|
|
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c
|
|
===================================================================
|
|
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c (revision 284174)
|
|
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c (working copy)
|
|
@@ -129,6 +129,8 @@ skip_open:
|
|
return (error);
|
|
}
|
|
|
|
+ vd->vdev_notrim = B_TRUE;
|
|
+
|
|
*max_psize = *psize = vattr.va_size;
|
|
*logical_ashift = SPA_MINBLOCKSHIFT;
|
|
*physical_ashift = SPA_MINBLOCKSHIFT;
|
|
@@ -185,6 +187,8 @@ vdev_file_io_start(zio_t *zio)
|
|
return (ZIO_PIPELINE_STOP);
|
|
}
|
|
|
|
+ ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE);
|
|
+
|
|
zio->io_error = vn_rdwr(zio->io_type == ZIO_TYPE_READ ?
|
|
UIO_READ : UIO_WRITE, vp, zio->io_data, zio->io_size,
|
|
zio->io_offset, UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred, &resid);
|
|
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
|
|
===================================================================
|
|
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c (revision 284174)
|
|
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c (working copy)
|
|
@@ -832,6 +832,11 @@ vdev_geom_io_start(zio_t *zio)
|
|
return (ZIO_PIPELINE_STOP);
|
|
}
|
|
sendreq:
|
|
+ ASSERT(zio->io_type == ZIO_TYPE_READ ||
|
|
+ zio->io_type == ZIO_TYPE_WRITE ||
|
|
+ zio->io_type == ZIO_TYPE_FREE ||
|
|
+ zio->io_type == ZIO_TYPE_IOCTL);
|
|
+
|
|
cp = vd->vdev_tsd;
|
|
if (cp == NULL) {
|
|
zio->io_error = SET_ERROR(ENXIO);
|
|
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c
|
|
===================================================================
|
|
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c (revision 284174)
|
|
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c (working copy)
|
|
@@ -713,8 +713,9 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_l
|
|
* Don't TRIM if removing so that we don't interfere with zpool
|
|
* disaster recovery.
|
|
*/
|
|
- if (zfs_trim_enabled && vdev_trim_on_init && (reason == VDEV_LABEL_CREATE ||
|
|
- reason == VDEV_LABEL_SPARE || reason == VDEV_LABEL_L2CACHE))
|
|
+ if (zfs_trim_enabled && vdev_trim_on_init && !vd->vdev_notrim &&
|
|
+ (reason == VDEV_LABEL_CREATE || reason == VDEV_LABEL_SPARE ||
|
|
+ reason == VDEV_LABEL_L2CACHE))
|
|
zio_wait(zio_trim(NULL, spa, vd, 0, vd->vdev_psize));
|
|
|
|
/*
|