From: Brian Foster <bfoster@redhat.com>
To: xfs@oss.sgi.com
Subject: [PATCH v3 13/18] db/metadump: bump lsn when log is cleared on v5 supers
Date: Fri, 2 Oct 2015 14:19:50 -0400 [thread overview]
Message-ID: <1443809995-20395-14-git-send-email-bfoster@redhat.com> (raw)
In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com>
xfs_metadump handles the log in different ways depending on the mode of
operation. If the log is dirty or obfuscation and stale data zeroing are
disabled, the log is copied as is. In all other scenarios, the log is
explicitly zeroed. This is incorrect for version 5 superblocks where the
current LSN is always expected to be ahead of all fs metadata.
Update metadump to use libxfs_log_clear() to format the log with an
elevated LSN rather than zero the log and reset the current the LSN.
Metadump does not use buffers for the dump target, instead using a
cursor implementation to access the log via a single memory buffer.
Therefore, update libxfs_log_clear() to receive an optional (but
exclusive to the buftarg parameter) memory buffer pointer for the log.
If the pointer is provided, the log format is written out to this
buffer. Otherwise, fall back to the original behavior and access the log
through buftarg buffers.
Signed-off-by: Brian Foster <bfoster@redhat.com>
---
db/metadump.c | 16 +++++++++++--
db/sb.c | 2 +-
include/libxfs.h | 4 ++--
libxfs/rdwr.c | 68 +++++++++++++++++++++++++++++++++++++++--------------
mkfs/xfs_mkfs.c | 2 +-
repair/phase2.c | 2 +-
repair/xfs_repair.c | 5 ++--
7 files changed, 72 insertions(+), 27 deletions(-)
diff --git a/db/metadump.c b/db/metadump.c
index 129670e..56b733e 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -2514,6 +2514,10 @@ copy_log(void)
{
struct xlog log;
int dirty;
+ xfs_daddr_t logstart;
+ int logblocks;
+ int logversion;
+ int cycle = XLOG_INIT_CYCLE;
if (show_progress)
print_progress("Copying log");
@@ -2538,8 +2542,16 @@ copy_log(void)
/* clear out a clean log */
if (show_progress)
print_progress("Zeroing clean log");
- memset(iocur_top->data, 0,
- mp->m_sb.sb_logblocks * mp->m_sb.sb_blocksize);
+
+ logstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart);
+ logblocks = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
+ logversion = xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1;
+ if (xfs_sb_version_hascrc(&mp->m_sb))
+ cycle = log.l_curr_cycle + 1;
+
+ libxfs_log_clear(NULL, iocur_top->data, logstart, logblocks,
+ &mp->m_sb.sb_uuid, logversion,
+ mp->m_sb.sb_logsunit, XLOG_FMT, cycle);
break;
case 1:
/* keep the dirty log */
diff --git a/db/sb.c b/db/sb.c
index 30c622d..17d446c 100644
--- a/db/sb.c
+++ b/db/sb.c
@@ -283,7 +283,7 @@ sb_logzero(uuid_t *uuidp)
dbprintf(_("Clearing log and setting UUID\n"));
- error = libxfs_log_clear(mp->m_logdev_targp,
+ error = libxfs_log_clear(mp->m_logdev_targp, NULL,
XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
(xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks),
uuidp,
diff --git a/include/libxfs.h b/include/libxfs.h
index 6c87934..f733c36 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -153,8 +153,8 @@ typedef char *(libxfs_get_block_t)(char *, int, void *);
* Helpers to clear the log to a particular log cycle.
*/
#define XLOG_INIT_CYCLE 1
-extern int libxfs_log_clear(struct xfs_buftarg *, xfs_daddr_t, uint,
- uuid_t *, int, int, int, int);
+extern int libxfs_log_clear(struct xfs_buftarg *, char *, xfs_daddr_t,
+ uint, uuid_t *, int, int, int, int);
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 93f6eb7..ee41a1e 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -133,38 +133,54 @@ static void unmount_record(void *p)
memcpy((char *)p + sizeof(xlog_op_header_t), &magic, sizeof(magic));
}
-static char *next(char *ptr, int offset, void *private)
+static char *next(
+ char *ptr,
+ int offset,
+ void *private)
{
- xfs_buf_t *buf = (xfs_buf_t *)private;
+ struct xfs_buf *buf = (struct xfs_buf *)private;
- if (XFS_BUF_COUNT(buf) < (int)(ptr - XFS_BUF_PTR(buf)) + offset)
+ if (buf &&
+ (XFS_BUF_COUNT(buf) < (int)(ptr - XFS_BUF_PTR(buf)) + offset))
abort();
+
return ptr + offset;
}
+/*
+ * Format the log. The caller provides either a buftarg which is used to access
+ * the log via buffers or a direct pointer to a buffer that encapsulates the
+ * entire log.
+ */
int
libxfs_log_clear(
struct xfs_buftarg *btp,
+ char *dptr,
xfs_daddr_t start,
- uint length,
+ uint length, /* basic blocks */
uuid_t *fs_uuid,
int version,
- int sunit,
+ int sunit, /* bytes */
int fmt,
int cycle)
{
- xfs_buf_t *bp;
+ struct xfs_buf *bp = NULL;
int len;
xfs_lsn_t lsn;
xfs_lsn_t tail_lsn;
xfs_daddr_t blk;
xfs_daddr_t end_blk;
+ char *ptr;
- if (!btp->dev || !fs_uuid)
+ if (((btp && dptr) || (!btp && !dptr)) ||
+ (btp && !btp->dev) || !fs_uuid)
return -EINVAL;
/* first zero the log */
- libxfs_device_zero(btp, start, length);
+ if (btp)
+ libxfs_device_zero(btp, start, length);
+ else
+ memset(dptr, 0, BBTOB(length));
/*
* Initialize the log record length and LSNs. XLOG_INIT_CYCLE is a
@@ -182,11 +198,17 @@ libxfs_log_clear(
tail_lsn = xlog_assign_lsn(cycle - 1, length - len);
/* write out the first log record */
- bp = libxfs_getbufr(btp, start, len);
- libxfs_log_header(XFS_BUF_PTR(bp), fs_uuid, version, sunit, fmt,
- lsn, tail_lsn, next, bp);
- bp->b_flags |= LIBXFS_B_DIRTY;
- libxfs_putbufr(bp);
+ ptr = dptr;
+ if (btp) {
+ bp = libxfs_getbufr(btp, start, len);
+ ptr = XFS_BUF_PTR(bp);
+ }
+ libxfs_log_header(ptr, fs_uuid, version, sunit, fmt, lsn, tail_lsn,
+ next, bp);
+ if (bp) {
+ bp->b_flags |= LIBXFS_B_DIRTY;
+ libxfs_putbufr(bp);
+ }
/*
* There's nothing else to do if this is a log reset. The kernel detects
@@ -207,6 +229,8 @@ libxfs_log_clear(
*/
cycle--;
blk = start + len;
+ if (dptr)
+ dptr += BBTOB(len);
end_blk = start + length;
len = min(end_blk - blk, BTOBB(BDSTRAT_SIZE));
@@ -214,18 +238,26 @@ libxfs_log_clear(
lsn = xlog_assign_lsn(cycle, blk - start);
tail_lsn = xlog_assign_lsn(cycle, blk - start - len);
- bp = libxfs_getbufr(btp, blk, len);
+ ptr = dptr;
+ if (btp) {
+ bp = libxfs_getbufr(btp, blk, len);
+ ptr = XFS_BUF_PTR(bp);
+ }
/*
* Note: pass the full buffer length as the sunit to initialize
* the entire buffer.
*/
- libxfs_log_header(XFS_BUF_PTR(bp), fs_uuid, version, BBTOB(len),
- fmt, lsn, tail_lsn, next, bp);
- bp->b_flags |= LIBXFS_B_DIRTY;
- libxfs_putbufr(bp);
+ libxfs_log_header(ptr, fs_uuid, version, BBTOB(len), fmt, lsn,
+ tail_lsn, next, bp);
+ if (bp) {
+ bp->b_flags |= LIBXFS_B_DIRTY;
+ libxfs_putbufr(bp);
+ }
len = min(end_blk - blk, BTOBB(BDSTRAT_SIZE));
blk += len;
+ if (dptr)
+ dptr += BBTOB(len);
}
return 0;
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 238d400..5f939b5 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2667,7 +2667,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
/*
* Zero the log....
*/
- libxfs_log_clear(mp->m_logdev_targp,
+ 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);
diff --git a/repair/phase2.c b/repair/phase2.c
index f9d0e22..cb24711 100644
--- a/repair/phase2.c
+++ b/repair/phase2.c
@@ -114,7 +114,7 @@ zero_log(
* filesystems.
*/
if (!no_modify && zap_log) {
- libxfs_log_clear(log->l_dev,
+ libxfs_log_clear(log->l_dev, NULL,
XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
(xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks),
&mp->m_sb.sb_uuid,
diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
index 8285d9d..bed2ff5 100644
--- a/repair/xfs_repair.c
+++ b/repair/xfs_repair.c
@@ -584,8 +584,9 @@ format_log_max_lsn(
}
do_warn(_("Format log to cycle %d.\n"), new_cycle);
- libxfs_log_clear(log->l_dev, logstart, logblocks, &mp->m_sb.sb_uuid,
- logversion, mp->m_sb.sb_logsunit, XLOG_FMT, 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);
}
int
--
2.1.0
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2015-10-02 18:19 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-02 18:19 [PATCH v3 00/18] xfsprogs: format the log correctly on v5 supers Brian Foster
2015-10-02 18:19 ` [PATCH v3 01/18] libxfs: validate metadata LSNs against log on v5 superblocks Brian Foster
2015-10-02 18:19 ` [PATCH v3 02/18] libxfs: track largest metadata LSN in use via verifiers Brian Foster
2015-10-02 18:19 ` [PATCH v3 03/18] libxfs: don't hardcode cycle 1 into unmount op header Brian Foster
2015-10-02 18:19 ` [PATCH v3 04/18] libxfs: pass lsn param to log clear and record header logging helpers Brian Foster
2015-10-02 18:19 ` [PATCH v3 05/18] libxfs: add ability to clear log to arbitrary log cycle Brian Foster
2015-10-02 18:19 ` [PATCH v3 06/18] libxlog: pull struct xlog out of xlog_is_dirty() Brian Foster
2015-10-02 18:19 ` [PATCH v3 07/18] xfs_repair: track log state throughout all recovery phases Brian Foster
2015-10-02 18:19 ` [PATCH v3 08/18] xfs_repair: process the log in no_modify mode Brian Foster
2015-10-02 18:19 ` [PATCH v3 09/18] xfs_repair: format the log with forward cycle number on v5 supers Brian Foster
2015-10-02 18:19 ` [PATCH v3 10/18] xfs_repair: don't clear the log by default Brian Foster
2015-10-02 18:19 ` [PATCH v3 11/18] xfs_repair: seed the max lsn from log state in phase 2 Brian Foster
2015-10-02 18:19 ` [PATCH v3 12/18] xfs_db: do not reset current lsn from uuid command on v5 supers Brian Foster
2015-10-02 18:19 ` Brian Foster [this message]
2015-10-02 18:19 ` [PATCH v3 14/18] xfs_copy: check for dirty log on non-duplicate copies Brian Foster
2015-10-02 18:19 ` [PATCH v3 15/18] xfs_copy: genericize write helper to facilitate separate log buf Brian Foster
2015-10-02 18:19 ` [PATCH v3 16/18] xfs_copy: store data buf alignment in buf data structure Brian Foster
2015-10-02 18:19 ` [PATCH v3 17/18] xfs_copy: refactor log format code into new helper Brian Foster
2015-10-02 18:19 ` [PATCH v3 18/18] xfs_copy: format v5 sb logs correctly Brian Foster
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1443809995-20395-14-git-send-email-bfoster@redhat.com \
--to=bfoster@redhat.com \
--cc=xfs@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox