From mm@mail.vx.sk  Fri Dec 11 22:35:25 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 4FC8E1065670
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 11 Dec 2009 22:35:25 +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 C015D8FC0A
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 11 Dec 2009 22:35:24 +0000 (UTC)
Received: from localhost (localhost [127.0.0.1])
	by mail.vx.sk (Postfix) with ESMTP id 2E3162954C
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 11 Dec 2009 23:35:23 +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 YJ9rG+VcBa0r for <FreeBSD-gnats-submit@freebsd.org>;
	Fri, 11 Dec 2009 23:35:21 +0100 (CET)
Received: by mail.vx.sk (Postfix, from userid 1001)
	id 52B082953F; Fri, 11 Dec 2009 23:35:21 +0100 (CET)
Message-Id: <20091211223521.52B082953F@mail.vx.sk>
Date: Fri, 11 Dec 2009 23:35:21 +0100 (CET)
From: Martin Matuska <mm@FreeBSD.org>
Reply-To: Martin Matuska <mm@FreeBSD.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [zfs] [patch] zfs snapshot -r failed because filesystem was busy
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         141387
>Category:       kern
>Synopsis:       [zfs] [patch] zfs snapshot -r failed because filesystem was busy
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    delphij
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Dec 11 22:40:01 UTC 2009
>Closed-Date:    Sun Jan 03 02:58:42 UTC 2010
>Last-Modified:  Sun Jan  3 03:00:09 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 recursive snapshot that was already fixed in OpenSolaris snv_111
I was able to reproduce this bug in FreeBSD.

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

This bug was fixed in OpenSolaris snv_111:
http://dlc.sun.com/osol/on/downloads/b111/on-changelog-b111.html

Issues Resolved:
BUG/RFE:6462803 zfs snapshot -r failed because filesystem was busy
Files Changed:
update:usr/src/cmd/zdb/zdb_il.c
update:usr/src/grub/grub-0.97/stage2/zfs-include/zil.h
update:usr/src/uts/common/fs/zfs/sys/zil.h
update:usr/src/uts/common/fs/zfs/zil.c

Revision: 8989:cfce31f4eebf

hg clone ssh://anon@hg.opensolaris.org/hg/onnv/onnv-gate
hg diff -c 8989 onnv-gate
>How-To-Repeat:
This may happen during ZFS recursive snapshot (managed to reproduce it):
root@www:~ > zfs snapshot -r pool@test
cannot create snapshot 'pool@test': dataset is busy
no snapshots were created
>Fix:
Index: cddl/contrib/opensolaris/cmd/zdb/zdb_il.c
===================================================================
--- cddl/contrib/opensolaris/cmd/zdb/zdb_il.c	(revision 200415)
+++ cddl/contrib/opensolaris/cmd/zdb/zdb_il.c	(working copy)
@@ -19,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 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"
-
 /*
  * Print intent log header and statistics.
  */
@@ -345,8 +343,10 @@
 	if (zh->zh_log.blk_birth == 0 || verbose < 2)
 		return;
 
-	(void) printf("\n    ZIL header: claim_txg %llu, seq %llu\n",
-	    (u_longlong_t)zh->zh_claim_txg, (u_longlong_t)zh->zh_replay_seq);
+	(void) printf("\n    ZIL header: claim_txg %llu, claim_seq %llu",
+	    (u_longlong_t)zh->zh_claim_txg, (u_longlong_t)zh->zh_claim_seq);
+	(void) printf(" replay_seq %llu, flags 0x%llx\n",
+	    (u_longlong_t)zh->zh_replay_seq, (u_longlong_t)zh->zh_flags);
 
 	if (verbose >= 4)
 		print_log_bp(&zh->zh_log, "\n\tfirst block: ");
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c	(revision 200415)
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c	(working copy)
@@ -502,6 +502,25 @@
 	    tx, zh->zh_claim_txg);
 }
 
+/*
+ * return true if the initial log block is not valid
+ */
+static boolean_t
+zil_empty(zilog_t *zilog)
+{
+	const zil_header_t *zh = zilog->zl_header;
+	arc_buf_t *abuf = NULL;
+
+	if (BP_IS_HOLE(&zh->zh_log))
+		return (B_TRUE);
+
+	if (zil_read_log_block(zilog, &zh->zh_log, &abuf) != 0)
+		return (B_TRUE);
+
+	VERIFY(arc_buf_remove_ref(abuf, &abuf) == 1);
+	return (B_FALSE);
+}
+
 int
 zil_claim(char *osname, void *txarg)
 {
@@ -522,6 +541,21 @@
 	zh = zil_header_in_syncing_context(zilog);
 
 	/*
+	 * Record here whether the zil has any records to replay.
+	 * If the header block pointer is null or the block points
+	 * to the stubby then we know there are no valid log records.
+	 * We use the header to store this state as the the zilog gets
+	 * freed later in dmu_objset_close().
+	 * The flags (and the rest of the header fields) are cleared in
+	 * zil_sync() as a result of a zil_destroy(), after replaying the log.
+	 *
+	 * Note, the intent log can be empty but still need the
+	 * stubby to be claimed.
+	 */
+	if (!zil_empty(zilog))
+		zh->zh_flags |= ZIL_REPLAY_NEEDED;
+
+	/*
 	 * Claim all log blocks if we haven't already done so, and remember
 	 * the highest claimed sequence number.  This ensures that if we can
 	 * read only part of the log now (e.g. due to a missing device),
@@ -1345,25 +1379,6 @@
 }
 
 /*
- * return true if the initial log block is not valid
- */
-static boolean_t
-zil_empty(zilog_t *zilog)
-{
-	const zil_header_t *zh = zilog->zl_header;
-	arc_buf_t *abuf = NULL;
-
-	if (BP_IS_HOLE(&zh->zh_log))
-		return (B_TRUE);
-
-	if (zil_read_log_block(zilog, &zh->zh_log, &abuf) != 0)
-		return (B_TRUE);
-
-	VERIFY(arc_buf_remove_ref(abuf, &abuf) == 1);
-	return (B_FALSE);
-}
-
-/*
  * Open an intent log.
  */
 zilog_t *
@@ -1418,7 +1433,7 @@
 	const zil_header_t *zh = zilog->zl_header;
 
 	mutex_enter(&zilog->zl_lock);
-	if (zh->zh_claim_txg != 0) {		/* unplayed log */
+	if (zh->zh_flags & ZIL_REPLAY_NEEDED) {		/* unplayed log */
 		mutex_exit(&zilog->zl_lock);
 		return (EBUSY);
 	}
@@ -1645,7 +1660,7 @@
 	const zil_header_t *zh = zilog->zl_header;
 	zil_replay_arg_t zr;
 
-	if (zil_empty(zilog)) {
+	if ((zh->zh_flags & ZIL_REPLAY_NEEDED) == 0) {
 		zil_destroy(zilog, B_TRUE);
 		return;
 	}
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h	(revision 200415)
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.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.
  */
 
@@ -56,10 +56,16 @@
 	uint64_t zh_replay_seq;	/* highest replayed sequence number */
 	blkptr_t zh_log;	/* log chain */
 	uint64_t zh_claim_seq;	/* highest claimed sequence number */
-	uint64_t zh_pad[5];
+	uint64_t zh_flags;	/* header flags */
+	uint64_t zh_pad[4];
 } zil_header_t;
 
 /*
+ * zh_flags bit settings
+ */
+#define	ZIL_REPLAY_NEEDED 0x1	/* replay needed - internal only */
+
+/*
  * Log block trailer - structure at the end of the header and each log block
  *
  * The zit_bt contains a zbt_cksum which for the intent log is
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-fs 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Fri Dec 11 22:48:30 UTC 2009 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=141387 
State-Changed-From-To: open->patched 
State-Changed-By: delphij 
State-Changed-When: Sat Dec 19 11:58:46 UTC 2009 
State-Changed-Why:  
A patch has been applied as revision 200727. 


Responsible-Changed-From-To: freebsd-fs->delphij 
Responsible-Changed-By: delphij 
Responsible-Changed-When: Sat Dec 19 11:58:46 UTC 2009 
Responsible-Changed-Why:  
Grab. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=141387 
State-Changed-From-To: patched->closed 
State-Changed-By: delphij 
State-Changed-When: Sun Jan 3 02:58:21 UTC 2010 
State-Changed-Why:  
Patch applied against 8-STABLE, thanks for your submission! 

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

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

 Author: delphij
 Date: Sun Jan  3 02:58:05 2010
 New Revision: 201409
 URL: http://svn.freebsd.org/changeset/base/201409
 
 Log:
   MFC r200724:
   
   Apply fix for Solaris bug  6462803 zfs snapshot -r failed because
   filesystem was busy.
   
   PR:		kern/141387
   Submitted by:	mm
   Approved by:	pjd
   Obtained from:	OpenSolaris (onnv 8989:cfce31f4eebf)
 
 Modified:
   stable/8/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c
   stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h
   stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
 Directory Properties:
   stable/8/cddl/contrib/opensolaris/cmd/zdb/   (props changed)
   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/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c
 ==============================================================================
 --- stable/8/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c	Sun Jan  3 02:43:46 2010	(r201408)
 +++ stable/8/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c	Sun Jan  3 02:58:05 2010	(r201409)
 @@ -19,12 +19,10 @@
   * CDDL HEADER END
   */
  /*
 - * Copyright 2007 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"
 -
  /*
   * Print intent log header and statistics.
   */
 @@ -345,8 +343,10 @@ dump_intent_log(zilog_t *zilog)
  	if (zh->zh_log.blk_birth == 0 || verbose < 2)
  		return;
  
 -	(void) printf("\n    ZIL header: claim_txg %llu, seq %llu\n",
 -	    (u_longlong_t)zh->zh_claim_txg, (u_longlong_t)zh->zh_replay_seq);
 +	(void) printf("\n    ZIL header: claim_txg %llu, claim_seq %llu",
 +	    (u_longlong_t)zh->zh_claim_txg, (u_longlong_t)zh->zh_claim_seq);
 +	(void) printf(" replay_seq %llu, flags 0x%llx\n",
 +	    (u_longlong_t)zh->zh_replay_seq, (u_longlong_t)zh->zh_flags);
  
  	if (verbose >= 4)
  		print_log_bp(&zh->zh_log, "\n\tfirst block: ");
 
 Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h
 ==============================================================================
 --- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h	Sun Jan  3 02:43:46 2010	(r201408)
 +++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h	Sun Jan  3 02:58:05 2010	(r201409)
 @@ -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.
   */
  
 @@ -56,10 +56,16 @@ typedef struct zil_header {
  	uint64_t zh_replay_seq;	/* highest replayed sequence number */
  	blkptr_t zh_log;	/* log chain */
  	uint64_t zh_claim_seq;	/* highest claimed sequence number */
 -	uint64_t zh_pad[5];
 +	uint64_t zh_flags;	/* header flags */
 +	uint64_t zh_pad[4];
  } zil_header_t;
  
  /*
 + * zh_flags bit settings
 + */
 +#define	ZIL_REPLAY_NEEDED 0x1	/* replay needed - internal only */
 +
 +/*
   * Log block trailer - structure at the end of the header and each log block
   *
   * The zit_bt contains a zbt_cksum which for the intent log is
 
 Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
 ==============================================================================
 --- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c	Sun Jan  3 02:43:46 2010	(r201408)
 +++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c	Sun Jan  3 02:58:05 2010	(r201409)
 @@ -502,6 +502,25 @@ zil_rollback_destroy(zilog_t *zilog, dmu
  	    tx, zh->zh_claim_txg);
  }
  
 +/*
 + * return true if the initial log block is not valid
 + */
 +static boolean_t
 +zil_empty(zilog_t *zilog)
 +{
 +	const zil_header_t *zh = zilog->zl_header;
 +	arc_buf_t *abuf = NULL;
 +
 +	if (BP_IS_HOLE(&zh->zh_log))
 +		return (B_TRUE);
 +
 +	if (zil_read_log_block(zilog, &zh->zh_log, &abuf) != 0)
 +		return (B_TRUE);
 +
 +	VERIFY(arc_buf_remove_ref(abuf, &abuf) == 1);
 +	return (B_FALSE);
 +}
 +
  int
  zil_claim(char *osname, void *txarg)
  {
 @@ -522,6 +541,21 @@ zil_claim(char *osname, void *txarg)
  	zh = zil_header_in_syncing_context(zilog);
  
  	/*
 +	 * Record here whether the zil has any records to replay.
 +	 * If the header block pointer is null or the block points
 +	 * to the stubby then we know there are no valid log records.
 +	 * We use the header to store this state as the the zilog gets
 +	 * freed later in dmu_objset_close().
 +	 * The flags (and the rest of the header fields) are cleared in
 +	 * zil_sync() as a result of a zil_destroy(), after replaying the log.
 +	 *
 +	 * Note, the intent log can be empty but still need the
 +	 * stubby to be claimed.
 +	 */
 +	if (!zil_empty(zilog))
 +		zh->zh_flags |= ZIL_REPLAY_NEEDED;
 +
 +	/*
  	 * Claim all log blocks if we haven't already done so, and remember
  	 * the highest claimed sequence number.  This ensures that if we can
  	 * read only part of the log now (e.g. due to a missing device),
 @@ -1345,25 +1379,6 @@ zil_free(zilog_t *zilog)
  }
  
  /*
 - * return true if the initial log block is not valid
 - */
 -static boolean_t
 -zil_empty(zilog_t *zilog)
 -{
 -	const zil_header_t *zh = zilog->zl_header;
 -	arc_buf_t *abuf = NULL;
 -
 -	if (BP_IS_HOLE(&zh->zh_log))
 -		return (B_TRUE);
 -
 -	if (zil_read_log_block(zilog, &zh->zh_log, &abuf) != 0)
 -		return (B_TRUE);
 -
 -	VERIFY(arc_buf_remove_ref(abuf, &abuf) == 1);
 -	return (B_FALSE);
 -}
 -
 -/*
   * Open an intent log.
   */
  zilog_t *
 @@ -1418,7 +1433,7 @@ zil_suspend(zilog_t *zilog)
  	const zil_header_t *zh = zilog->zl_header;
  
  	mutex_enter(&zilog->zl_lock);
 -	if (zh->zh_claim_txg != 0) {		/* unplayed log */
 +	if (zh->zh_flags & ZIL_REPLAY_NEEDED) {		/* unplayed log */
  		mutex_exit(&zilog->zl_lock);
  		return (EBUSY);
  	}
 @@ -1645,7 +1660,7 @@ zil_replay(objset_t *os, void *arg, uint
  	const zil_header_t *zh = zilog->zl_header;
  	zil_replay_arg_t zr;
  
 -	if (zil_empty(zilog)) {
 +	if ((zh->zh_flags & ZIL_REPLAY_NEEDED) == 0) {
  		zil_destroy(zilog, B_TRUE);
  		return;
  	}
 _______________________________________________
 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:
