mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-24 11:29:10 +00:00
Apply fix Solaris bug 6462803 zfs snapshot -r failed because
filesystem was busy. Submitted by: mm Approved by: pjd MFC after: 2 weeks
This commit is contained in:
parent
28d3fd007e
commit
775f802393
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=200724
@ -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: ");
|
||||
|
@ -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,9 +56,15 @@ 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
|
||||
*
|
||||
|
@ -502,6 +502,25 @@ zil_rollback_destroy(zilog_t *zilog, dmu_tx_t *tx)
|
||||
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)
|
||||
{
|
||||
@ -521,6 +540,21 @@ zil_claim(char *osname, void *txarg)
|
||||
zilog = dmu_objset_zil(os);
|
||||
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
|
||||
@ -1344,25 +1378,6 @@ zil_free(zilog_t *zilog)
|
||||
kmem_free(zilog, sizeof (zilog_t));
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
@ -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, uint64_t *txgp,
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user