mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 10:37:35 +03:00
Persistent L2ARC
This commit makes the L2ARC persistent across reboots. We implement a light-weight persistent L2ARC metadata structure that allows L2ARC contents to be recovered after a reboot. This significantly eases the impact a reboot has on read performance on systems with large caches. Reviewed-by: Matthew Ahrens <mahrens@delphix.com> Reviewed-by: George Wilson <gwilson@delphix.com> Reviewed-by: Ryan Moeller <ryan@iXsystems.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Co-authored-by: Saso Kiselkov <skiselkov@gmail.com> Co-authored-by: Jorgen Lundman <lundman@lundman.net> Co-authored-by: George Amanakis <gamanakis@gmail.com> Ported-by: Yuxuan Shui <yshuiv7@gmail.com> Signed-off-by: George Amanakis <gamanakis@gmail.com> Closes #925 Closes #1823 Closes #2672 Closes #3744 Closes #9582
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
#include <libzfs.h>
|
||||
#include <libzfs_impl.h>
|
||||
#include <libzutil.h>
|
||||
#include <sys/arc_impl.h>
|
||||
|
||||
/*
|
||||
* Returns true if the named pool matches the given GUID.
|
||||
@@ -146,8 +147,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_blk(fd, &statbuf) == -1)
|
||||
return (0);
|
||||
@@ -157,8 +160,13 @@ zpool_clear_label(int fd)
|
||||
if ((label = calloc(1, sizeof (vdev_label_t))) == 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),
|
||||
@@ -185,6 +193,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);
|
||||
|
||||
/*
|
||||
@@ -202,7 +219,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);
|
||||
|
||||
Reference in New Issue
Block a user