ddt.c revision 7448a0795bbf890c55a5c66129a0d606f02a784e
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <sys/zfs_context.h>
#include <sys/spa_impl.h>
#include <sys/dsl_pool.h>
#include <sys/zio_checksum.h>
#include <sys/zio_compress.h>
#include <sys/dsl_scan.h>
/*
*/
int zfs_dedup_prefetch = 1;
};
static const char *ddt_class_name[DDT_CLASSES] = {
"ditto",
"duplicate",
"unique",
};
static void
{
char name[DDT_NAMELEN];
}
static void
{
char name[DDT_NAMELEN];
*objectp = 0;
}
static int
{
char name[DDT_NAMELEN];
int error;
if (error)
return (error);
/*
* Seed the cached statistics.
*/
return (error);
}
static void
{
char name[DDT_NAMELEN];
/*
* Cache DDT statistics; this is the only time they'll change.
*/
}
static int
{
return (ENOENT);
}
static void
{
return;
}
int
{
}
static int
{
}
int
{
}
{
}
int
{
return (ENOENT);
doi));
}
{
}
void
char *name)
{
}
void
{
for (int d = 0; d < SPA_DVAS_PER_BP; d++)
}
void
{
BP_SET_LEVEL(bp, 0);
BP_SET_DEDUP(bp, 0);
}
void
{
}
void
{
for (int d = 0; d < SPA_DVAS_PER_BP; d++)
}
void
{
}
void
{
ddp->ddp_refcnt++;
}
void
{
ddp->ddp_refcnt--;
}
void
{
}
{
for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
return (ddp);
}
return (NULL);
}
{
for (int p = DDT_PHYS_SINGLE; p <= DDT_PHYS_TRIPLE; p++)
return (refcnt);
}
static void
{
for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
if (ddp->ddp_phys_birth == 0)
continue;
for (int d = 0; d < SPA_DVAS_PER_BP; d++)
}
}
void
{
while (d < d_end)
}
static void
{
int bucket;
}
void
{
for (int h = 0; h < 64; h++)
}
void
{
for (int h = 0; h < 64; h++)
}
{
while (s < s_end)
if (*s++ != 0)
return (B_FALSE);
return (B_TRUE);
}
void
{
/* Sum the statistics we cached in ddt_object_sync(). */
for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
class++) {
ddt_object_t *ddo =
}
}
}
/* ... and compute the averages. */
}
}
void
{
for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
class++) {
}
}
}
}
void
{
}
{
ddt_stat_t dds_total = { 0 };
}
{
ddt_stat_t dds_total = { 0 };
return (100);
}
int
{
uint64_t total_refcnt = 0;
int total_copies = 0;
int desired_copies = 0;
for (int p = DDT_PHYS_SINGLE; p <= DDT_PHYS_TRIPLE; p++) {
if (ddp == ddp_willref)
refcnt++; /* caller's ref */
if (refcnt != 0) {
total_refcnt += refcnt;
total_copies += p;
}
}
ditto = UINT32_MAX;
if (total_refcnt >= 1)
if (total_refcnt >= ditto)
}
int
{
for (int d = 0; d < SPA_DVAS_PER_BP; d++, dva++)
if (DVA_IS_VALID(dva))
copies++;
return (copies);
}
{
int cpfunc = ZIO_COMPRESS_ZLE;
}
return (c_len + 1);
}
void
{
else
}
ddt_t *
{
}
ddt_t *
{
}
void
{
}
void
{
}
static ddt_entry_t *
{
return (dde);
}
static void
{
for (int p = 0; p < DDT_PHYS_TYPES; p++)
}
void
{
}
{
int error;
if (!add)
return (NULL);
}
while (dde->dde_loading)
if (dde->dde_loaded)
return (dde);
break;
}
break;
}
if (error == 0)
return (dde);
}
void
{
return;
/*
* We only remove the DDT once all tables are empty and only
* prefetch dedup blocks when there are entries in the DDT.
* Thus no locking is required as the DDT can't disappear on us.
*/
}
}
}
int
{
for (int i = 0; i < DDT_KEY_WORDS; i++) {
return (-1);
return (1);
}
return (0);
}
static ddt_t *
{
ddt->ddt_checksum = c;
return (ddt);
}
static void
{
}
void
{
for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++)
}
int
{
int error;
if (error)
for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
class++) {
return (error);
}
}
/*
* Seed the cached histograms.
*/
sizeof (ddt->ddt_histogram));
}
return (0);
}
void
{
for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
}
}
}
{
if (!BP_GET_DEDUP(bp))
return (B_FALSE);
if (max_class == DDT_CLASS_UNIQUE)
return (B_TRUE);
return (B_TRUE);
return (B_FALSE);
}
{
/*
* We can only do repair if there are multiple copies
* of the block. For anything in the UNIQUE class,
* there's definitely only one copy, so don't even try.
*/
if (class != DDT_CLASS_UNIQUE &&
return (dde);
}
}
return (dde);
}
void
{
else
}
static void
{
}
static void
{
if (ddp->ddp_phys_birth == 0 ||
continue;
}
}
static void
{
return;
}
}
static void
{
uint64_t total_refcnt = 0;
for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
if (ddp->ddp_phys_birth == 0) {
continue;
}
if (p == DDT_PHYS_DITTO) {
continue;
}
if (ddp->ddp_refcnt == 0)
}
else if (total_refcnt > 1)
else
}
if (total_refcnt != 0) {
/*
* If the class changes, the order that we scan this bp
* changes. If it decreases, we could miss it, so
* scan it right now. (This covers both class changing
* while we are doing ddt_walk(), and when we are
* traversing.)
*/
}
}
}
static void
{
return;
if (spa->spa_ddt_stat_object == 0) {
}
}
}
}
}
}
sizeof (ddt->ddt_histogram));
}
void
{
for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
continue;
}
}
int
{
do {
do {
do {
}
if (error == 0)
return (0);
return (error);
ddb->ddb_cursor = 0;
ddb->ddb_checksum = 0;
return (ENOENT);
}