ZIL: use a bitfield for LWB "slog" and "slim" state flags

I'm soon about to need another LWB flag, and boolean_t is just so big
for only storing a single bit. Changing to a bitfield is far less
wasteful.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17622
This commit is contained in:
Rob Norris 2025-05-16 15:25:59 +10:00 committed by Brian Behlendorf
parent 6b3333de2d
commit 508c546975
2 changed files with 23 additions and 14 deletions

View File

@ -100,11 +100,15 @@ typedef enum {
* holding the "zl_issuer_lock". After the lwb is issued, the zilog's * holding the "zl_issuer_lock". After the lwb is issued, the zilog's
* "zl_lock" is used to protect the lwb against concurrent access. * "zl_lock" is used to protect the lwb against concurrent access.
*/ */
typedef enum {
LWB_FLAG_SLIM = (1<<0), /* log block has slim format */
LWB_FLAG_SLOG = (1<<1), /* lwb_blk is on SLOG device */
} lwb_flag_t;
typedef struct lwb { typedef struct lwb {
zilog_t *lwb_zilog; /* back pointer to log struct */ zilog_t *lwb_zilog; /* back pointer to log struct */
blkptr_t lwb_blk; /* on disk address of this log blk */ blkptr_t lwb_blk; /* on disk address of this log blk */
boolean_t lwb_slim; /* log block has slim format */ lwb_flag_t lwb_flags; /* extra info about this lwb */
boolean_t lwb_slog; /* lwb_blk is on SLOG device */
int lwb_error; /* log block allocation error */ int lwb_error; /* log block allocation error */
int lwb_nmax; /* max bytes in the buffer */ int lwb_nmax; /* max bytes in the buffer */
int lwb_nused; /* # used bytes in buffer */ int lwb_nused; /* # used bytes in buffer */

View File

@ -825,19 +825,22 @@ zil_alloc_lwb(zilog_t *zilog, int sz, blkptr_t *bp, boolean_t slog,
lwb_t *lwb; lwb_t *lwb;
lwb = kmem_cache_alloc(zil_lwb_cache, KM_SLEEP); lwb = kmem_cache_alloc(zil_lwb_cache, KM_SLEEP);
lwb->lwb_flags = 0;
lwb->lwb_zilog = zilog; lwb->lwb_zilog = zilog;
if (bp) { if (bp) {
lwb->lwb_blk = *bp; lwb->lwb_blk = *bp;
lwb->lwb_slim = (BP_GET_CHECKSUM(bp) == ZIO_CHECKSUM_ZILOG2); if (BP_GET_CHECKSUM(bp) == ZIO_CHECKSUM_ZILOG2)
lwb->lwb_flags |= LWB_FLAG_SLIM;
sz = BP_GET_LSIZE(bp); sz = BP_GET_LSIZE(bp);
} else { } else {
BP_ZERO(&lwb->lwb_blk); BP_ZERO(&lwb->lwb_blk);
lwb->lwb_slim = (spa_version(zilog->zl_spa) >= if (spa_version(zilog->zl_spa) >= SPA_VERSION_SLIM_ZIL)
SPA_VERSION_SLIM_ZIL); lwb->lwb_flags |= LWB_FLAG_SLIM;
} }
lwb->lwb_slog = slog; if (slog)
lwb->lwb_flags |= LWB_FLAG_SLOG;
lwb->lwb_error = 0; lwb->lwb_error = 0;
if (lwb->lwb_slim) { if (lwb->lwb_flags & LWB_FLAG_SLIM) {
lwb->lwb_nmax = sz; lwb->lwb_nmax = sz;
lwb->lwb_nused = lwb->lwb_nfilled = sizeof (zil_chain_t); lwb->lwb_nused = lwb->lwb_nfilled = sizeof (zil_chain_t);
} else { } else {
@ -1944,14 +1947,15 @@ zil_lwb_write_issue(zilog_t *zilog, lwb_t *lwb)
mutex_exit(&zilog->zl_lock); mutex_exit(&zilog->zl_lock);
next_lwb: next_lwb:
if (lwb->lwb_slim) if (lwb->lwb_flags & LWB_FLAG_SLIM)
zilc = (zil_chain_t *)lwb->lwb_buf; zilc = (zil_chain_t *)lwb->lwb_buf;
else else
zilc = (zil_chain_t *)(lwb->lwb_buf + lwb->lwb_nmax); zilc = (zil_chain_t *)(lwb->lwb_buf + lwb->lwb_nmax);
int wsz = lwb->lwb_sz; int wsz = lwb->lwb_sz;
if (lwb->lwb_error == 0) { if (lwb->lwb_error == 0) {
abd_t *lwb_abd = abd_get_from_buf(lwb->lwb_buf, lwb->lwb_sz); abd_t *lwb_abd = abd_get_from_buf(lwb->lwb_buf, lwb->lwb_sz);
if (!lwb->lwb_slog || zilog->zl_cur_size <= zil_slog_bulk) if (!(lwb->lwb_flags & LWB_FLAG_SLOG) ||
zilog->zl_cur_size <= zil_slog_bulk)
prio = ZIO_PRIORITY_SYNC_WRITE; prio = ZIO_PRIORITY_SYNC_WRITE;
else else
prio = ZIO_PRIORITY_ASYNC_WRITE; prio = ZIO_PRIORITY_ASYNC_WRITE;
@ -1963,7 +1967,7 @@ next_lwb:
lwb, prio, ZIO_FLAG_CANFAIL, &zb); lwb, prio, ZIO_FLAG_CANFAIL, &zb);
zil_lwb_add_block(lwb, &lwb->lwb_blk); zil_lwb_add_block(lwb, &lwb->lwb_blk);
if (lwb->lwb_slim) { if (lwb->lwb_flags & LWB_FLAG_SLIM) {
/* For Slim ZIL only write what is used. */ /* For Slim ZIL only write what is used. */
wsz = P2ROUNDUP_TYPED(lwb->lwb_nused, ZIL_MIN_BLKSZ, wsz = P2ROUNDUP_TYPED(lwb->lwb_nused, ZIL_MIN_BLKSZ,
int); int);
@ -2009,8 +2013,8 @@ next_lwb:
} }
if (error == 0) { if (error == 0) {
ASSERT3U(BP_GET_BIRTH(bp), ==, txg); ASSERT3U(BP_GET_BIRTH(bp), ==, txg);
BP_SET_CHECKSUM(bp, nlwb->lwb_slim ? ZIO_CHECKSUM_ZILOG2 : BP_SET_CHECKSUM(bp, (nlwb->lwb_flags & LWB_FLAG_SLIM) ?
ZIO_CHECKSUM_ZILOG); ZIO_CHECKSUM_ZILOG2 : ZIO_CHECKSUM_ZILOG);
bp->blk_cksum = lwb->lwb_blk.blk_cksum; bp->blk_cksum = lwb->lwb_blk.blk_cksum;
bp->blk_cksum.zc_word[ZIL_ZC_SEQ]++; bp->blk_cksum.zc_word[ZIL_ZC_SEQ]++;
} }
@ -2039,14 +2043,15 @@ next_lwb:
if (nlwb) { if (nlwb) {
nlwb->lwb_blk = *bp; nlwb->lwb_blk = *bp;
nlwb->lwb_error = error; nlwb->lwb_error = error;
nlwb->lwb_slog = slog; if (slog)
nlwb->lwb_flags |= LWB_FLAG_SLOG;
nlwb->lwb_alloc_txg = txg; nlwb->lwb_alloc_txg = txg;
if (nlwb->lwb_state != LWB_STATE_READY) if (nlwb->lwb_state != LWB_STATE_READY)
nlwb = NULL; nlwb = NULL;
} }
mutex_exit(&zilog->zl_lock); mutex_exit(&zilog->zl_lock);
if (lwb->lwb_slog) { if (lwb->lwb_flags & LWB_FLAG_SLOG) {
ZIL_STAT_BUMP(zilog, zil_itx_metaslab_slog_count); ZIL_STAT_BUMP(zilog, zil_itx_metaslab_slog_count);
ZIL_STAT_INCR(zilog, zil_itx_metaslab_slog_bytes, ZIL_STAT_INCR(zilog, zil_itx_metaslab_slog_bytes,
lwb->lwb_nused); lwb->lwb_nused);