svn commit: r219317 - in
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs: . sys
Pawel Jakub Dawidek
pjd at FreeBSD.org
Sat Mar 5 22:31:03 UTC 2011
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();
+}
More information about the svn-src-all
mailing list