summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorNeil Perrin <Neil.Perrin@Sun.COM>2009-03-06 10:47:00 -0700
committerNeil Perrin <Neil.Perrin@Sun.COM>2009-03-06 10:47:00 -0700
commit3589c4f01c20349ca65899d209cdc0c17a641433 (patch)
treefaa56e5ffd2d8a7405aef968bf4822b2248cf647 /usr/src
parent13651adbc76509937e310f6a6a515b59ff7bbafd (diff)
downloadillumos-gate-3589c4f01c20349ca65899d209cdc0c17a641433.tar.gz
6462803 zfs snapshot -r failed because filesystem was busy
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/zdb/zdb_il.c10
-rw-r--r--usr/src/grub/grub-0.97/stage2/zfs-include/zil.h12
-rw-r--r--usr/src/uts/common/fs/zfs/sys/zil.h10
-rw-r--r--usr/src/uts/common/fs/zfs/zil.c57
4 files changed, 57 insertions, 32 deletions
diff --git a/usr/src/cmd/zdb/zdb_il.c b/usr/src/cmd/zdb/zdb_il.c
index 02d35a0503..cc08ef5148 100644
--- a/usr/src/cmd/zdb/zdb_il.c
+++ b/usr/src/cmd/zdb/zdb_il.c
@@ -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: ");
diff --git a/usr/src/grub/grub-0.97/stage2/zfs-include/zil.h b/usr/src/grub/grub-0.97/stage2/zfs-include/zil.h
index 11ab4b5a3a..87c1dc57f1 100644
--- a/usr/src/grub/grub-0.97/stage2/zfs-include/zil.h
+++ b/usr/src/grub/grub-0.97/stage2/zfs-include/zil.h
@@ -17,15 +17,13 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_ZIL_H
#define _SYS_ZIL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Intent log format:
*
@@ -47,7 +45,13 @@ 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 */
+
#endif /* _SYS_ZIL_H */
diff --git a/usr/src/uts/common/fs/zfs/sys/zil.h b/usr/src/uts/common/fs/zfs/sys/zil.h
index b69323cfaf..d85345d86d 100644
--- a/usr/src/uts/common/fs/zfs/sys/zil.h
+++ b/usr/src/uts/common/fs/zfs/sys/zil.h
@@ -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
diff --git a/usr/src/uts/common/fs/zfs/zil.c b/usr/src/uts/common/fs/zfs/zil.c
index b9a373139b..2a1f82a1be 100644
--- a/usr/src/uts/common/fs/zfs/zil.c
+++ b/usr/src/uts/common/fs/zfs/zil.c
@@ -470,6 +470,25 @@ zil_destroy(zilog_t *zilog, boolean_t keep_first)
dmu_tx_commit(tx);
}
+/*
+ * 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)
{
@@ -490,6 +509,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),
@@ -1313,25 +1347,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 *
@@ -1386,7 +1401,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);
}
@@ -1570,7 +1585,7 @@ zil_replay(objset_t *os, void *arg, zil_replay_func_t *replay_func[TX_MAX_TYPE])
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;
}