summaryrefslogtreecommitdiffstats
path: root/cddl
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2017-09-19 08:53:13 +0000
committeravg <avg@FreeBSD.org>2017-09-19 08:53:13 +0000
commit70d73375fe27608fe1002a74c330dacc51667d39 (patch)
tree3256be1e1c272f2b5eb00bb6c09932c73e2ad31c /cddl
parent2c0524d4755d1c31cba8ed899c429211f7763a61 (diff)
downloadFreeBSD-src-70d73375fe27608fe1002a74c330dacc51667d39.zip
FreeBSD-src-70d73375fe27608fe1002a74c330dacc51667d39.tar.gz
MFC r322226: MFV r322223: 8378 crash due to bp in-memory modification of nopwrite block
illumos/illumos-gate@b7edcb940884114e61382937505433c4c38c0278 https://github.com/illumos/illumos-gate/commit/b7edcb940884114e61382937505433c4c38c0278 https://www.illumos.org/issues/8378 The problem is that zfs_get_data() supplies a stale zgd_bp to dmu_sync(), which we then nopwrite against. zfs_get_data() doesn't hold any DMU-related locks, so after it copies db_blkptr to zgd_bp, dbuf_write_ready() could change db_blkptr, and dbuf_write_done() could remove the dirty record. dmu_sync() then sees the stale BP and that the dbuf it not dirty, so it is eligible for nop-writing. The fix is for dmu_sync() to copy db_blkptr to zgd_bp after acquiring the db_mtx. We could still see a stale db_blkptr, but if it is stale then the dirty record will still exist and thus we won't attempt to nopwrite. Reviewed by: Prakash Surya <prakash.surya@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Approved by: Robert Mustacchi <rm@joyent.com> Author: Matthew Ahrens <mahrens@delphix.com>
Diffstat (limited to 'cddl')
-rw-r--r--cddl/contrib/opensolaris/cmd/ztest/ztest.c7
1 files changed, 1 insertions, 6 deletions
diff --git a/cddl/contrib/opensolaris/cmd/ztest/ztest.c b/cddl/contrib/opensolaris/cmd/ztest/ztest.c
index a0b6858..2205c95 100644
--- a/cddl/contrib/opensolaris/cmd/ztest/ztest.c
+++ b/cddl/contrib/opensolaris/cmd/ztest/ztest.c
@@ -1838,7 +1838,6 @@ ztest_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio)
uint64_t object = lr->lr_foid;
uint64_t offset = lr->lr_offset;
uint64_t size = lr->lr_length;
- blkptr_t *bp = &lr->lr_blkptr;
uint64_t txg = lr->lr_common.lrc_txg;
uint64_t crtxg;
dmu_object_info_t doi;
@@ -1892,11 +1891,7 @@ ztest_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio)
DMU_READ_NO_PREFETCH);
if (error == 0) {
- blkptr_t *obp = dmu_buf_get_blkptr(db);
- if (obp) {
- ASSERT(BP_IS_HOLE(bp));
- *bp = *obp;
- }
+ blkptr_t *bp = &lr->lr_blkptr;
zgd->zgd_db = db;
zgd->zgd_bp = bp;
OpenPOWER on IntegriCloud