From: Brian Foster Date: Fri, 18 Dec 2015 01:14:39 +0000 (+1100) Subject: libxfs: conditionalize log format record size optimization X-Git-Tag: v4.5.0-rc1~63 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=571a78a7f3c6c4397f225cbaf9192da7ac49a1ec;p=thirdparty%2Fxfsprogs-dev.git libxfs: conditionalize log format record size optimization The libxfs log clear mechanism includes an optimization to use the maximum log buffer size (256k) when the log is being fully written (i.e., cycle != 1). This behavior is always enabled as no current callers are concerned with the size of the records written to format the log to a given cycle. A log format command will be added to xfs_db to facilitate testing of the userspace log format code (among other things). This command is not performance oriented and prefers the ability to format the log with varying record sizes. Update libxfs_log_clear() to use a new parameter to enable or disable the record size optimization. Note that the flag is a no-op when the cycle == XLOG_INIT_CYCLE (e.g., mkfs). Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c index 1dc7c6500..62edfc834 100644 --- a/copy/xfs_copy.c +++ b/copy/xfs_copy.c @@ -1328,7 +1328,7 @@ format_log( */ libxfs_log_clear(NULL, buf->data, logstart, length, &buf->owner->uuid, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, - mp->m_sb.sb_logsunit, XLOG_FMT, cycle); + mp->m_sb.sb_logsunit, XLOG_FMT, cycle, true); if (do_write(buf->owner, buf)) target[tcarg->id].state = INACTIVE; } diff --git a/db/metadump.c b/db/metadump.c index 8cdcb92e8..8455fdd60 100644 --- a/db/metadump.c +++ b/db/metadump.c @@ -2552,7 +2552,7 @@ copy_log(void) libxfs_log_clear(NULL, iocur_top->data, logstart, logblocks, &mp->m_sb.sb_uuid, logversion, - mp->m_sb.sb_logsunit, XLOG_FMT, cycle); + mp->m_sb.sb_logsunit, XLOG_FMT, cycle, true); break; case 1: /* keep the dirty log */ diff --git a/db/sb.c b/db/sb.c index 17d446cec..ee3927dd2 100644 --- a/db/sb.c +++ b/db/sb.c @@ -288,7 +288,7 @@ sb_logzero(uuid_t *uuidp) (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), uuidp, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, - mp->m_sb.sb_logsunit, XLOG_FMT, cycle); + mp->m_sb.sb_logsunit, XLOG_FMT, cycle, true); if (error) { dbprintf(_("ERROR: cannot clear the log\n")); return 0; diff --git a/include/libxfs.h b/include/libxfs.h index 04c6f9c74..bd51df0d7 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -154,7 +154,7 @@ typedef char *(libxfs_get_block_t)(char *, int, void *); */ #define XLOG_INIT_CYCLE 1 extern int libxfs_log_clear(struct xfs_buftarg *, char *, xfs_daddr_t, - uint, uuid_t *, int, int, int, int); + uint, uuid_t *, int, int, int, int, bool); extern int libxfs_log_header(char *, uuid_t *, int, int, int, xfs_lsn_t, xfs_lsn_t, libxfs_get_block_t *, void *); diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index 16904d0b0..7a0498509 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -162,7 +162,8 @@ libxfs_log_clear( int version, int sunit, /* bytes */ int fmt, - int cycle) + int cycle, + bool max) { struct xfs_buf *bp = NULL; int len; @@ -217,6 +218,14 @@ libxfs_log_clear( if (cycle == XLOG_INIT_CYCLE) return 0; + /* + * Bump the record size for a full log format if the caller allows it. + * This is primarily for performance reasons and most callers don't care + * about record size since the log is clean after we're done. + */ + if (max) + len = BTOBB(BDSTRAT_SIZE); + /* * Otherwise, fill everything beyond the initial record with records of * the previous cycle so the kernel head/tail detection works correctly. @@ -233,7 +242,7 @@ libxfs_log_clear( dptr += BBTOB(len); end_blk = start + length; - len = min(end_blk - blk, BTOBB(BDSTRAT_SIZE)); + len = min(end_blk - blk, len); while (blk < end_blk) { lsn = xlog_assign_lsn(cycle, blk - start); tail_lsn = xlog_assign_lsn(cycle, blk - start - len); @@ -257,7 +266,7 @@ libxfs_log_clear( blk += len; if (dptr) dptr += BBTOB(len); - len = min(end_blk - blk, BTOBB(BDSTRAT_SIZE)); + len = min(end_blk - blk, len); } return 0; diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 7cba41a69..546108dda 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -2713,7 +2713,8 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), libxfs_log_clear(mp->m_logdev_targp, NULL, XFS_FSB_TO_DADDR(mp, logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, logblocks), - &sbp->sb_uuid, logversion, lsunit, XLOG_FMT, XLOG_INIT_CYCLE); + &sbp->sb_uuid, logversion, lsunit, XLOG_FMT, XLOG_INIT_CYCLE, + false); mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 0); if (mp == NULL) { diff --git a/repair/phase2.c b/repair/phase2.c index cb24711d2..e21ffa66c 100644 --- a/repair/phase2.c +++ b/repair/phase2.c @@ -119,7 +119,7 @@ zero_log( (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), &mp->m_sb.sb_uuid, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, - mp->m_sb.sb_logsunit, XLOG_FMT, XLOG_INIT_CYCLE); + mp->m_sb.sb_logsunit, XLOG_FMT, XLOG_INIT_CYCLE, true); /* update the log data structure with new state */ error = xlog_find_tail(log, &head_blk, &tail_blk); diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index 1aeac5ba4..3eaced4b0 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -586,7 +586,7 @@ format_log_max_lsn( do_warn(_("Format log to cycle %d.\n"), new_cycle); libxfs_log_clear(log->l_dev, NULL, logstart, logblocks, &mp->m_sb.sb_uuid, logversion, mp->m_sb.sb_logsunit, - XLOG_FMT, new_cycle); + XLOG_FMT, new_cycle, true); } int