Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 5 Mar 2011 22:31:03 +0000 (UTC)
From:      Pawel Jakub Dawidek <pjd@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r219317 - in head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs: . sys
Message-ID:  <201103052231.p25MV3fd078293@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pjd
Date: Sat Mar  5 22:31:03 2011
New Revision: 219317
URL: http://svn.freebsd.org/changeset/base/219317

Log:
  Make renaming of a ZVOL, ZVOL's parent directory and ZVOL snapshot work.
  
  Reported by:	avg
  MFC after:	1 month

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c	Sat Mar  5 22:24:31 2011	(r219316)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c	Sat Mar  5 22:31:03 2011	(r219317)
@@ -2312,6 +2312,7 @@ dsl_dataset_snapshot_rename_check(void *
 static void
 dsl_dataset_snapshot_rename_sync(void *arg1, void *arg2, dmu_tx_t *tx)
 {
+	char oldname[MAXPATHLEN], newname[MAXPATHLEN];
 	dsl_dataset_t *ds = arg1;
 	const char *newsnapname = arg2;
 	dsl_dir_t *dd = ds->ds_dir;
@@ -2327,12 +2328,15 @@ dsl_dataset_snapshot_rename_sync(void *a
 	VERIFY(0 == dsl_dataset_get_snapname(ds));
 	err = dsl_dataset_snap_remove(hds, ds->ds_snapname, tx);
 	ASSERT3U(err, ==, 0);
+	dsl_dataset_name(ds, oldname);
 	mutex_enter(&ds->ds_lock);
 	(void) strcpy(ds->ds_snapname, newsnapname);
 	mutex_exit(&ds->ds_lock);
 	err = zap_add(mos, hds->ds_phys->ds_snapnames_zapobj,
 	    ds->ds_snapname, 8, 1, &ds->ds_object, tx);
 	ASSERT3U(err, ==, 0);
+	dsl_dataset_name(ds, newname);
+	zvol_rename_minors(oldname, newname);
 
 	spa_history_log_internal(LOG_DS_RENAME, dd->dd_pool->dp_spa, tx,
 	    "dataset = %llu", ds->ds_object);

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c	Sat Mar  5 22:24:31 2011	(r219316)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c	Sat Mar  5 22:31:03 2011	(r219317)
@@ -36,6 +36,7 @@
 #include <sys/zio.h>
 #include <sys/arc.h>
 #include <sys/sunddi.h>
+#include <sys/zvol.h>
 #include "zfs_namecheck.h"
 
 static uint64_t dsl_dir_space_towrite(dsl_dir_t *dd);
@@ -1294,6 +1295,7 @@ dsl_dir_rename_check(void *arg1, void *a
 static void
 dsl_dir_rename_sync(void *arg1, void *arg2, dmu_tx_t *tx)
 {
+	char oldname[MAXPATHLEN], newname[MAXPATHLEN];
 	dsl_dir_t *dd = arg1;
 	struct renamearg *ra = arg2;
 	dsl_pool_t *dp = dd->dd_pool;
@@ -1326,6 +1328,7 @@ dsl_dir_rename_sync(void *arg1, void *ar
 	dmu_buf_will_dirty(dd->dd_dbuf, tx);
 
 	/* remove from old parent zapobj */
+	dsl_dir_name(dd, oldname);
 	err = zap_remove(mos, dd->dd_parent->dd_phys->dd_child_dir_zapobj,
 	    dd->dd_myname, tx);
 	ASSERT3U(err, ==, 0);
@@ -1340,6 +1343,8 @@ dsl_dir_rename_sync(void *arg1, void *ar
 	err = zap_add(mos, ra->newparent->dd_phys->dd_child_dir_zapobj,
 	    dd->dd_myname, 8, 1, &dd->dd_object, tx);
 	ASSERT3U(err, ==, 0);
+	dsl_dir_name(dd, newname);
+	zvol_rename_minors(oldname, newname);
 
 	spa_history_log_internal(LOG_DS_RENAME, dd->dd_pool->dp_spa,
 	    tx, "dataset = %llu", dd->dd_phys->dd_head_dataset_obj);

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h	Sat Mar  5 22:24:31 2011	(r219316)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h	Sat Mar  5 22:31:03 2011	(r219317)
@@ -73,6 +73,7 @@ extern void zvol_log_write_minor(void *m
 
 #ifdef __FreeBSD__
 extern int zvol_create_minors(const char *name);
+extern void zvol_rename_minors(const char *oldname, const char *newname);
 #endif
 
 #endif

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c	Sat Mar  5 22:24:31 2011	(r219316)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c	Sat Mar  5 22:31:03 2011	(r219317)
@@ -3271,8 +3271,6 @@ zfs_ioc_rename(zfs_cmd_t *zc)
 		if (err)
 			return (err);
 	}
-	if (zc->zc_objset_type == DMU_OST_ZVOL)
-		(void) zvol_remove_minor(zc->zc_name);
 	return (dmu_objset_rename(zc->zc_name, zc->zc_value, recursive));
 }
 

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c	Sat Mar  5 22:24:31 2011	(r219316)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c	Sat Mar  5 22:31:03 2011	(r219317)
@@ -2223,3 +2223,70 @@ zvol_create_minors(const char *name)
 	kmem_free(osname, MAXPATHLEN);
 	return (0);
 }
+
+static void
+zvol_rename_minor(struct g_geom *gp, const char *newname)
+{
+	struct g_provider *pp;
+	zvol_state_t *zv;
+
+	ASSERT(MUTEX_HELD(&zfsdev_state_lock));
+	g_topology_assert();
+
+	pp = LIST_FIRST(&gp->provider);
+	ASSERT(pp != NULL);
+	zv = pp->private;
+	ASSERT(zv != NULL);
+
+	zv->zv_provider = NULL;
+	g_wither_provider(pp, ENXIO);
+
+	pp = g_new_providerf(gp, "%s/%s", ZVOL_DRIVER, newname);
+	pp->sectorsize = DEV_BSIZE;
+	pp->mediasize = zv->zv_volsize;
+	pp->private = zv;
+	zv->zv_provider = pp;
+	strlcpy(zv->zv_name, newname, sizeof(zv->zv_name));
+	g_error_provider(pp, 0);
+}
+
+void
+zvol_rename_minors(const char *oldname, const char *newname)
+{
+	char name[MAXPATHLEN];
+	struct g_provider *pp;
+	struct g_geom *gp;
+	size_t oldnamelen, newnamelen;
+	zvol_state_t *zv;
+	char *namebuf;
+
+	oldnamelen = strlen(oldname);
+	newnamelen = strlen(newname);
+
+	DROP_GIANT();
+	mutex_enter(&zfsdev_state_lock);
+	g_topology_lock();
+
+	LIST_FOREACH(gp, &zfs_zvol_class.geom, geom) {
+		pp = LIST_FIRST(&gp->provider);
+		if (pp == NULL)
+			continue;
+		zv = pp->private;
+		if (zv == NULL)
+			continue;
+		if (strcmp(zv->zv_name, oldname) == 0) {
+			zvol_rename_minor(gp, newname);
+		} else if (strncmp(zv->zv_name, oldname, oldnamelen) == 0 &&
+		    (zv->zv_name[oldnamelen] == '/' ||
+		     zv->zv_name[oldnamelen] == '@')) {
+			snprintf(name, sizeof(name), "%s%c%s", newname,
+			    zv->zv_name[oldnamelen],
+			    zv->zv_name + oldnamelen + 1);
+			zvol_rename_minor(gp, name);
+		}
+	}
+
+	g_topology_unlock();
+	mutex_exit(&zfsdev_state_lock);
+	PICKUP_GIANT();
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201103052231.p25MV3fd078293>