From owner-freebsd-bugs@FreeBSD.ORG Fri Dec 11 22:40:02 2009 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 61F32106568D for ; Fri, 11 Dec 2009 22:40:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 21F468FC0C for ; Fri, 11 Dec 2009 22:40:02 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id nBBMe2ID092594 for ; Fri, 11 Dec 2009 22:40:02 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.3/8.14.3/Submit) id nBBMe1ir092593; Fri, 11 Dec 2009 22:40:01 GMT (envelope-from gnats) Resent-Date: Fri, 11 Dec 2009 22:40:01 GMT Resent-Message-Id: <200912112240.nBBMe1ir092593@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Martin Matuska Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4FC8E1065670 for ; 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 ; 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 ; 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 ; 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 To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: Subject: kern/141387: [zfs] [patch] zfs snapshot -r failed because filesystem was busy X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Martin Matuska List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 11 Dec 2009 22:40:02 -0000 >Number: 141387 >Category: kern >Synopsis: [zfs] [patch] zfs snapshot -r failed because filesystem was busy >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Dec 11 22:40:01 UTC 2009 >Closed-Date: >Last-Modified: >Originator: Martin Matuska >Release: FreeBSD 8-STABLE amd64 >Organization: >Environment: System: FreeBSD 8-STABLE FreeBSD 8-STABLE #2 >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: >Unformatted: