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@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.su...@delphix.com>
  Reviewed by: George Wilson <george.wil...@delphix.com>
  Approved by: Robert Mustacchi <r...@joyent.com>
  Author: Matthew Ahrens <mahr...@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;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to