- Notifications
You must be signed in to change notification settings - Fork1.9k
added module param to enable decompression of scrubed blocks#17630
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:master
Are you sure you want to change the base?
Conversation
Uh oh!
There was an error while loading.Please reload this page.
| /* | ||
| * If the block was read without error, is compressed, and we're doing | ||
| * a decompression scrub we will now attempt to decompress it to | ||
| * further verify its integrity. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
For encrypted datasets, unless the encryption keys are loaded I'd expect the decompression to fail. It'd be nice to optionally do this check as part of the normal pipeline.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Existing scrub code always usesZIO_FLAG_RAW flag to disable both decryption and decompression. Unless that is what you mean, Brian, I wonder if instead of the additional code here we could just set the flags properly to make ZIO pipeline to also verify encryption MACs and only then decompress.
I also wonder whether it is realistic (I really doubt it happens now) to try to recover those errors by reading from other data copies. I don't know what is the use case of this patch, that can be either memory corruption (in which case all copies will be broken) or some on-disk corruption that managed to slip through checksums (that is unlikely, but in which case there might be a hope).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Unless that is what you mean... we could just set the flags properly...
Yes, this is what I was suggesting. Although, I'm not convinced we can set the flags properly since the encryption keys could be unloaded any at time while we're scrubbing. A newZIO_FLAG_ might be needed as a hint to decrypt and decompress the block only if possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I tried to go this route before by settingZIO_FLAG_RAW_ENCRYPT instead ofZIO_FLAG_RAW and hoping to see a decompression failure during scrub, but I couldn't find any evidence of the failure. I'll look again.
The use case is we have a handful of cases of on-disk corruption where the checksum for the block is correct, but it fails to decompress. We would like to identify all such cases using a scrub. By the way, demand-reading such a block returns an EIO and doesn't add anything to the errlog. We have a patch that changes this as well.
The recovery question is an interesting one. It might be possible to recover from this in some cases, but in the case I've dug into, it is not possible since we never had a good copy of that block. The bad block was received already containing the corruption (in a compressed send stream), and the source did not have redundancy configured.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I've tried a POC of what I think you were proposing:
@@ -4742,6 +4745,9 @@ dsl_scan_scrub_cb(dsl_pool_t *dp, boolean_t needs_io = B_FALSE; int zio_flags = ZIO_FLAG_SCAN_THREAD | ZIO_FLAG_RAW | ZIO_FLAG_CANFAIL;+ if (BP_GET_LEVEL(bp) == 0 && BP_GET_COMPRESS(bp) != ZIO_COMPRESS_OFF)+ zio_flags &= ~ZIO_FLAG_RAW_COMPRESS;+ count_block(dp->dp_blkstats, bp); if (phys_birth <= scn->scn_phys.scn_min_txg || phys_birth >= scn->scn_phys.scn_max_txg) {and this causes failure in zio_decompress_data() across all files in the pool... I don't see why that would be happening.
Signed-off-by: Alek Pinchuk <alek.pinchuk@connectwise.com>
Motivation and Context
We've seen a handful of the rare cases of corruption where the checksum for the block is correct, but it fails to decompress.
Since a scrub does not decompress the blocks that it reads, currently, a scrub will not catch this type of corruption.
To address this, we've implemented a module parameter (
zfs_scrub_decompress) that, when set to a non-zero value, will cause all scrubbed blocks to be decompressed, and if this decompression fails, the failure will be reported in zpool status -v output as permanent data error(s).Description
To implement this
dsl_scan_scrub_done()callback was modified to optionally do decompression for scrubbed blocks.The existing scurb behavior is preserved by default as the tunable in set to 0 by default.
How Has This Been Tested?
Ran the zpool scrub-related tests in the zfs test suite, which passed, and some surface performance tests. The performance tests suggest about 10-15% higher peak CPU usage when using decompressive scrub.
Types of changes
Checklist:
Signed-off-by.