changeset 1175:759d20c7e57b

6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz 6347491 libzfs: need vdevs structures to report size of underlying device 6347855 readonly property is not updated on volumes. 6350421 Internal Error returned from 'zfs set volsize' on a readonly volume
author lling
date Thu, 22 Dec 2005 16:47:43 -0800
parents edc9bda8ff27
children a1cfa1e3b6b5
files usr/src/lib/libzfs/common/libzfs_dataset.c usr/src/uts/common/fs/zfs/spa.c usr/src/uts/common/fs/zfs/sys/vdev_impl.h usr/src/uts/common/fs/zfs/vdev.c usr/src/uts/common/fs/zfs/zvol.c usr/src/uts/common/sys/fs/zfs.h
diffstat 6 files changed, 56 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c	Thu Dec 22 16:02:27 2005 -0800
+++ b/usr/src/lib/libzfs/common/libzfs_dataset.c	Thu Dec 22 16:47:43 2005 -0800
@@ -883,6 +883,12 @@
 			}
 			break;
 
+		case EROFS:
+			zfs_error(dgettext(TEXT_DOMAIN, "cannot set %s for "
+			    "'%s': read only %s"), propname, zhp->zfs_name,
+			    zfs_type_to_name(zhp->zfs_type));
+			break;
+
 		case EOVERFLOW:
 			/*
 			 * This platform can't address a volume this big.
--- a/usr/src/uts/common/fs/zfs/spa.c	Thu Dec 22 16:02:27 2005 -0800
+++ b/usr/src/uts/common/fs/zfs/spa.c	Thu Dec 22 16:47:43 2005 -0800
@@ -910,7 +910,11 @@
 	if ((error = vdev_create(newrootvd, txg)) != 0)
 		return (spa_vdev_exit(spa, newrootvd, txg, error));
 
-	if (newvd->vdev_psize < oldvd->vdev_psize)
+	/*
+	 * Compare the new device size with the replaceable/attachable
+	 * device size.
+	 */
+	if (newvd->vdev_psize < vdev_get_rsize(oldvd))
 		return (spa_vdev_exit(spa, newrootvd, txg, EOVERFLOW));
 
 	if (newvd->vdev_ashift != oldvd->vdev_ashift && oldvd->vdev_ashift != 0)
--- a/usr/src/uts/common/fs/zfs/sys/vdev_impl.h	Thu Dec 22 16:02:27 2005 -0800
+++ b/usr/src/uts/common/fs/zfs/sys/vdev_impl.h	Thu Dec 22 16:47:43 2005 -0800
@@ -277,9 +277,10 @@
 extern vdev_ops_t vdev_missing_ops;
 
 /*
- * Common asize function
+ * Common size functions
  */
 extern uint64_t vdev_default_asize(vdev_t *vd, uint64_t psize);
+extern uint64_t vdev_get_rsize(vdev_t *vd);
 
 #ifdef	__cplusplus
 }
--- a/usr/src/uts/common/fs/zfs/vdev.c	Thu Dec 22 16:02:27 2005 -0800
+++ b/usr/src/uts/common/fs/zfs/vdev.c	Thu Dec 22 16:47:43 2005 -0800
@@ -89,6 +89,43 @@
 	return (asize);
 }
 
+/*
+ * Get the replaceable or attachable device size.
+ * If the parent is a mirror or raidz, the replaceable size is the minimum
+ * psize of all its children. For the rest, just return our own psize.
+ *
+ * e.g.
+ *			psize	rsize
+ * root			-	-
+ *	mirror/raidz	-	-
+ *	    disk1	20g	20g
+ *	    disk2 	40g	20g
+ *	disk3 		80g	80g
+ */
+uint64_t
+vdev_get_rsize(vdev_t *vd)
+{
+	vdev_t *pvd, *cvd;
+	uint64_t c, rsize;
+
+	pvd = vd->vdev_parent;
+
+	/*
+	 * If our parent is NULL or the root, just return our own psize.
+	 */
+	if (pvd == NULL || pvd->vdev_parent == NULL)
+		return (vd->vdev_psize);
+
+	rsize = 0;
+
+	for (c = 0; c < pvd->vdev_children; c++) {
+		cvd = pvd->vdev_child[c];
+		rsize = MIN(rsize - 1, cvd->vdev_psize - 1) + 1;
+	}
+
+	return (rsize);
+}
+
 vdev_t *
 vdev_lookup_top(spa_t *spa, uint64_t vdev)
 {
@@ -1442,6 +1479,7 @@
 	bcopy(&vd->vdev_stat, vs, sizeof (*vs));
 	vs->vs_timestamp = gethrtime() - vs->vs_timestamp;
 	vs->vs_state = vd->vdev_state;
+	vs->vs_rsize = vdev_get_rsize(vd);
 	mutex_exit(&vd->vdev_stat_lock);
 
 	/*
--- a/usr/src/uts/common/fs/zfs/zvol.c	Thu Dec 22 16:02:27 2005 -0800
+++ b/usr/src/uts/common/fs/zfs/zvol.c	Thu Dec 22 16:47:43 2005 -0800
@@ -165,6 +165,10 @@
 	if (error == 0)
 		zc->zc_volblocksize = doi.doi_data_block_size;
 
+	error = dsl_prop_get_integer(zc->zc_name, "readonly",
+			&zc->zc_zfs_stats.zs_readonly,
+			zc->zc_zfs_stats.zs_readonly_setpoint);
+
 	return (error);
 }
 
--- a/usr/src/uts/common/sys/fs/zfs.h	Thu Dec 22 16:02:27 2005 -0800
+++ b/usr/src/uts/common/sys/fs/zfs.h	Thu Dec 22 16:47:43 2005 -0800
@@ -228,6 +228,7 @@
 	uint64_t	vs_aux;			/* see vdev_aux_t	*/
 	uint64_t	vs_alloc;		/* space allocated	*/
 	uint64_t	vs_space;		/* total capacity	*/
+	uint64_t	vs_rsize;		/* replaceable dev size */
 	uint64_t	vs_ops[ZIO_TYPES];	/* operation count	*/
 	uint64_t	vs_bytes[ZIO_TYPES];	/* bytes read/written	*/
 	uint64_t	vs_read_errors;		/* read errors		*/