Revert "Illumos 3749 - zfs event processing should work on R/O root filesystems"
This reverts commit b47637ecdc
which
introduced a regression in ztest.
$ ./cmd/ztest/ztest -V
5 vdevs, 7 datasets, 23 threads, 300 seconds...
*** Error in `/rpool/home/behlendo/src/git/zfs/cmd/ztest/.libs/lt-ztest':
double free or corruption (fasttop): 0x0000000000d339f0 ***
This commit is contained in:
parent
928c58dd0f
commit
b870c7e5f4
|
@ -56,7 +56,6 @@ extern "C" {
|
||||||
#define FM_EREPORT_ZFS_IO_FAILURE "io_failure"
|
#define FM_EREPORT_ZFS_IO_FAILURE "io_failure"
|
||||||
#define FM_EREPORT_ZFS_PROBE_FAILURE "probe_failure"
|
#define FM_EREPORT_ZFS_PROBE_FAILURE "probe_failure"
|
||||||
#define FM_EREPORT_ZFS_LOG_REPLAY "log_replay"
|
#define FM_EREPORT_ZFS_LOG_REPLAY "log_replay"
|
||||||
#define FM_EREPORT_ZFS_CONFIG_CACHE_WRITE "config_cache_write"
|
|
||||||
#define FM_EREPORT_ZFS_RESILVER_START "resilver.start"
|
#define FM_EREPORT_ZFS_RESILVER_START "resilver.start"
|
||||||
#define FM_EREPORT_ZFS_RESILVER_FINISH "resilver.finish"
|
#define FM_EREPORT_ZFS_RESILVER_FINISH "resilver.finish"
|
||||||
#define FM_EREPORT_ZFS_SCRUB_START "scrub.start"
|
#define FM_EREPORT_ZFS_SCRUB_START "scrub.start"
|
||||||
|
|
|
@ -252,7 +252,6 @@ struct spa {
|
||||||
uint64_t spa_deadman_synctime; /* deadman expiration timer */
|
uint64_t spa_deadman_synctime; /* deadman expiration timer */
|
||||||
uint64_t spa_errata; /* errata issues detected */
|
uint64_t spa_errata; /* errata issues detected */
|
||||||
spa_stats_t spa_stats; /* assorted spa statistics */
|
spa_stats_t spa_stats; /* assorted spa statistics */
|
||||||
hrtime_t spa_ccw_fail_time; /* Conf cache write fail time */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* spa_refcount & spa_config_lock must be the last elements
|
* spa_refcount & spa_config_lock must be the last elements
|
||||||
|
|
|
@ -82,12 +82,6 @@
|
||||||
#include "zfs_prop.h"
|
#include "zfs_prop.h"
|
||||||
#include "zfs_comutil.h"
|
#include "zfs_comutil.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* The interval, in seconds, at which failed configuration cache file writes
|
|
||||||
* should be retried.
|
|
||||||
*/
|
|
||||||
static int zfs_ccw_retry_interval = 300;
|
|
||||||
|
|
||||||
typedef enum zti_modes {
|
typedef enum zti_modes {
|
||||||
ZTI_MODE_FIXED, /* value is # of threads (min 1) */
|
ZTI_MODE_FIXED, /* value is # of threads (min 1) */
|
||||||
ZTI_MODE_BATCH, /* cpu-intensive; value is ignored */
|
ZTI_MODE_BATCH, /* cpu-intensive; value is ignored */
|
||||||
|
@ -5918,34 +5912,13 @@ spa_async_resume(spa_t *spa)
|
||||||
mutex_exit(&spa->spa_async_lock);
|
mutex_exit(&spa->spa_async_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean_t
|
|
||||||
spa_async_tasks_pending(spa_t *spa)
|
|
||||||
{
|
|
||||||
uint_t non_config_tasks;
|
|
||||||
uint_t config_task;
|
|
||||||
boolean_t config_task_suspended;
|
|
||||||
|
|
||||||
non_config_tasks = spa->spa_async_tasks & ~SPA_ASYNC_CONFIG_UPDATE;
|
|
||||||
config_task = spa->spa_async_tasks & SPA_ASYNC_CONFIG_UPDATE;
|
|
||||||
if (spa->spa_ccw_fail_time == 0) {
|
|
||||||
config_task_suspended = B_FALSE;
|
|
||||||
} else {
|
|
||||||
config_task_suspended =
|
|
||||||
(gethrtime() - spa->spa_ccw_fail_time) <
|
|
||||||
(zfs_ccw_retry_interval * NANOSEC);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (non_config_tasks || (config_task && !config_task_suspended));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
spa_async_dispatch(spa_t *spa)
|
spa_async_dispatch(spa_t *spa)
|
||||||
{
|
{
|
||||||
mutex_enter(&spa->spa_async_lock);
|
mutex_enter(&spa->spa_async_lock);
|
||||||
if (spa_async_tasks_pending(spa) &&
|
if (spa->spa_async_tasks && !spa->spa_async_suspended &&
|
||||||
!spa->spa_async_suspended &&
|
|
||||||
spa->spa_async_thread == NULL &&
|
spa->spa_async_thread == NULL &&
|
||||||
rootdir != NULL)
|
rootdir != NULL && !vn_is_readonly(rootdir))
|
||||||
spa->spa_async_thread = thread_create(NULL, 0,
|
spa->spa_async_thread = thread_create(NULL, 0,
|
||||||
spa_async_thread, spa, 0, &p0, TS_RUN, maxclsyspri);
|
spa_async_thread, spa, 0, &p0, TS_RUN, maxclsyspri);
|
||||||
mutex_exit(&spa->spa_async_lock);
|
mutex_exit(&spa->spa_async_lock);
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/spa.h>
|
#include <sys/spa.h>
|
||||||
#include <sys/fm/fs/zfs.h>
|
|
||||||
#include <sys/spa_impl.h>
|
#include <sys/spa_impl.h>
|
||||||
#include <sys/nvpair.h>
|
#include <sys/nvpair.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
|
@ -146,22 +145,22 @@ out:
|
||||||
kobj_close_file(file);
|
kobj_close_file(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl)
|
spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl)
|
||||||
{
|
{
|
||||||
size_t buflen;
|
size_t buflen;
|
||||||
char *buf;
|
char *buf;
|
||||||
vnode_t *vp;
|
vnode_t *vp;
|
||||||
int oflags = FWRITE | FTRUNC | FCREAT | FOFFMAX;
|
int oflags = FWRITE | FTRUNC | FCREAT | FOFFMAX;
|
||||||
|
int error;
|
||||||
char *temp;
|
char *temp;
|
||||||
int err;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the nvlist is empty (NULL), then remove the old cachefile.
|
* If the nvlist is empty (NULL), then remove the old cachefile.
|
||||||
*/
|
*/
|
||||||
if (nvl == NULL) {
|
if (nvl == NULL) {
|
||||||
err = vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE);
|
(void) vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE);
|
||||||
return (err);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -182,16 +181,16 @@ spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl)
|
||||||
* and overwritten in place. In the event of an error the file is
|
* and overwritten in place. In the event of an error the file is
|
||||||
* unlinked to make sure we always have a consistent view of the data.
|
* unlinked to make sure we always have a consistent view of the data.
|
||||||
*/
|
*/
|
||||||
err = vn_open(dp->scd_path, UIO_SYSSPACE, oflags, 0644, &vp, 0, 0);
|
error = vn_open(dp->scd_path, UIO_SYSSPACE, oflags, 0644, &vp, 0, 0);
|
||||||
if (err == 0) {
|
if (error == 0) {
|
||||||
err = vn_rdwr(UIO_WRITE, vp, buf, buflen, 0,
|
error = vn_rdwr(UIO_WRITE, vp, buf, buflen, 0,
|
||||||
UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred, NULL);
|
UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred, NULL);
|
||||||
if (err == 0)
|
if (error == 0)
|
||||||
err = VOP_FSYNC(vp, FSYNC, kcred, NULL);
|
error = VOP_FSYNC(vp, FSYNC, kcred, NULL);
|
||||||
|
|
||||||
(void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL);
|
(void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL);
|
||||||
|
|
||||||
if (err)
|
if (error)
|
||||||
(void) vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE);
|
(void) vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -202,16 +201,14 @@ spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl)
|
||||||
*/
|
*/
|
||||||
(void) snprintf(temp, MAXPATHLEN, "%s.tmp", dp->scd_path);
|
(void) snprintf(temp, MAXPATHLEN, "%s.tmp", dp->scd_path);
|
||||||
|
|
||||||
err = vn_open(temp, UIO_SYSSPACE, oflags, 0644, &vp, CRCREAT, 0);
|
error = vn_open(temp, UIO_SYSSPACE, oflags, 0644, &vp, CRCREAT, 0);
|
||||||
if (err == 0) {
|
if (error == 0) {
|
||||||
err = vn_rdwr(UIO_WRITE, vp, buf, buflen, 0, UIO_SYSSPACE,
|
if (vn_rdwr(UIO_WRITE, vp, buf, buflen, 0, UIO_SYSSPACE,
|
||||||
0, RLIM64_INFINITY, kcred, NULL);
|
0, RLIM64_INFINITY, kcred, NULL) == 0 &&
|
||||||
if (err == 0)
|
VOP_FSYNC(vp, FSYNC, kcred, NULL) == 0) {
|
||||||
err = VOP_FSYNC(vp, FSYNC, kcred, NULL);
|
(void) vn_rename(temp, dp->scd_path, UIO_SYSSPACE);
|
||||||
if (err == 0)
|
}
|
||||||
err = vn_rename(temp, dp->scd_path, UIO_SYSSPACE);
|
|
||||||
(void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL);
|
(void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL);
|
||||||
VN_RELE(vp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) vn_remove(temp, UIO_SYSSPACE, RMFILE);
|
(void) vn_remove(temp, UIO_SYSSPACE, RMFILE);
|
||||||
|
@ -219,7 +216,6 @@ spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl)
|
||||||
|
|
||||||
vmem_free(buf, buflen);
|
vmem_free(buf, buflen);
|
||||||
kmem_free(temp, MAXPATHLEN);
|
kmem_free(temp, MAXPATHLEN);
|
||||||
return (err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -237,8 +233,6 @@ spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent)
|
||||||
spa_config_dirent_t *dp, *tdp;
|
spa_config_dirent_t *dp, *tdp;
|
||||||
nvlist_t *nvl;
|
nvlist_t *nvl;
|
||||||
char *pool_name;
|
char *pool_name;
|
||||||
boolean_t ccw_failure;
|
|
||||||
int error = 0;
|
|
||||||
|
|
||||||
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
||||||
|
|
||||||
|
@ -250,7 +244,6 @@ spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent)
|
||||||
* cachefile is changed, the new one is pushed onto this list, allowing
|
* cachefile is changed, the new one is pushed onto this list, allowing
|
||||||
* us to update previous cachefiles that no longer contain this pool.
|
* us to update previous cachefiles that no longer contain this pool.
|
||||||
*/
|
*/
|
||||||
ccw_failure = B_FALSE;
|
|
||||||
for (dp = list_head(&target->spa_config_list); dp != NULL;
|
for (dp = list_head(&target->spa_config_list); dp != NULL;
|
||||||
dp = list_next(&target->spa_config_list, dp)) {
|
dp = list_next(&target->spa_config_list, dp)) {
|
||||||
spa_t *spa = NULL;
|
spa_t *spa = NULL;
|
||||||
|
@ -297,32 +290,10 @@ spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent)
|
||||||
mutex_exit(&spa->spa_props_lock);
|
mutex_exit(&spa->spa_props_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
error = spa_config_write(dp, nvl);
|
spa_config_write(dp, nvl);
|
||||||
if (error != 0)
|
|
||||||
ccw_failure = B_TRUE;
|
|
||||||
nvlist_free(nvl);
|
nvlist_free(nvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ccw_failure) {
|
|
||||||
/*
|
|
||||||
* Keep trying so that configuration data is
|
|
||||||
* written if/when any temporary filesystem
|
|
||||||
* resource issues are resolved.
|
|
||||||
*/
|
|
||||||
if (target->spa_ccw_fail_time == 0) {
|
|
||||||
zfs_ereport_post(FM_EREPORT_ZFS_CONFIG_CACHE_WRITE,
|
|
||||||
target, NULL, NULL, 0, 0);
|
|
||||||
}
|
|
||||||
target->spa_ccw_fail_time = gethrtime();
|
|
||||||
spa_async_request(target, SPA_ASYNC_CONFIG_UPDATE);
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Do not rate limit future attempts to update
|
|
||||||
* the config cache.
|
|
||||||
*/
|
|
||||||
target->spa_ccw_fail_time = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove any config entries older than the current one.
|
* Remove any config entries older than the current one.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue