mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
Illumos 3749 - zfs event processing should work on R/O root filesystems
3749 zfs event processing should work on R/O root filesystems Reviewed by: Matthew Ahrens <mahrens@delphix.com> Reviewed by: Eric Schrock <eric.schrock@delphix.com> Approved by: Christopher Siden <christopher.siden@delphix.com> References: https://www.illumos.org/issues/3749 https://github.com/illumos/illumos-gate/commit/3cb69f7 Porting notes: - [include/sys/spa_impl.h] -ffe9d38Add generic errata infrastructure -1421c89Add visibility in to arc_read - [include/sys/fm/fs/zfs.h] -2668527Add linux events -6283f55Support custom build directories and move includes - [module/zfs/spa_config.c] - Updated spa_config_sync() to match illumos with the exception of a Linux specific block. Ported-by: kernelOfTruth kerneloftruth@gmail.com Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
This commit is contained in:
committed by
Brian Behlendorf
parent
e9e3d31d2c
commit
b47637ecdc
+47
-18
@@ -26,6 +26,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/spa.h>
|
||||
#include <sys/fm/fs/zfs.h>
|
||||
#include <sys/spa_impl.h>
|
||||
#include <sys/nvpair.h>
|
||||
#include <sys/uio.h>
|
||||
@@ -145,22 +146,22 @@ out:
|
||||
kobj_close_file(file);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl)
|
||||
{
|
||||
size_t buflen;
|
||||
char *buf;
|
||||
vnode_t *vp;
|
||||
int oflags = FWRITE | FTRUNC | FCREAT | FOFFMAX;
|
||||
int error;
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -181,16 +182,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
|
||||
* unlinked to make sure we always have a consistent view of the data.
|
||||
*/
|
||||
error = vn_open(dp->scd_path, UIO_SYSSPACE, oflags, 0644, &vp, 0, 0);
|
||||
if (error == 0) {
|
||||
error = vn_rdwr(UIO_WRITE, vp, buf, buflen, 0,
|
||||
err = vn_open(dp->scd_path, UIO_SYSSPACE, oflags, 0644, &vp, 0, 0);
|
||||
if (err == 0) {
|
||||
err = vn_rdwr(UIO_WRITE, vp, buf, buflen, 0,
|
||||
UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred, NULL);
|
||||
if (error == 0)
|
||||
error = VOP_FSYNC(vp, FSYNC, kcred, NULL);
|
||||
if (err == 0)
|
||||
err = VOP_FSYNC(vp, FSYNC, kcred, NULL);
|
||||
|
||||
(void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL);
|
||||
|
||||
if (error)
|
||||
if (err)
|
||||
(void) vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE);
|
||||
}
|
||||
#else
|
||||
@@ -201,14 +202,16 @@ spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl)
|
||||
*/
|
||||
(void) snprintf(temp, MAXPATHLEN, "%s.tmp", dp->scd_path);
|
||||
|
||||
error = vn_open(temp, UIO_SYSSPACE, oflags, 0644, &vp, CRCREAT, 0);
|
||||
if (error == 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);
|
||||
VN_RELE(vp);
|
||||
}
|
||||
|
||||
(void) vn_remove(temp, UIO_SYSSPACE, RMFILE);
|
||||
@@ -216,6 +219,7 @@ spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl)
|
||||
|
||||
vmem_free(buf, buflen);
|
||||
kmem_free(temp, MAXPATHLEN);
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -233,6 +237,8 @@ spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent)
|
||||
spa_config_dirent_t *dp, *tdp;
|
||||
nvlist_t *nvl;
|
||||
char *pool_name;
|
||||
boolean_t ccw_failure;
|
||||
int error = 0;
|
||||
|
||||
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
||||
|
||||
@@ -244,6 +250,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;
|
||||
@@ -290,10 +297,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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user