[Glibc-bsd-commits] r5748 - in trunk/kfreebsd-10/debian: . patches

stevenc-guest at alioth.debian.org stevenc-guest at alioth.debian.org
Tue Aug 4 11:45:01 UTC 2015


Author: stevenc-guest
Date: 2015-08-04 11:45:01 +0000 (Tue, 04 Aug 2015)
New Revision: 5748

Added:
   trunk/kfreebsd-10/debian/patches/EN-15_07.zfs.patch
Modified:
   trunk/kfreebsd-10/debian/changelog
   trunk/kfreebsd-10/debian/patches/series
Log:
Pick SVN r284193 from FreeBSD 10.1-RELEASE to fix:
- EN-15:07: ZFS Reliability Improvements.


Modified: trunk/kfreebsd-10/debian/changelog
===================================================================
--- trunk/kfreebsd-10/debian/changelog	2015-08-04 11:36:01 UTC (rev 5747)
+++ trunk/kfreebsd-10/debian/changelog	2015-08-04 11:45:01 UTC (rev 5748)
@@ -7,6 +7,8 @@
       state.
   * Pick SVN r285979 from FreeBSD 10.1-RELEASE to fix:
     - SA-15:15: Resource exhaustion in TCP reassembly.
+  * Pick SVN r284193 from FreeBSD 10.1-RELEASE to fix:
+    - EN-15:07: ZFS Reliability Improvements.
   * Use new preferred hostname for upstream SVN with HTTPS
     (svn.freebsd.org).
 

Added: trunk/kfreebsd-10/debian/patches/EN-15_07.zfs.patch
===================================================================
--- trunk/kfreebsd-10/debian/patches/EN-15_07.zfs.patch	                        (rev 0)
+++ trunk/kfreebsd-10/debian/patches/EN-15_07.zfs.patch	2015-08-04 11:45:01 UTC (rev 5748)
@@ -0,0 +1,246 @@
+Description:
+ Improve reliability of ZFS when TRIM/UNMAP and/or L2ARC is used. [EN-15:07]
+Origin: vendor, https://security.FreeBSD.org/patches/SA-15:15/tcp.patch
+Bug: https://security.FreeBSD.org/patches/EN-15:07/zfs.patch
+Applied-Upstream: https://svnweb.freebsd.org/base?view=revision&revision=284193
+
+--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c
++++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c
+@@ -713,8 +713,9 @@
+ 	 * 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));
+ 
+ 	/*
+--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c
++++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c
+@@ -129,6 +129,8 @@
+ 		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 @@
+ 		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);
+--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
++++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
+@@ -1214,6 +1214,7 @@
+ 	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 @@
+ 	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) {
+--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
++++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
+@@ -344,6 +344,7 @@
+ 	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 @@
+ 	{ "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 @@
+ 	    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_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_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 @@
+ 			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 @@
+ 	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 @@
+ 				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 @@
+ 		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,15 +5365,18 @@
+ {
+ 	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.
+ 		 */
+ 		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;
+ }
+ 
+ /*
+--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
++++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
+@@ -832,6 +832,11 @@
+ 		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);
+--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c
++++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c
+@@ -155,10 +155,8 @@
+ {
+ 	trim_map_t *tm;
+ 
+-	ASSERT(vd->vdev_ops->vdev_op_leaf);
+-
+-	if (!zfs_trim_enabled)
+-		return;
++	ASSERT(zfs_trim_enabled && !vd->vdev_notrim &&
++		vd->vdev_ops->vdev_op_leaf);
+ 
+ 	tm = kmem_zalloc(sizeof (*tm), KM_SLEEP);
+ 	mutex_init(&tm->tm_lock, NULL, MUTEX_DEFAULT, NULL);
+--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c
++++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c
+@@ -796,6 +796,8 @@
+ 		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;

Modified: trunk/kfreebsd-10/debian/patches/series
===================================================================
--- trunk/kfreebsd-10/debian/patches/series	2015-08-04 11:36:01 UTC (rev 5747)
+++ trunk/kfreebsd-10/debian/patches/series	2015-08-04 11:45:01 UTC (rev 5748)
@@ -46,3 +46,4 @@
 EN-15_05.ufs.patch
 SA-15_13.tcp.patch
 SA-15_15.tcp.patch
+EN-15_07.zfs.patch




More information about the Glibc-bsd-commits mailing list