mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
Add BRT support to zpool prefetch command
Implement BRT (Block Reference Table) prefetch functionality similar to existing DDT prefetch. This allows preloading BRT metadata into ARC to improve performance for block cloning operations and frees of earlier cloned blocks. Make -t parameter optional. When omitted, prefetch all supported metadata types (both DDT and BRT now). Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com> Closes #17890
This commit is contained in:
committed by
Brian Behlendorf
parent
002bc3da6a
commit
41878d57ea
@@ -1510,6 +1510,31 @@ brt_load(spa_t *spa)
|
||||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
brt_prefetch_all(spa_t *spa)
|
||||
{
|
||||
/*
|
||||
* Load all BRT entries for each vdev. This is intended to perform
|
||||
* a prefetch on all such blocks. For the same reason that brt_prefetch
|
||||
* (called from brt_pending_add) isn't locked, this is also not locked.
|
||||
*/
|
||||
brt_rlock(spa);
|
||||
for (uint64_t vdevid = 0; vdevid < spa->spa_brt_nvdevs; vdevid++) {
|
||||
brt_vdev_t *brtvd = spa->spa_brt_vdevs[vdevid];
|
||||
brt_unlock(spa);
|
||||
|
||||
rw_enter(&brtvd->bv_mos_entries_lock, RW_READER);
|
||||
if (brtvd->bv_mos_entries != 0) {
|
||||
(void) zap_prefetch_object(spa->spa_meta_objset,
|
||||
brtvd->bv_mos_entries);
|
||||
}
|
||||
rw_exit(&brtvd->bv_mos_entries_lock);
|
||||
|
||||
brt_rlock(spa);
|
||||
}
|
||||
brt_unlock(spa);
|
||||
}
|
||||
|
||||
void
|
||||
brt_unload(spa_t *spa)
|
||||
{
|
||||
|
||||
+4
-1
@@ -850,12 +850,15 @@ dmu_prefetch_wait(objset_t *os, uint64_t object, uint64_t offset, uint64_t size)
|
||||
return (err);
|
||||
|
||||
/*
|
||||
* Chunk the requests (16 indirects worth) so that we can be interrupted
|
||||
* Chunk the requests (16 indirects worth) so that we can be
|
||||
* interrupted. Prefetch at least SPA_MAXBLOCKSIZE at a time
|
||||
* to better utilize pools with smaller block sizes.
|
||||
*/
|
||||
uint64_t chunksize;
|
||||
if (dn->dn_indblkshift) {
|
||||
uint64_t nbps = bp_span_in_blocks(dn->dn_indblkshift, 1);
|
||||
chunksize = (nbps * 16) << dn->dn_datablkshift;
|
||||
chunksize = MAX(chunksize, SPA_MAXBLOCKSIZE);
|
||||
} else {
|
||||
chunksize = dn->dn_datablksz;
|
||||
}
|
||||
|
||||
+17
-10
@@ -212,6 +212,8 @@
|
||||
#include <sys/vdev_impl.h>
|
||||
#include <sys/vdev_initialize.h>
|
||||
#include <sys/vdev_trim.h>
|
||||
#include <sys/brt.h>
|
||||
#include <sys/ddt.h>
|
||||
|
||||
#include "zfs_namecheck.h"
|
||||
#include "zfs_prop.h"
|
||||
@@ -4276,13 +4278,11 @@ zfs_ioc_pool_prefetch(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
|
||||
spa_t *spa;
|
||||
int32_t type;
|
||||
|
||||
/*
|
||||
* Currently, only ZPOOL_PREFETCH_DDT is supported
|
||||
*/
|
||||
if (nvlist_lookup_int32(innvl, ZPOOL_PREFETCH_TYPE, &type) != 0 ||
|
||||
type != ZPOOL_PREFETCH_DDT) {
|
||||
if (nvlist_lookup_int32(innvl, ZPOOL_PREFETCH_TYPE, &type) != 0)
|
||||
return (EINVAL);
|
||||
|
||||
if (type != ZPOOL_PREFETCH_DDT && type != ZPOOL_PREFETCH_BRT)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
error = spa_open(poolname, &spa, FTAG);
|
||||
if (error != 0)
|
||||
@@ -4290,10 +4290,17 @@ zfs_ioc_pool_prefetch(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
|
||||
|
||||
hrtime_t start_time = gethrtime();
|
||||
|
||||
ddt_prefetch_all(spa);
|
||||
|
||||
zfs_dbgmsg("pool '%s': loaded ddt into ARC in %llu ms", spa->spa_name,
|
||||
(u_longlong_t)NSEC2MSEC(gethrtime() - start_time));
|
||||
if (type == ZPOOL_PREFETCH_DDT) {
|
||||
ddt_prefetch_all(spa);
|
||||
zfs_dbgmsg("pool '%s': loaded ddt into ARC in %llu ms",
|
||||
spa->spa_name,
|
||||
(u_longlong_t)NSEC2MSEC(gethrtime() - start_time));
|
||||
} else {
|
||||
brt_prefetch_all(spa);
|
||||
zfs_dbgmsg("pool '%s': loaded brt into ARC in %llu ms",
|
||||
spa->spa_name,
|
||||
(u_longlong_t)NSEC2MSEC(gethrtime() - start_time));
|
||||
}
|
||||
|
||||
spa_close(spa, FTAG);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user