From owner-svn-src-stable@freebsd.org Wed Jul 26 16:24:12 2017 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9B292D98BD6; Wed, 26 Jul 2017 16:24:12 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7770E694CC; Wed, 26 Jul 2017 16:24:12 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v6QGOBtQ067946; Wed, 26 Jul 2017 16:24:11 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v6QGOBu4067944; Wed, 26 Jul 2017 16:24:11 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201707261624.v6QGOBu4067944@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Wed, 26 Jul 2017 16:24:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r321537 - stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: stable-11 X-SVN-Commit-Author: mav X-SVN-Commit-Paths: stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Commit-Revision: 321537 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 26 Jul 2017 16:24:12 -0000 Author: mav Date: Wed Jul 26 16:24:11 2017 New Revision: 321537 URL: https://svnweb.freebsd.org/changeset/base/321537 Log: MFC r317511: MFV 316896 7580 ztest failure in dbuf_read_impl illumos/illumos-gate@1a01181fdc809f40c64d5c6881ae3e4521a9d9c7 https://github.com/illumos/illumos-gate/commit/1a01181fdc809f40c64d5c6881ae3e4521a9d9c7 https://www.illumos.org/issues/7580 We need to prevent any reader whenever we're about the zero out all the blkptrs. To do this we need to grab the dn_struct_rwlock as writer in dbuf_write_children_ready and free_children just prior to calling bzero. Reviewed by: Pavel Zakharov Reviewed by: Steve Gonczi Reviewed by: Matthew Ahrens Approved by: Dan McDonald Author: George Wilson Modified: stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c ============================================================================== --- stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c Wed Jul 26 16:23:30 2017 (r321536) +++ stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c Wed Jul 26 16:24:11 2017 (r321537) @@ -3317,13 +3317,13 @@ dbuf_write_children_ready(zio_t *zio, arc_buf_t *buf, dmu_buf_impl_t *db = vdb; dnode_t *dn; blkptr_t *bp; - uint64_t i; - int epbs; + unsigned int epbs, i; ASSERT3U(db->db_level, >, 0); DB_DNODE_ENTER(db); dn = DB_DNODE(db); epbs = dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT; + ASSERT3U(epbs, <, 31); /* Determine if all our children are holes */ for (i = 0, bp = db->db.db_data; i < 1 << epbs; i++, bp++) { @@ -3336,8 +3336,14 @@ dbuf_write_children_ready(zio_t *zio, arc_buf_t *buf, * we may get compressed away. */ if (i == 1 << epbs) { - /* didn't find any non-holes */ + /* + * We only found holes. Grab the rwlock to prevent + * anybody from reading the blocks we're about to + * zero out. + */ + rw_enter(&dn->dn_struct_rwlock, RW_WRITER); bzero(db->db.db_data, db->db.db_size); + rw_exit(&dn->dn_struct_rwlock); } DB_DNODE_EXIT(db); } Modified: stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c ============================================================================== --- stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c Wed Jul 26 16:23:30 2017 (r321536) +++ stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c Wed Jul 26 16:24:11 2017 (r321537) @@ -236,8 +236,8 @@ free_children(dmu_buf_impl_t *db, uint64_t blkid, uint dnode_t *dn; blkptr_t *bp; dmu_buf_impl_t *subdb; - uint64_t start, end, dbstart, dbend, i; - int epbs, shift; + uint64_t start, end, dbstart, dbend; + unsigned int epbs, shift, i; /* * There is a small possibility that this block will not be cached: @@ -254,6 +254,7 @@ free_children(dmu_buf_impl_t *db, uint64_t blkid, uint DB_DNODE_ENTER(db); dn = DB_DNODE(db); epbs = dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT; + ASSERT3U(epbs, <, 31); shift = (db->db_level - 1) * epbs; dbstart = db->db_blkid << epbs; start = blkid >> shift; @@ -273,12 +274,12 @@ free_children(dmu_buf_impl_t *db, uint64_t blkid, uint FREE_VERIFY(db, start, end, tx); free_blocks(dn, bp, end-start+1, tx); } else { - for (i = start; i <= end; i++, bp++) { + for (uint64_t id = start; id <= end; id++, bp++) { if (BP_IS_HOLE(bp)) continue; rw_enter(&dn->dn_struct_rwlock, RW_READER); VERIFY0(dbuf_hold_impl(dn, db->db_level - 1, - i, TRUE, FALSE, FTAG, &subdb)); + id, TRUE, FALSE, FTAG, &subdb)); rw_exit(&dn->dn_struct_rwlock); ASSERT3P(bp, ==, subdb->db_blkptr); @@ -293,8 +294,14 @@ free_children(dmu_buf_impl_t *db, uint64_t blkid, uint break; } if (i == 1 << epbs) { - /* didn't find any non-holes */ + /* + * We only found holes. Grab the rwlock to prevent + * anybody from reading the blocks we're about to + * zero out. + */ + rw_enter(&dn->dn_struct_rwlock, RW_WRITER); bzero(db->db.db_data, db->db.db_size); + rw_exit(&dn->dn_struct_rwlock); free_blocks(dn, db->db_blkptr, 1, tx); } else { /*