[Bug 193803] zvol rename failing due to out of order locking

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Thu Oct 2 17:53:06 UTC 2014


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=193803

--- Comment #16 from kash at tripleback.net ---
The patch does not apply cleanly to a new SVN pull of releng/10.0:

[/usr/src]-[root at fbsd-master]-[0]-[1704]
[:)] # cat sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c.rej     
@@ -1684,8 +1682,7 @@
        VERIFY0(zap_add(dp->dp_meta_objset, hds->ds_phys->ds_snapnames_zapobj,
            ds->ds_snapname, 8, 1, &ds->ds_object, tx));

-#ifdef __FreeBSD__
-#ifdef _KERNEL
+#if defined(__FreeBSD__) && defined (_KERNEL)
        oldname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
        newname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
        snprintf(oldname, MAXPATHLEN, "%s@%s", ddrsa->ddrsa_fsname,
@@ -2144,6 +2143,14 @@
                    dd->dd_phys->dd_clones, origin_head->ds_object, tx));
        }

+#if defined(__FreeBSD__) && defined(_KERNEL)
+       /* Take the spa_namespace_lock so zvol renames don't livelock */
+       mutex_enter(&spa_namespace_lock);
+
+       oldname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
+       newname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
+#endif
+
        /* move snapshots to this dir */
        for (snap = list_head(&ddpa->shared_snaps); snap;
            snap = list_next(&ddpa->shared_snaps, snap)) {
[/usr/src]-[root at fbsd-master]-[0]-[1705]
[:)] # cat sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c.rej       
@@ -2393,9 +2381,10 @@
        if (dmu_objset_type(os) == DMU_OST_ZVOL) {
                dsl_dataset_long_hold(os->os_dsl_dataset, FTAG);
                dsl_pool_rele(dmu_objset_pool(os), FTAG);
-               if ((error = zvol_create_minor(name)) == 0)
+               error = zvol_create_minor(name);
+               if (error == 0 || error == EEXIST) {
                        error = zvol_create_snapshots(os, name);
-               else {
+               } else {
                        printf("ZFS WARNING: Unable to create ZVOL %s
(error=%d).\n",
                            name, error);
                }
@@ -2479,12 +2468,16 @@
        size_t oldnamelen, newnamelen;
        zvol_state_t *zv;
        char *namebuf;
+       boolean_t locked = B_FALSE;

        oldnamelen = strlen(oldname);
        newnamelen = strlen(newname);

        DROP_GIANT();
-       mutex_enter(&spa_namespace_lock);
+       if (!MUTEX_HELD(&spa_namespace_lock)) {
+               mutex_enter(&spa_namespace_lock);
+               locked = B_TRUE;
+       }
        g_topology_lock();

        LIST_FOREACH(gp, &zfs_zvol_class.geom, geom) {
@@ -2507,6 +2500,7 @@
        }

        g_topology_unlock();
-       mutex_exit(&spa_namespace_lock);
+       if (locked)
+               mutex_exit(&spa_namespace_lock);
        PICKUP_GIANT();
 }

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-bugs mailing list