svn commit: r322223 - vendor-sys/illumos/dist/uts/common/fs/zfs vendor/illumos/dist/cmd/ztest
Andriy Gapon
avg at FreeBSD.org
Tue Aug 8 10:44:50 UTC 2017
Author: avg
Date: Tue Aug 8 10:44:48 2017
New Revision: 322223
URL: https://svnweb.freebsd.org/changeset/base/322223
Log:
8378 crash due to bp in-memory modification of nopwrite block
illumos/illumos-gate at 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 at delphix.com>
Reviewed by: George Wilson <george.wilson at delphix.com>
Approved by: Robert Mustacchi <rm at joyent.com>
Author: Matthew Ahrens <mahrens at delphix.com>
Modified:
vendor/illumos/dist/cmd/ztest/ztest.c
Changes in other areas also in this revision:
Modified:
vendor-sys/illumos/dist/uts/common/fs/zfs/dmu.c
vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_vnops.c
vendor-sys/illumos/dist/uts/common/fs/zfs/zvol.c
Modified: vendor/illumos/dist/cmd/ztest/ztest.c
==============================================================================
--- vendor/illumos/dist/cmd/ztest/ztest.c Tue Aug 8 10:43:41 2017 (r322222)
+++ vendor/illumos/dist/cmd/ztest/ztest.c Tue Aug 8 10:44:48 2017 (r322223)
@@ -1842,7 +1842,6 @@ ztest_get_data(void *arg, lr_write_t *lr, char *buf, z
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;
@@ -1896,11 +1895,7 @@ ztest_get_data(void *arg, lr_write_t *lr, char *buf, z
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;
More information about the svn-src-all
mailing list