removed, care should be taken when attempting to access this file.
When the last pool using a
.Sy cachefile
-is exported or destroyed, the file is removed.
+is exported or destroyed, the file will be empty.
.It Sy comment Ns = Ns Ar text
A text string consisting of printable ASCII characters that will be stored
such that it is available even if the pool becomes faulted.
kobj_close_file(file);
}
+static int
+spa_config_remove(spa_config_dirent_t *dp)
+{
+#if defined(__linux__) && defined(_KERNEL)
+ int error, flags = FWRITE | FTRUNC;
+ uio_seg_t seg = UIO_SYSSPACE;
+ vnode_t *vp;
+
+ error = vn_open(dp->scd_path, seg, flags, 0644, &vp, 0, 0);
+ if (error == 0) {
+ (void) VOP_FSYNC(vp, FSYNC, kcred, NULL);
+ (void) VOP_CLOSE(vp, 0, 1, 0, kcred, NULL);
+ }
+
+ return (error);
+#else
+ return (vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE));
+#endif
+}
+
static int
spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl)
{
* If the nvlist is empty (NULL), then remove the old cachefile.
*/
if (nvl == NULL) {
- err = vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE);
- /*
- * Don't report an error when the cache file is already removed
- */
+ err = spa_config_remove(dp);
if (err == ENOENT)
err = 0;
+
return (err);
}
#if defined(__linux__) && defined(_KERNEL)
/*
* Write the configuration to disk. Due to the complexity involved
- * in performing a rename from within the kernel the file is truncated
- * 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.
+ * in performing a rename and remove from within the kernel the file
+ * is instead truncated and overwritten in place. This way we always
+ * have a consistent view of the data or a zero length file.
*/
err = vn_open(dp->scd_path, UIO_SYSSPACE, oflags, 0644, &vp, 0, 0);
if (err == 0) {
err = VOP_FSYNC(vp, FSYNC, kcred, NULL);
(void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL);
-
if (err)
- (void) vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE);
+ (void) spa_config_remove(dp);
}
#else
/*
log_must pool_in_cache $TESTPOOL1 $CPATH2
log_must zpool set cachefile=$CPATH2 $TESTPOOL2
log_must pool_in_cache $TESTPOOL2 $CPATH2
-if [[ -f $CPATH1 ]]; then
+if [[ -s $CPATH1 ]]; then
log_fail "Verify set when cachefile is set on pool."
fi
log_must zpool export $TESTPOOL1
log_must zpool export $TESTPOOL2
-if [[ -f $CPATH2 ]]; then
+if [[ -s $CPATH2 ]]; then
log_fail "Verify export when cachefile is set on pool."
fi
log_must zpool destroy $TESTPOOL1
log_must zpool destroy $TESTPOOL2
-if [[ -f $CPATH2 ]]; then
+if [[ -s $CPATH2 ]]; then
log_fail "Verify destroy when cachefile is set on pool."
fi