mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-25 18:59:33 +03:00
Enable raw writes to perform dedup with verification
Reviewed by: Dan Kimmel <dan.kimmel@delphix.com> Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed by: David Quigley <david.quigley@intel.com> Signed-off-by: Tom Caputi <tcaputi@datto.com> Issue #5078
This commit is contained in:
parent
2aa34383b9
commit
c17bcf83da
@ -2363,19 +2363,30 @@ zio_ddt_collision(zio_t *zio, ddt_t *ddt, ddt_entry_t *dde)
|
||||
{
|
||||
spa_t *spa = zio->io_spa;
|
||||
int p;
|
||||
boolean_t do_raw = !!(zio->io_flags & ZIO_FLAG_RAW);
|
||||
|
||||
ASSERT0(zio->io_flags & ZIO_FLAG_RAW);
|
||||
ASSERT(!(zio->io_bp_override && do_raw));
|
||||
|
||||
/*
|
||||
* Note: we compare the original data, not the transformed data,
|
||||
* because when zio->io_bp is an override bp, we will not have
|
||||
* pushed the I/O transforms. That's an important optimization
|
||||
* because otherwise we'd compress/encrypt all dmu_sync() data twice.
|
||||
* However, we should never get a raw, override zio so in these
|
||||
* cases we can compare the io_data directly. This is useful because
|
||||
* it allows us to do dedup verification even if we don't have access
|
||||
* to the original data (for instance, if the encryption keys aren't
|
||||
* loaded).
|
||||
*/
|
||||
|
||||
for (p = DDT_PHYS_SINGLE; p <= DDT_PHYS_TRIPLE; p++) {
|
||||
zio_t *lio = dde->dde_lead_zio[p];
|
||||
|
||||
if (lio != NULL) {
|
||||
if (lio != NULL && do_raw) {
|
||||
return (lio->io_size != zio->io_size ||
|
||||
bcmp(zio->io_data, lio->io_data,
|
||||
zio->io_size) != 0);
|
||||
} else if (lio != NULL) {
|
||||
return (lio->io_orig_size != zio->io_orig_size ||
|
||||
bcmp(zio->io_orig_data, lio->io_orig_data,
|
||||
zio->io_orig_size) != 0);
|
||||
@ -2385,7 +2396,36 @@ zio_ddt_collision(zio_t *zio, ddt_t *ddt, ddt_entry_t *dde)
|
||||
for (p = DDT_PHYS_SINGLE; p <= DDT_PHYS_TRIPLE; p++) {
|
||||
ddt_phys_t *ddp = &dde->dde_phys[p];
|
||||
|
||||
if (ddp->ddp_phys_birth != 0) {
|
||||
if (ddp->ddp_phys_birth != 0 && do_raw) {
|
||||
blkptr_t blk = *zio->io_bp;
|
||||
uint64_t psize;
|
||||
void *tmpbuf;
|
||||
int error;
|
||||
|
||||
ddt_bp_fill(ddp, &blk, ddp->ddp_phys_birth);
|
||||
psize = BP_GET_PSIZE(&blk);
|
||||
|
||||
if (psize != zio->io_size)
|
||||
return (B_TRUE);
|
||||
|
||||
ddt_exit(ddt);
|
||||
|
||||
tmpbuf = zio_buf_alloc(psize);
|
||||
|
||||
error = zio_wait(zio_read(NULL, spa, &blk, tmpbuf,
|
||||
psize, NULL, NULL, ZIO_PRIORITY_SYNC_READ,
|
||||
ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE |
|
||||
ZIO_FLAG_RAW, &zio->io_bookmark));
|
||||
|
||||
if (error == 0) {
|
||||
if (bcmp(tmpbuf, zio->io_data, psize) != 0)
|
||||
error = SET_ERROR(ENOENT);
|
||||
}
|
||||
|
||||
zio_buf_free(tmpbuf, psize);
|
||||
ddt_enter(ddt);
|
||||
return (error != 0);
|
||||
} else if (ddp->ddp_phys_birth != 0) {
|
||||
arc_buf_t *abuf = NULL;
|
||||
arc_flags_t aflags = ARC_FLAG_WAIT;
|
||||
blkptr_t blk = *zio->io_bp;
|
||||
@ -2393,6 +2433,9 @@ zio_ddt_collision(zio_t *zio, ddt_t *ddt, ddt_entry_t *dde)
|
||||
|
||||
ddt_bp_fill(ddp, &blk, ddp->ddp_phys_birth);
|
||||
|
||||
if (BP_GET_LSIZE(&blk) != zio->io_orig_size)
|
||||
return (B_TRUE);
|
||||
|
||||
ddt_exit(ddt);
|
||||
|
||||
error = arc_read(NULL, spa, &blk,
|
||||
@ -2401,10 +2444,9 @@ zio_ddt_collision(zio_t *zio, ddt_t *ddt, ddt_entry_t *dde)
|
||||
&aflags, &zio->io_bookmark);
|
||||
|
||||
if (error == 0) {
|
||||
if (arc_buf_size(abuf) != zio->io_orig_size ||
|
||||
bcmp(abuf->b_data, zio->io_orig_data,
|
||||
if (bcmp(abuf->b_data, zio->io_orig_data,
|
||||
zio->io_orig_size) != 0)
|
||||
error = SET_ERROR(EEXIST);
|
||||
error = SET_ERROR(ENOENT);
|
||||
arc_buf_destroy(abuf, &abuf);
|
||||
}
|
||||
|
||||
@ -2511,7 +2553,7 @@ zio_ddt_write(zio_t *zio)
|
||||
ASSERT(BP_GET_DEDUP(bp));
|
||||
ASSERT(BP_GET_CHECKSUM(bp) == zp->zp_checksum);
|
||||
ASSERT(BP_IS_HOLE(bp) || zio->io_bp_override);
|
||||
ASSERT0(zio->io_flags & ZIO_FLAG_RAW);
|
||||
ASSERT(!(zio->io_bp_override && (zio->io_flags & ZIO_FLAG_RAW)));
|
||||
|
||||
ddt_enter(ddt);
|
||||
dde = ddt_lookup(ddt, bp, B_TRUE);
|
||||
|
Loading…
Reference in New Issue
Block a user