diff options
author | delphij <delphij@FreeBSD.org> | 2013-06-11 19:35:44 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2013-06-11 19:35:44 +0000 |
commit | 46c768b6a7fd9d51fc2b9385b56f30e852d00811 (patch) | |
tree | df3953c70bbdd68f67534b16011650c51771c94e /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c | |
parent | 421d82372619ed594e217affe20d5bfa3854e919 (diff) | |
download | FreeBSD-src-46c768b6a7fd9d51fc2b9385b56f30e852d00811.zip FreeBSD-src-46c768b6a7fd9d51fc2b9385b56f30e852d00811.tar.gz |
MFV r251626:
ZFS event processing should work on R/O root filesystems
Illumos ZFS issues:
3749 zfs event processing should work on R/O root filesystems
MFC after: 2 weeks
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c index 28fb6f2..0f3bd67 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c @@ -27,6 +27,7 @@ #include <sys/zfs_context.h> #include <sys/spa.h> +#include <sys/fm/fs/zfs.h> #include <sys/spa_impl.h> #include <sys/nvpair.h> #include <sys/uio.h> @@ -139,7 +140,7 @@ out: kobj_close_file(file); } -static void +static int spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl) { size_t buflen; @@ -147,13 +148,14 @@ spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl) vnode_t *vp; int oflags = FWRITE | FTRUNC | FCREAT | FOFFMAX; char *temp; + int err; /* * If the nvlist is empty (NULL), then remove the old cachefile. */ if (nvl == NULL) { - (void) vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE); - return; + err = vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE); + return (err); } /* @@ -174,12 +176,14 @@ spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl) */ (void) snprintf(temp, MAXPATHLEN, "%s.tmp", dp->scd_path); - if (vn_open(temp, UIO_SYSSPACE, oflags, 0644, &vp, CRCREAT, 0) == 0) { - if (vn_rdwr(UIO_WRITE, vp, buf, buflen, 0, UIO_SYSSPACE, - 0, RLIM64_INFINITY, kcred, NULL) == 0 && - VOP_FSYNC(vp, FSYNC, kcred, NULL) == 0) { - (void) vn_rename(temp, dp->scd_path, UIO_SYSSPACE); - } + err = vn_open(temp, UIO_SYSSPACE, oflags, 0644, &vp, CRCREAT, 0); + if (err == 0) { + err = vn_rdwr(UIO_WRITE, vp, buf, buflen, 0, UIO_SYSSPACE, + 0, RLIM64_INFINITY, kcred, NULL); + if (err == 0) + err = VOP_FSYNC(vp, FSYNC, kcred, NULL); + if (err == 0) + err = vn_rename(temp, dp->scd_path, UIO_SYSSPACE); (void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL); } @@ -187,6 +191,7 @@ spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl) kmem_free(buf, buflen); kmem_free(temp, MAXPATHLEN); + return (err); } /* @@ -198,6 +203,8 @@ spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent) { spa_config_dirent_t *dp, *tdp; nvlist_t *nvl; + boolean_t ccw_failure; + int error; ASSERT(MUTEX_HELD(&spa_namespace_lock)); @@ -209,6 +216,7 @@ spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent) * cachefile is changed, the new one is pushed onto this list, allowing * 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; dp = list_next(&target->spa_config_list, dp)) { spa_t *spa = NULL; @@ -249,10 +257,32 @@ spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent) mutex_exit(&spa->spa_props_lock); } - spa_config_write(dp, nvl); + error = spa_config_write(dp, nvl); + if (error != 0) + ccw_failure = B_TRUE; 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. */ |