FreeBSD Bugzilla – Attachment 147924 Details for
Bug 193803
fix zvol rename failing due to out of order locking
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Possible fix for zvol hang issues (against 10.0-RELEASE)
zfs-zvol-fixes.patch (text/plain), 7.27 KB, created by
Steven Hartland
on 2014-10-03 01:06:01 UTC
(
hide
)
Description:
Possible fix for zvol hang issues (against 10.0-RELEASE)
Filename:
MIME Type:
Creator:
Steven Hartland
Created:
2014-10-03 01:06:01 UTC
Size:
7.27 KB
patch
obsolete
>Various fixes for zvol devices not being correctly maintained when operations >which effect them occur. >--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c.orig 2014-10-03 00:20:27.261734053 +0000 >+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c 2014-10-03 00:45:09.037824518 +0000 >@@ -1655,11 +1655,9 @@ static int > dsl_dataset_rename_snapshot_sync_impl(dsl_pool_t *dp, > dsl_dataset_t *hds, void *arg) > { >-#ifdef __FreeBSD__ >-#ifdef _KERNEL >+#if defined(__FreeBSD__) && defined(_KERNEL) > char *oldname, *newname; > #endif >-#endif > dsl_dataset_rename_snapshot_arg_t *ddrsa = arg; > dsl_dataset_t *ds; > uint64_t val; >@@ -1686,8 +1684,7 @@ dsl_dataset_rename_snapshot_sync_impl(ds > 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, >@@ -1699,7 +1696,6 @@ dsl_dataset_rename_snapshot_sync_impl(ds > kmem_free(newname, MAXPATHLEN); > kmem_free(oldname, MAXPATHLEN); > #endif >-#endif > dsl_dataset_rele(ds, FTAG); > > return (0); >@@ -2076,6 +2072,9 @@ dsl_dataset_promote_sync(void *arg, dmu_ > dsl_dir_t *odd = NULL; > uint64_t oldnext_obj; > int64_t delta; >+#if defined(__FreeBSD__) && defined(_KERNEL) >+ char *oldname, *newname; >+#endif > > VERIFY0(promote_hold(ddpa, dp, FTAG)); > hds = ddpa->ddpa_clone; >@@ -2141,6 +2140,14 @@ dsl_dataset_promote_sync(void *arg, dmu_ > 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)) { >@@ -2173,6 +2180,12 @@ dsl_dataset_promote_sync(void *arg, dmu_ > VERIFY0(dsl_dir_hold_obj(dp, dd->dd_object, > NULL, ds, &ds->ds_dir)); > >+#if defined(__FreeBSD__) && defined(_KERNEL) >+ dsl_dataset_name(ds, newname); >+ zfsvfs_update_fromname(oldname, newname); >+ zvol_rename_minors(oldname, newname); >+#endif >+ > /* move any clone references */ > if (ds->ds_phys->ds_next_clones_obj && > spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) { >@@ -2210,6 +2223,12 @@ dsl_dataset_promote_sync(void *arg, dmu_ > ASSERT(!dsl_prop_hascb(ds)); > } > >+#if defined(__FreeBSD__) && defined(_KERNEL) >+ mutex_exit(&spa_namespace_lock); >+ >+ kmem_free(newname, MAXPATHLEN); >+ kmem_free(oldname, MAXPATHLEN); >+#endif > /* > * Change space accounting. > * Note, pa->*usedsnap and dd_used_breakdown[SNAP] will either >--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h.orig 2014-10-03 00:29:00.568543367 +0000 >+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h 2014-10-03 00:45:09.038824805 +0000 >@@ -41,8 +41,7 @@ extern int zvol_check_volblocksize(uint6 > extern int zvol_get_stats(objset_t *os, nvlist_t *nv); > extern void zvol_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx); > extern int zvol_create_minor(const char *); >-extern int zvol_remove_minor(const char *); >-extern void zvol_remove_minors(const char *); >+extern int zvol_remove_minors(const char *); > extern int zvol_set_volsize(const char *, major_t, uint64_t); > > #ifdef sun >--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c.orig 2014-10-03 00:28:18.224546707 +0000 >+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c 2014-10-03 00:46:12.636821793 +0000 >@@ -3298,6 +3298,10 @@ zfs_ioc_clone(const char *fsname, nvlist > if (error != 0) > (void) dsl_destroy_head(fsname); > } >+#ifdef __FreeBSD__ >+ if (error == 0) >+ zvol_create_minors(fsname); >+#endif > return (error); > } > >@@ -3517,7 +3521,7 @@ zfs_ioc_destroy_snaps(const char *poolna > error = zfs_unmount_snap(name); > if (error != 0) > return (error); >- (void) zvol_remove_minor(name); >+ (void) zvol_remove_minors(name); > } > > return (dsl_destroy_snapshots_nvl(snaps, defer, outnvl)); >@@ -3547,7 +3551,7 @@ zfs_ioc_destroy(zfs_cmd_t *zc) > else > err = dsl_destroy_head(zc->zc_name); > if (zc->zc_objset_type == DMU_OST_ZVOL && err == 0) >- (void) zvol_remove_minor(zc->zc_name); >+ (void) zvol_remove_minors(zc->zc_name); > return (err); > } > >@@ -3643,7 +3647,7 @@ zfs_ioc_rename(zfs_cmd_t *zc) > } else { > #ifdef illumos > if (zc->zc_objset_type == DMU_OST_ZVOL) >- (void) zvol_remove_minor(zc->zc_name); >+ (void) zvol_remove_minors(zc->zc_name); > #endif > return (dsl_dir_rename(zc->zc_name, zc->zc_value)); > } >--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c.orig 2014-10-03 00:29:10.090016574 +0000 >+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c 2014-10-03 00:45:09.042824710 +0000 >@@ -630,24 +630,6 @@ zvol_remove_zv(zvol_state_t *zv) > } > > int >-zvol_remove_minor(const char *name) >-{ >- zvol_state_t *zv; >- int rc; >- >- mutex_enter(&spa_namespace_lock); >- if ((zv = zvol_minor_lookup(name)) == NULL) { >- mutex_exit(&spa_namespace_lock); >- return (SET_ERROR(ENXIO)); >- } >- g_topology_lock(); >- rc = zvol_remove_zv(zv); >- g_topology_unlock(); >- mutex_exit(&spa_namespace_lock); >- return (rc); >-} >- >-int > zvol_first_open(zvol_state_t *zv) > { > objset_t *os; >@@ -775,15 +757,17 @@ zvol_update_volsize(objset_t *os, uint64 > return (error); > } > >-void >+int > zvol_remove_minors(const char *name) > { > struct g_geom *gp, *gptmp; > struct g_provider *pp; > zvol_state_t *zv; > size_t namelen; >+ int rc; > > namelen = strlen(name); >+ rc = ENXIO; > > DROP_GIANT(); > mutex_enter(&spa_namespace_lock); >@@ -798,14 +782,18 @@ zvol_remove_minors(const char *name) > continue; > if (strcmp(zv->zv_name, name) == 0 || > (strncmp(zv->zv_name, name, namelen) == 0 && >- zv->zv_name[namelen] == '/')) { >- (void) zvol_remove_zv(zv); >+ strlen(zv->zv_name) > namelen && (zv->zv_name[namelen] == '/' || >+ zv->zv_name[namelen] == '@'))) { >+ if ((rc = zvol_remove_zv(zv)) != 0) >+ break; > } > } > > g_topology_unlock(); > mutex_exit(&spa_namespace_lock); > PICKUP_GIANT(); >+ >+ return (rc); > } > > int >@@ -2393,9 +2381,10 @@ zvol_create_minors(const char *name) > 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 @@ zvol_rename_minors(const char *oldname, > 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 @@ zvol_rename_minors(const char *oldname, > } > > g_topology_unlock(); >- mutex_exit(&spa_namespace_lock); >+ if (locked) >+ mutex_exit(&spa_namespace_lock); > PICKUP_GIANT(); > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 193803
:
147905
|
147915
| 147924 |
161674