summaryrefslogtreecommitdiff
path: root/usr/src/lib/libzfs
diff options
context:
space:
mode:
authorGeorge Amanakis <gamanakis@gmail.com>2020-07-30 18:40:44 -0500
committerJason King <jason.king@joyent.com>2020-10-16 11:10:02 -0500
commitf0a052391861a2b96cf28973c3b7f2854591aa79 (patch)
tree653d2330669b465bac1ab1c55b7e24c018cddc8a /usr/src/lib/libzfs
parent6218f28969018904255fddf306e6489c7ae28bba (diff)
downloadillumos-joyent-f0a052391861a2b96cf28973c3b7f2854591aa79.tar.gz
3525 Persistent L2ARC
Portions contributed by: Saso Kiselkov <skiselkov@gmail.com> Portions contributed by: Jorgen Lundman <lundman@lundman.net> Portions contributed by: Brian Behlendorf <behlendorf1@llnl.gov> Portions contributed by: Alexander Motin <mav@FreeBSD.org> Portions contributed by: Jason King <jason.king@joyent.com> Reviewed by: C Fraire <cfraire@me.com> Reviewed by: Toomas Soome <tsoome@me.com> Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/lib/libzfs')
-rw-r--r--usr/src/lib/libzfs/common/libzfs_import.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs_import.c b/usr/src/lib/libzfs/common/libzfs_import.c
index dc15aca0c0..257cd5e59e 100644
--- a/usr/src/lib/libzfs/common/libzfs_import.c
+++ b/usr/src/lib/libzfs/common/libzfs_import.c
@@ -60,6 +60,7 @@
#include <sys/vdev_impl.h>
#include <libzutil.h>
+#include <sys/arc_impl.h>
#include "libzfs.h"
#include "libzfs_impl.h"
@@ -168,8 +169,10 @@ zpool_clear_label(int fd)
struct stat64 statbuf;
int l;
vdev_label_t *label;
+ l2arc_dev_hdr_phys_t *l2dhdr;
uint64_t size;
- int labels_cleared = 0;
+ int labels_cleared = 0, header_cleared = 0;
+ boolean_t clear_l2arc_header = B_FALSE;
if (fstat64(fd, &statbuf) == -1)
return (0);
@@ -179,8 +182,13 @@ zpool_clear_label(int fd)
if ((label = calloc(sizeof (vdev_label_t), 1)) == NULL)
return (-1);
+ if ((l2dhdr = calloc(1, sizeof (l2arc_dev_hdr_phys_t))) == NULL) {
+ free(label);
+ return (-1);
+ }
+
for (l = 0; l < VDEV_LABELS; l++) {
- uint64_t state, guid;
+ uint64_t state, guid, l2cache;
nvlist_t *config;
if (pread64(fd, label, sizeof (vdev_label_t),
@@ -207,6 +215,15 @@ zpool_clear_label(int fd)
continue;
}
+ /* If the device is a cache device clear the header. */
+ if (!clear_l2arc_header) {
+ if (nvlist_lookup_uint64(config,
+ ZPOOL_CONFIG_POOL_STATE, &l2cache) == 0 &&
+ l2cache == POOL_STATE_L2CACHE) {
+ clear_l2arc_header = B_TRUE;
+ }
+ }
+
nvlist_free(config);
/*
@@ -224,7 +241,17 @@ zpool_clear_label(int fd)
}
}
+ /* Clear the L2ARC header. */
+ if (clear_l2arc_header) {
+ memset(l2dhdr, 0, sizeof (l2arc_dev_hdr_phys_t));
+ if (pwrite64(fd, l2dhdr, sizeof (l2arc_dev_hdr_phys_t),
+ VDEV_LABEL_START_SIZE) == sizeof (l2arc_dev_hdr_phys_t)) {
+ header_cleared++;
+ }
+ }
+
free(label);
+ free(l2dhdr);
if (labels_cleared == 0)
return (-1);