From mm@mail.vx.sk  Thu Dec 10 21:40:34 2009
Return-Path: <mm@mail.vx.sk>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id CBF05106566B
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 10 Dec 2009 21:40:34 +0000 (UTC)
	(envelope-from mm@mail.vx.sk)
Received: from mail.vx.sk (core.vx.sk [188.40.32.143])
	by mx1.freebsd.org (Postfix) with ESMTP id 8E2338FC1B
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 10 Dec 2009 21:40:34 +0000 (UTC)
Received: from localhost (localhost [127.0.0.1])
	by mail.vx.sk (Postfix) with ESMTP id 248AA28505
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 10 Dec 2009 22:40:33 +0100 (CET)
Received: from mail.vx.sk ([127.0.0.1])
	by localhost (mail.vx.sk [127.0.0.1]) (amavisd-new, port 10024)
	with LMTP id R0VkmCyZC4Ek for <FreeBSD-gnats-submit@freebsd.org>;
	Thu, 10 Dec 2009 22:40:30 +0100 (CET)
Received: by mail.vx.sk (Postfix, from userid 1001)
	id EC1F3284F8; Thu, 10 Dec 2009 22:40:30 +0100 (CET)
Message-Id: <20091210214030.EC1F3284F8@mail.vx.sk>
Date: Thu, 10 Dec 2009 22:40:30 +0100 (CET)
From: Martin Matuska <mm@FreeBSD.org>
Reply-To: Martin Matuska <mm@FreeBSD.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [zfs] zfs recv can fail with E2BIG
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         141355
>Category:       kern
>Synopsis:       [zfs] [patch] zfs recv can fail with E2BIG
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    delphij
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Dec 10 21:50:03 UTC 2009
>Closed-Date:    Sun Jan 03 03:05:58 UTC 2010
>Last-Modified:  Sun Jan  3 03:10:01 UTC 2010
>Originator:     Martin Matuska
>Release:        FreeBSD 8.0-STABLE amd64
>Organization:
>Environment:
System: FreeBSD 8.0-STABLE
>Description:
There is a bug in ZFS send/receive that was already fixed in OpenSolaris snv_111

References:
Opensolaris Bug ID: 6801979
http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6801979

>How-To-Repeat:
This may happen during ZFS send/receive (managed to reproduce it):
internal error: Argument list too long
Abort (core dumped)
warning: cannot send 'pool/home@s2': Broken pipe	
>Fix:
This bug was fixed in snv_111, right after the dirtying snapshot problem:
http://dlc.sun.com/osol/on/downloads/b111/on-changelog-b111.html

Issues Resolved:
BUG/RFE:6801979 zfs recv can fail with E2BIG
Files Changed: (revision 8986:45c289aff7c9)
update:usr/src/uts/common/fs/zfs/dmu_object.c
update:usr/src/uts/common/fs/zfs/dmu_send.c
update:usr/src/uts/common/fs/zfs/dnode.c
update:usr/src/uts/common/fs/zfs/sys/dmu.h

Should be easy to implement.
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-fs 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Thu Dec 10 22:51:00 UTC 2009 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=141355 

From: Martin Matuska <mm@FreeBSD.org>
To: bug-followup@FreeBSD.org, mm@FreeBSD.org
Cc:  
Subject: Re: kern/141355: [zfs] zfs recv can fail with E2BIG
Date: Fri, 11 Dec 2009 10:08:43 +0100

 This is a multi-part message in MIME format.
 --------------070208060700060803030000
 Content-Type: text/plain; charset=ISO-8859-2
 Content-Transfer-Encoding: 7bit
 
 I have created a patch from OpenSolaris mercurial for head.
 
 Diffs used:
 
 hg clone ssh://anon@hg.opensolaris.org/hg/onnv/onnv-gate
 hg diff -r 7837 -r 7994 onnv-gate/usr/src/uts/common/fs/zfs/dmu_send.c
 hg diff -c 8986 onnv-gate
 
 Patch is easily backportable to RELENG_8. I am testing it in RELENG_8.
 
 --------------070208060700060803030000
 Content-Type: text/plain;
  name="sys.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="sys.patch"
 
 Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h
 ===================================================================
 --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h	(revision 200402)
 +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h	(working copy)
 @@ -19,7 +19,7 @@
   * CDDL HEADER END
   */
  /*
 - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
   * Use is subject to license terms.
   */
  
 @@ -237,7 +237,7 @@
  int dmu_object_claim(objset_t *os, uint64_t object, dmu_object_type_t ot,
      int blocksize, dmu_object_type_t bonus_type, int bonus_len, dmu_tx_t *tx);
  int dmu_object_reclaim(objset_t *os, uint64_t object, dmu_object_type_t ot,
 -    int blocksize, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx);
 +    int blocksize, dmu_object_type_t bonustype, int bonuslen);
  
  /*
   * Free an object from this objset.
 Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c
 ===================================================================
 --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c	(revision 200402)
 +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c	(working copy)
 @@ -19,12 +19,10 @@
   * CDDL HEADER END
   */
  /*
 - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
   * Use is subject to license terms.
   */
  
 -#pragma ident	"%Z%%M%	%I%	%E% SMI"
 -
  #include <sys/dmu.h>
  #include <sys/dmu_objset.h>
  #include <sys/dmu_tx.h>
 @@ -108,19 +106,51 @@
  
  int
  dmu_object_reclaim(objset_t *os, uint64_t object, dmu_object_type_t ot,
 -    int blocksize, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
 +    int blocksize, dmu_object_type_t bonustype, int bonuslen)
  {
  	dnode_t *dn;
 +	dmu_tx_t *tx;
 +	int nblkptr;
  	int err;
  
 -	if (object == DMU_META_DNODE_OBJECT && !dmu_tx_private_ok(tx))
 +	if (object == DMU_META_DNODE_OBJECT)
  		return (EBADF);
  
  	err = dnode_hold_impl(os->os, object, DNODE_MUST_BE_ALLOCATED,
  	    FTAG, &dn);
  	if (err)
  		return (err);
 +
 +	if (dn->dn_type == ot && dn->dn_datablksz == blocksize &&
 +	    dn->dn_bonustype == bonustype && dn->dn_bonuslen == bonuslen) {
 +		/* nothing is changing, this is a noop */
 +		dnode_rele(dn, FTAG);
 +		return (0);
 +	}
 +
 +	tx = dmu_tx_create(os);
 +	dmu_tx_hold_bonus(tx, object);
 +	err = dmu_tx_assign(tx, TXG_WAIT);
 +	if (err) {
 +		dmu_tx_abort(tx);
 +		dnode_rele(dn, FTAG);
 +		return (err);
 +	}
 +
 +	nblkptr = 1 + ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
 +
 +	/*
 +	 * If we are losing blkptrs or changing the block size this must
 +	 * be a new file instance.   We must clear out the previous file
 +	 * contents before we can change this type of metadata in the dnode.
 +	 */
 +	if (dn->dn_nblkptr > nblkptr || dn->dn_datablksz != blocksize)
 +		dmu_free_long_range(os, object, 0, DMU_OBJECT_END);
 +
  	dnode_reallocate(dn, ot, blocksize, bonustype, bonuslen, tx);
 +
 +	dmu_tx_commit(tx);
 +
  	dnode_rele(dn, FTAG);
  
  	return (0);
 Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
 ===================================================================
 --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c	(revision 200402)
 +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c	(working copy)
 @@ -415,8 +415,7 @@
  dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
      dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
  {
 -	int i, nblkptr;
 -	dmu_buf_impl_t *db = NULL;
 +	int nblkptr;
  
  	ASSERT3U(blocksize, >=, SPA_MINBLOCKSIZE);
  	ASSERT3U(blocksize, <=, SPA_MAXBLOCKSIZE);
 @@ -428,42 +427,25 @@
  	ASSERT3U(bonustype, <, DMU_OT_NUMTYPES);
  	ASSERT3U(bonuslen, <=, DN_MAX_BONUSLEN);
  
 -	for (i = 0; i < TXG_SIZE; i++)
 -		ASSERT(!list_link_active(&dn->dn_dirty_link[i]));
 -
  	/* clean up any unreferenced dbufs */
  	dnode_evict_dbufs(dn);
 -	ASSERT3P(list_head(&dn->dn_dbufs), ==, NULL);
  
 -	/*
 -	 * XXX I should really have a generation number to tell if we
 -	 * need to do this...
 -	 */
 -	if (blocksize != dn->dn_datablksz ||
 -	    dn->dn_bonustype != bonustype || dn->dn_bonuslen != bonuslen) {
 -		/* free all old data */
 -		dnode_free_range(dn, 0, -1ULL, tx);
 -	}
 -
 -	nblkptr = 1 + ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
 -
 -	/* change blocksize */
  	rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
 -	if (blocksize != dn->dn_datablksz &&
 -	    (!BP_IS_HOLE(&dn->dn_phys->dn_blkptr[0]) ||
 -	    list_head(&dn->dn_dbufs) != NULL)) {
 -		db = dbuf_hold(dn, 0, FTAG);
 -		dbuf_new_size(db, blocksize, tx);
 -	}
 -	dnode_setdblksz(dn, blocksize);
  	dnode_setdirty(dn, tx);
 -	dn->dn_next_bonuslen[tx->tx_txg&TXG_MASK] = bonuslen;
 -	dn->dn_next_blksz[tx->tx_txg&TXG_MASK] = blocksize;
 +	if (dn->dn_datablksz != blocksize) {
 +		/* change blocksize */
 +		ASSERT(dn->dn_maxblkid == 0 &&
 +		    (BP_IS_HOLE(&dn->dn_phys->dn_blkptr[0]) ||
 +		    dnode_block_freed(dn, 0)));
 +		dnode_setdblksz(dn, blocksize);
 +		dn->dn_next_blksz[tx->tx_txg&TXG_MASK] = blocksize;
 +	}
 +	if (dn->dn_bonuslen != bonuslen)
 +		dn->dn_next_bonuslen[tx->tx_txg&TXG_MASK] = bonuslen;
 +	nblkptr = 1 + ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
  	if (dn->dn_nblkptr != nblkptr)
  		dn->dn_next_nblkptr[tx->tx_txg&TXG_MASK] = nblkptr;
  	rw_exit(&dn->dn_struct_rwlock);
 -	if (db)
 -		dbuf_rele(db, FTAG);
  
  	/* change type */
  	dn->dn_type = ot;
 @@ -1187,11 +1169,6 @@
  	if (dn->dn_free_txg)
  		return (TRUE);
  
 -	/*
 -	 * If dn_datablkshift is not set, then there's only a single
 -	 * block, in which case there will never be a free range so it
 -	 * won't matter.
 -	 */
  	range_tofind.fr_blkid = blkid;
  	mutex_enter(&dn->dn_mtx);
  	for (i = 0; i < TXG_SIZE; i++) {
 Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
 ===================================================================
 --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c	(revision 200402)
 +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c	(working copy)
 @@ -828,12 +828,8 @@
  {
  	int err;
  	dmu_tx_t *tx;
 +	void *data = NULL;
  
 -	err = dmu_object_info(os, drro->drr_object, NULL);
 -
 -	if (err != 0 && err != ENOENT)
 -		return (EINVAL);
 -
  	if (drro->drr_type == DMU_OT_NONE ||
  	    drro->drr_type >= DMU_OT_NUMTYPES ||
  	    drro->drr_bonustype >= DMU_OT_NUMTYPES ||
 @@ -846,12 +842,21 @@
  		return (EINVAL);
  	}
  
 -	tx = dmu_tx_create(os);
 +	err = dmu_object_info(os, drro->drr_object, NULL);
  
 +	if (err != 0 && err != ENOENT)
 +		return (EINVAL);
 +
 +	if (drro->drr_bonuslen) {
 +		data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8));
 +		if (ra->err)
 +			return (ra->err);
 +	}
 +
  	if (err == ENOENT) {
  		/* currently free, want to be allocated */
 +		tx = dmu_tx_create(os);
  		dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
 -		dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, 1);
  		err = dmu_tx_assign(tx, TXG_WAIT);
  		if (err) {
  			dmu_tx_abort(tx);
 @@ -860,45 +865,34 @@
  		err = dmu_object_claim(os, drro->drr_object,
  		    drro->drr_type, drro->drr_blksz,
  		    drro->drr_bonustype, drro->drr_bonuslen, tx);
 +		dmu_tx_commit(tx);
  	} else {
  		/* currently allocated, want to be allocated */
 -		dmu_tx_hold_bonus(tx, drro->drr_object);
 -		/*
 -		 * We may change blocksize and delete old content,
 -		 * so need to hold_write and hold_free.
 -		 */
 -		dmu_tx_hold_write(tx, drro->drr_object, 0, 1);
 -		dmu_tx_hold_free(tx, drro->drr_object, 0, DMU_OBJECT_END);
 -		err = dmu_tx_assign(tx, TXG_WAIT);
 -		if (err) {
 -			dmu_tx_abort(tx);
 -			return (err);
 -		}
 -
  		err = dmu_object_reclaim(os, drro->drr_object,
  		    drro->drr_type, drro->drr_blksz,
 -		    drro->drr_bonustype, drro->drr_bonuslen, tx);
 +		    drro->drr_bonustype, drro->drr_bonuslen);
  	}
 -	if (err) {
 -		dmu_tx_commit(tx);
 +	if (err)
  		return (EINVAL);
 +
 +	tx = dmu_tx_create(os);
 +	dmu_tx_hold_bonus(tx, drro->drr_object);
 +	err = dmu_tx_assign(tx, TXG_WAIT);
 +	if (err) {
 +		dmu_tx_abort(tx);
 +		return (err);
  	}
  
  	dmu_object_set_checksum(os, drro->drr_object, drro->drr_checksum, tx);
  	dmu_object_set_compress(os, drro->drr_object, drro->drr_compress, tx);
  
 -	if (drro->drr_bonuslen) {
 +	if (data != NULL) {
  		dmu_buf_t *db;
 -		void *data;
 +
  		VERIFY(0 == dmu_bonus_hold(os, drro->drr_object, FTAG, &db));
  		dmu_buf_will_dirty(db, tx);
  
  		ASSERT3U(db->db_size, >=, drro->drr_bonuslen);
 -		data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8));
 -		if (data == NULL) {
 -			dmu_tx_commit(tx);
 -			return (ra->err);
 -		}
  		bcopy(data, db->db_data, drro->drr_bonuslen);
  		if (ra->byteswap) {
  			dmu_ot[drro->drr_bonustype].ot_byteswap(db->db_data,
 
 --------------070208060700060803030000--
State-Changed-From-To: open->feedback 
State-Changed-By: pjd 
State-Changed-When: ndz 13 gru 2009 16:29:51 UTC 
State-Changed-Why:  
Is thispatch like that one: 

http://people.freebsd.org/~pjd/patches/zfs_recv_E2BIG.patch 

There was a report that it was causing a panic. 


Responsible-Changed-From-To: freebsd-fs->pjd 
Responsible-Changed-By: pjd 
Responsible-Changed-When: ndz 13 gru 2009 16:29:51 UTC 
Responsible-Changed-Why:  
I'll take this one. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=141355 

From: Martin Matuska <mm@FreeBSD.org>
To: bug-followup@FreeBSD.org, mm@FreeBSD.org
Cc:  
Subject: Re: kern/141355: [zfs] [patch] zfs recv can fail with E2BIG
Date: Sun, 13 Dec 2009 17:42:06 +0100

 This is a multi-part message in MIME format.
 --------------050406010502000704050908
 Content-Type: text/plain; charset=ISO-8859-2
 Content-Transfer-Encoding: 7bit
 
 Your patch does not include the changes in dmu_send.c between revisions
 7837 and 7994, that seems to be in direct relation with this bugfix:
 
 hg clone ssh://anon@hg.opensolaris.org/hg/onnv/onnv-gate
 hg diff -r 7837 -r 7994 onnv-gate/usr/src/uts/common/fs/zfs/dmu_send.c
 
 
 I am now running for some days with applied patch of dmu_send.c
 7837-7994 and total changeset of 8989 and have no panics - on the
 contrary, everything works well.
 
 The opensolaris diff output of dmu_send.c between revisions 7837 and
 7994 is attached.
 
 --------------050406010502000704050908
 Content-Type: text/plain;
  name="dmu_send.c.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="dmu_send.c.diff"
 
 diff -r 001de5627df3 -r 7a573dc88b73 usr/src/uts/common/fs/zfs/dmu_send.c
 --- a/usr/src/uts/common/fs/zfs/dmu_send.c	Tue Oct 14 15:57:18 2008 -0700
 +++ b/usr/src/uts/common/fs/zfs/dmu_send.c	Mon Nov 03 10:55:42 2008 -0700
 @@ -773,6 +773,7 @@
  {
  	int err;
  	dmu_tx_t *tx;
 +	void *data = NULL;
  
  	err = dmu_object_info(os, drro->drr_object, NULL);
  
 @@ -791,6 +792,12 @@
  		return (EINVAL);
  	}
  
 +	if (drro->drr_bonuslen) {
 +		data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8));
 +		if (ra->err)
 +			return (ra->err);
 +	}
 +
  	tx = dmu_tx_create(os);
  
  	if (err == ENOENT) {
 @@ -831,18 +838,13 @@
  	dmu_object_set_checksum(os, drro->drr_object, drro->drr_checksum, tx);
  	dmu_object_set_compress(os, drro->drr_object, drro->drr_compress, tx);
  
 -	if (drro->drr_bonuslen) {
 +	if (data != NULL) {
  		dmu_buf_t *db;
 -		void *data;
 +
  		VERIFY(0 == dmu_bonus_hold(os, drro->drr_object, FTAG, &db));
  		dmu_buf_will_dirty(db, tx);
  
  		ASSERT3U(db->db_size, >=, drro->drr_bonuslen);
 -		data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8));
 -		if (data == NULL) {
 -			dmu_tx_commit(tx);
 -			return (ra->err);
 -		}
  		bcopy(data, db->db_data, drro->drr_bonuslen);
  		if (ra->byteswap) {
  			dmu_ot[drro->drr_bonustype].ot_byteswap(db->db_data,
 
 --------------050406010502000704050908--

From: Borja Marcos <borjam@sarenet.es>
To: bug-followup@FreeBSD.org,
 mm@FreeBSD.org
Cc:  
Subject: Re: kern/141355: [zfs] [patch] zfs recv can fail with E2BIG
Date: Wed, 16 Dec 2009 10:54:09 +0100

 I reported a panic with Pawel's patch for this issue, and I'm afraid I =
 cannot reproduce it now.=20
 
 As I had been doing lots of tests in order to reproduce a deadlock =
 situation, maybe the virtual machine's ZFS pool had some damage, I =
 cannot find out I'm afraid.
 
 I will try this alternative patch and see how it goes.
 
 Sorry for the maybe silly panic report.
 
 
 
 
 Borja.
 
State-Changed-From-To: feedback->patched 
State-Changed-By: delphij 
State-Changed-When: Sat Dec 19 11:54:04 UTC 2009 
State-Changed-Why:  
Patch was applied as revision 200726 (requested by mm@). 

MFC reminder. 


Responsible-Changed-From-To: pjd->delphij 
Responsible-Changed-By: delphij 
Responsible-Changed-When: Sat Dec 19 11:54:04 UTC 2009 
Responsible-Changed-Why:  
All bugs are mine (you touch it and you buy it :) 

http://www.freebsd.org/cgi/query-pr.cgi?pr=141355 
State-Changed-From-To: patched->closed 
State-Changed-By: delphij 
State-Changed-When: Sun Jan 3 03:05:36 UTC 2010 
State-Changed-Why:  
Patch applied against 8-STABLE, thanks for submitting! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=141355 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/141355: commit references a PR
Date: Sun,  3 Jan 2010 03:05:40 +0000 (UTC)

 Author: delphij
 Date: Sun Jan  3 03:05:30 2010
 New Revision: 201411
 URL: http://svn.freebsd.org/changeset/base/201411
 
 Log:
   MFC r200726:
   
   Apply fix for Solaris bug 6801979: zfs recv can fail with E2BIG
   (onnv revision 8986)
   
   PR:		kern/141355
   Requested by:	mm
   Submitted by:	pjd
   Obtained from:	OpenSolaris
 
 Modified:
   stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c
   stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
   stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
   stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h
 Directory Properties:
   stable/8/sys/   (props changed)
   stable/8/sys/amd64/include/xen/   (props changed)
   stable/8/sys/cddl/contrib/opensolaris/   (props changed)
   stable/8/sys/contrib/dev/acpica/   (props changed)
   stable/8/sys/contrib/pf/   (props changed)
   stable/8/sys/dev/xen/xenpci/   (props changed)
 
 Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c
 ==============================================================================
 --- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c	Sun Jan  3 02:58:43 2010	(r201410)
 +++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c	Sun Jan  3 03:05:30 2010	(r201411)
 @@ -19,12 +19,10 @@
   * CDDL HEADER END
   */
  /*
 - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
   * Use is subject to license terms.
   */
  
 -#pragma ident	"%Z%%M%	%I%	%E% SMI"
 -
  #include <sys/dmu.h>
  #include <sys/dmu_objset.h>
  #include <sys/dmu_tx.h>
 @@ -108,19 +106,51 @@ dmu_object_claim(objset_t *os, uint64_t 
  
  int
  dmu_object_reclaim(objset_t *os, uint64_t object, dmu_object_type_t ot,
 -    int blocksize, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
 +    int blocksize, dmu_object_type_t bonustype, int bonuslen)
  {
  	dnode_t *dn;
 +	dmu_tx_t *tx;
 +	int nblkptr;
  	int err;
  
 -	if (object == DMU_META_DNODE_OBJECT && !dmu_tx_private_ok(tx))
 +	if (object == DMU_META_DNODE_OBJECT)
  		return (EBADF);
  
  	err = dnode_hold_impl(os->os, object, DNODE_MUST_BE_ALLOCATED,
  	    FTAG, &dn);
  	if (err)
  		return (err);
 +
 +	if (dn->dn_type == ot && dn->dn_datablksz == blocksize &&
 +	    dn->dn_bonustype == bonustype && dn->dn_bonuslen == bonuslen) {
 +		/* nothing is changing, this is a noop */
 +		dnode_rele(dn, FTAG);
 +		return (0);
 +	}
 +
 +	tx = dmu_tx_create(os);
 +	dmu_tx_hold_bonus(tx, object);
 +	err = dmu_tx_assign(tx, TXG_WAIT);
 +	if (err) {
 +		dmu_tx_abort(tx);
 +		dnode_rele(dn, FTAG);
 +		return (err);
 +	}
 +
 +	nblkptr = 1 + ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
 +
 +	/*
 +	 * If we are losing blkptrs or changing the block size this must
 +	 * be a new file instance.   We must clear out the previous file
 +	 * contents before we can change this type of metadata in the dnode.
 +	 */
 +	if (dn->dn_nblkptr > nblkptr || dn->dn_datablksz != blocksize)
 +		dmu_free_long_range(os, object, 0, DMU_OBJECT_END);
 +
  	dnode_reallocate(dn, ot, blocksize, bonustype, bonuslen, tx);
 +
 +	dmu_tx_commit(tx);
 +
  	dnode_rele(dn, FTAG);
  
  	return (0);
 
 Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
 ==============================================================================
 --- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c	Sun Jan  3 02:58:43 2010	(r201410)
 +++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c	Sun Jan  3 03:05:30 2010	(r201411)
 @@ -829,11 +829,6 @@ restore_object(struct restorearg *ra, ob
  	int err;
  	dmu_tx_t *tx;
  
 -	err = dmu_object_info(os, drro->drr_object, NULL);
 -
 -	if (err != 0 && err != ENOENT)
 -		return (EINVAL);
 -
  	if (drro->drr_type == DMU_OT_NONE ||
  	    drro->drr_type >= DMU_OT_NUMTYPES ||
  	    drro->drr_bonustype >= DMU_OT_NUMTYPES ||
 @@ -846,12 +841,15 @@ restore_object(struct restorearg *ra, ob
  		return (EINVAL);
  	}
  
 -	tx = dmu_tx_create(os);
 +	err = dmu_object_info(os, drro->drr_object, NULL);
 +
 +	if (err != 0 && err != ENOENT)
 +		return (EINVAL);
  
  	if (err == ENOENT) {
  		/* currently free, want to be allocated */
 +		tx = dmu_tx_create(os);
  		dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
 -		dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, 1);
  		err = dmu_tx_assign(tx, TXG_WAIT);
  		if (err) {
  			dmu_tx_abort(tx);
 @@ -860,28 +858,23 @@ restore_object(struct restorearg *ra, ob
  		err = dmu_object_claim(os, drro->drr_object,
  		    drro->drr_type, drro->drr_blksz,
  		    drro->drr_bonustype, drro->drr_bonuslen, tx);
 +		dmu_tx_commit(tx);
  	} else {
  		/* currently allocated, want to be allocated */
 -		dmu_tx_hold_bonus(tx, drro->drr_object);
 -		/*
 -		 * We may change blocksize and delete old content,
 -		 * so need to hold_write and hold_free.
 -		 */
 -		dmu_tx_hold_write(tx, drro->drr_object, 0, 1);
 -		dmu_tx_hold_free(tx, drro->drr_object, 0, DMU_OBJECT_END);
 -		err = dmu_tx_assign(tx, TXG_WAIT);
 -		if (err) {
 -			dmu_tx_abort(tx);
 -			return (err);
 -		}
  
  		err = dmu_object_reclaim(os, drro->drr_object,
  		    drro->drr_type, drro->drr_blksz,
 -		    drro->drr_bonustype, drro->drr_bonuslen, tx);
 +		    drro->drr_bonustype, drro->drr_bonuslen);
  	}
 -	if (err) {
 -		dmu_tx_commit(tx);
 +	if (err)
  		return (EINVAL);
 +
 +	tx = dmu_tx_create(os);
 +	dmu_tx_hold_bonus(tx, drro->drr_object);
 +	err = dmu_tx_assign(tx, TXG_WAIT);
 +	if (err) {
 +		dmu_tx_abort(tx);
 +		return (err);
  	}
  
  	dmu_object_set_checksum(os, drro->drr_object, drro->drr_checksum, tx);
 
 Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
 ==============================================================================
 --- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c	Sun Jan  3 02:58:43 2010	(r201410)
 +++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c	Sun Jan  3 03:05:30 2010	(r201411)
 @@ -415,8 +415,7 @@ void
  dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
      dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
  {
 -	int i, nblkptr;
 -	dmu_buf_impl_t *db = NULL;
 +	int nblkptr;
  
  	ASSERT3U(blocksize, >=, SPA_MINBLOCKSIZE);
  	ASSERT3U(blocksize, <=, SPA_MAXBLOCKSIZE);
 @@ -428,42 +427,25 @@ dnode_reallocate(dnode_t *dn, dmu_object
  	ASSERT3U(bonustype, <, DMU_OT_NUMTYPES);
  	ASSERT3U(bonuslen, <=, DN_MAX_BONUSLEN);
  
 -	for (i = 0; i < TXG_SIZE; i++)
 -		ASSERT(!list_link_active(&dn->dn_dirty_link[i]));
 -
  	/* clean up any unreferenced dbufs */
  	dnode_evict_dbufs(dn);
 -	ASSERT3P(list_head(&dn->dn_dbufs), ==, NULL);
 -
 -	/*
 -	 * XXX I should really have a generation number to tell if we
 -	 * need to do this...
 -	 */
 -	if (blocksize != dn->dn_datablksz ||
 -	    dn->dn_bonustype != bonustype || dn->dn_bonuslen != bonuslen) {
 -		/* free all old data */
 -		dnode_free_range(dn, 0, -1ULL, tx);
 -	}
 -
 -	nblkptr = 1 + ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
  
 -	/* change blocksize */
  	rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
 -	if (blocksize != dn->dn_datablksz &&
 -	    (!BP_IS_HOLE(&dn->dn_phys->dn_blkptr[0]) ||
 -	    list_head(&dn->dn_dbufs) != NULL)) {
 -		db = dbuf_hold(dn, 0, FTAG);
 -		dbuf_new_size(db, blocksize, tx);
 -	}
 -	dnode_setdblksz(dn, blocksize);
  	dnode_setdirty(dn, tx);
 -	dn->dn_next_bonuslen[tx->tx_txg&TXG_MASK] = bonuslen;
 -	dn->dn_next_blksz[tx->tx_txg&TXG_MASK] = blocksize;
 +	if (dn->dn_datablksz != blocksize) {
 +		/* change blocksize */
 +		ASSERT(dn->dn_maxblkid == 0 &&
 +		    (BP_IS_HOLE(&dn->dn_phys->dn_blkptr[0]) ||
 +		    dnode_block_freed(dn, 0)));
 +		dnode_setdblksz(dn, blocksize);
 +		dn->dn_next_blksz[tx->tx_txg&TXG_MASK] = blocksize;
 +	}
 +	if (dn->dn_bonuslen != bonuslen)
 +		dn->dn_next_bonuslen[tx->tx_txg&TXG_MASK] = bonuslen;
 +	nblkptr = 1 + ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
  	if (dn->dn_nblkptr != nblkptr)
  		dn->dn_next_nblkptr[tx->tx_txg&TXG_MASK] = nblkptr;
  	rw_exit(&dn->dn_struct_rwlock);
 -	if (db)
 -		dbuf_rele(db, FTAG);
  
  	/* change type */
  	dn->dn_type = ot;
 @@ -1187,11 +1169,6 @@ dnode_block_freed(dnode_t *dn, uint64_t 
  	if (dn->dn_free_txg)
  		return (TRUE);
  
 -	/*
 -	 * If dn_datablkshift is not set, then there's only a single
 -	 * block, in which case there will never be a free range so it
 -	 * won't matter.
 -	 */
  	range_tofind.fr_blkid = blkid;
  	mutex_enter(&dn->dn_mtx);
  	for (i = 0; i < TXG_SIZE; i++) {
 
 Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h
 ==============================================================================
 --- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h	Sun Jan  3 02:58:43 2010	(r201410)
 +++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h	Sun Jan  3 03:05:30 2010	(r201411)
 @@ -19,7 +19,7 @@
   * CDDL HEADER END
   */
  /*
 - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
   * Use is subject to license terms.
   */
  
 @@ -237,7 +237,7 @@ uint64_t dmu_object_alloc(objset_t *os, 
  int dmu_object_claim(objset_t *os, uint64_t object, dmu_object_type_t ot,
      int blocksize, dmu_object_type_t bonus_type, int bonus_len, dmu_tx_t *tx);
  int dmu_object_reclaim(objset_t *os, uint64_t object, dmu_object_type_t ot,
 -    int blocksize, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx);
 +    int blocksize, dmu_object_type_t bonustype, int bonuslen);
  
  /*
   * Free an object from this objset.
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
>Unformatted:
