From owner-svn-src-stable-10@FreeBSD.ORG Mon Oct 20 22:22:40 2014 Return-Path: Delivered-To: svn-src-stable-10@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 86C4C1EE; Mon, 20 Oct 2014 22:22:40 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::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 6899037A; Mon, 20 Oct 2014 22:22:40 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s9KMMePf040428; Mon, 20 Oct 2014 22:22:40 GMT (envelope-from delphij@FreeBSD.org) Received: (from delphij@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s9KMMe4E040424; Mon, 20 Oct 2014 22:22:40 GMT (envelope-from delphij@FreeBSD.org) Message-Id: <201410202222.s9KMMe4E040424@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: delphij set sender to delphij@FreeBSD.org using -f From: Xin LI Date: Mon, 20 Oct 2014 22:22:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r273350 - stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Oct 2014 22:22:40 -0000 Author: delphij Date: Mon Oct 20 22:22:39 2014 New Revision: 273350 URL: https://svnweb.freebsd.org/changeset/base/273350 Log: MFC r272601: MFV r272591: Use loaned ARC buffer for zfs receive to avoid copy. Illumos issue: 5162 zfs recv should use loaned arc buffer to avoid copy Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c Mon Oct 20 22:18:21 2014 (r273349) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c Mon Oct 20 22:22:39 2014 (r273350) @@ -1333,7 +1333,14 @@ dmu_assign_arcbuf(dmu_buf_t *handle, uin rw_exit(&dn->dn_struct_rwlock); DB_DNODE_EXIT(dbuf); - if (offset == db->db.db_offset && blksz == db->db.db_size) { + /* + * We can only assign if the offset is aligned, the arc buf is the + * same size as the dbuf, and the dbuf is not metadata. It + * can't be metadata because the loaned arc buf comes from the + * user-data kmem arena. + */ + if (offset == db->db.db_offset && blksz == db->db.db_size && + DBUF_GET_BUFC_TYPE(db) == ARC_BUFC_DATA) { dbuf_assign_arcbuf(db, buf, tx); dbuf_rele(db, FTAG); } else { Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c Mon Oct 20 22:18:21 2014 (r273349) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c Mon Oct 20 22:22:39 2014 (r273350) @@ -1273,18 +1273,20 @@ restore_bytes(struct restorearg *ra, voi } static void * -restore_read(struct restorearg *ra, int len) +restore_read(struct restorearg *ra, int len, char *buf) { - void *rv; int done = 0; + if (buf == NULL) + buf = ra->buf; + /* some things will require 8-byte alignment, so everything must */ ASSERT0(len % 8); while (done < len) { ssize_t resid; - ra->err = restore_bytes(ra, (caddr_t)ra->buf + done, + ra->err = restore_bytes(ra, buf + done, len - done, ra->voff, &resid); if (resid == len - done) @@ -1296,12 +1298,11 @@ restore_read(struct restorearg *ra, int } ASSERT3U(done, ==, len); - rv = ra->buf; if (ra->byteswap) - fletcher_4_incremental_byteswap(rv, len, &ra->cksum); + fletcher_4_incremental_byteswap(buf, len, &ra->cksum); else - fletcher_4_incremental_native(rv, len, &ra->cksum); - return (rv); + fletcher_4_incremental_native(buf, len, &ra->cksum); + return (buf); } static void @@ -1416,7 +1417,7 @@ restore_object(struct restorearg *ra, ob return (SET_ERROR(EINVAL)); if (drro->drr_bonuslen) { - data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8)); + data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8), NULL); if (ra->err != 0) return (ra->err); } @@ -1513,19 +1514,30 @@ restore_write(struct restorearg *ra, obj !DMU_OT_IS_VALID(drrw->drr_type)) return (SET_ERROR(EINVAL)); - data = restore_read(ra, drrw->drr_length); - if (data == NULL) - return (ra->err); - if (dmu_object_info(os, drrw->drr_object, NULL) != 0) return (SET_ERROR(EINVAL)); + dmu_buf_t *bonus; + if (dmu_bonus_hold(os, drrw->drr_object, FTAG, &bonus) != 0) + return (SET_ERROR(EINVAL)); + + arc_buf_t *abuf = dmu_request_arcbuf(bonus, drrw->drr_length); + + data = restore_read(ra, drrw->drr_length, abuf->b_data); + if (data == NULL) { + dmu_return_arcbuf(abuf); + dmu_buf_rele(bonus, FTAG); + return (ra->err); + } + tx = dmu_tx_create(os); dmu_tx_hold_write(tx, drrw->drr_object, drrw->drr_offset, drrw->drr_length); err = dmu_tx_assign(tx, TXG_WAIT); if (err != 0) { + dmu_return_arcbuf(abuf); + dmu_buf_rele(bonus, FTAG); dmu_tx_abort(tx); return (err); } @@ -1534,9 +1546,9 @@ restore_write(struct restorearg *ra, obj DMU_OT_BYTESWAP(drrw->drr_type); dmu_ot_byteswap[byteswap].ob_func(data, drrw->drr_length); } - dmu_write(os, drrw->drr_object, - drrw->drr_offset, drrw->drr_length, data, tx); + dmu_assign_arcbuf(bonus, drrw->drr_offset, abuf, tx); dmu_tx_commit(tx); + dmu_buf_rele(bonus, FTAG); return (0); } @@ -1618,7 +1630,7 @@ restore_write_embedded(struct restorearg if (drrwnp->drr_compression >= ZIO_COMPRESS_FUNCTIONS) return (EINVAL); - data = restore_read(ra, P2ROUNDUP(drrwnp->drr_psize, 8)); + data = restore_read(ra, P2ROUNDUP(drrwnp->drr_psize, 8), NULL); if (data == NULL) return (ra->err); @@ -1653,7 +1665,7 @@ restore_spill(struct restorearg *ra, obj drrs->drr_length > SPA_MAXBLOCKSIZE) return (SET_ERROR(EINVAL)); - data = restore_read(ra, drrs->drr_length); + data = restore_read(ra, drrs->drr_length, NULL); if (data == NULL) return (ra->err); @@ -1795,7 +1807,7 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, */ pcksum = ra.cksum; while (ra.err == 0 && - NULL != (drr = restore_read(&ra, sizeof (*drr)))) { + NULL != (drr = restore_read(&ra, sizeof (*drr), NULL))) { if (issig(JUSTLOOKING) && issig(FORREAL)) { ra.err = SET_ERROR(EINTR); goto out;