This commit adds functionality to dump metadata from an XFS filesystem in newly introduced v2 format. Signed-off-by: Chandan Babu R <chandan.babu@xxxxxxxxxx> --- db/metadump.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/db/metadump.c b/db/metadump.c index 9d7ad76ae..627436e68 100644 --- a/db/metadump.c +++ b/db/metadump.c @@ -3037,6 +3037,69 @@ static struct metadump_ops metadump1_ops = { .release_metadump = release_metadump_v1, }; +static int +init_metadump_v2(void) +{ + struct xfs_metadump_header xmh = {0}; + uint32_t compat_flags = 0; + + xmh.xmh_magic = cpu_to_be32(XFS_MD_MAGIC_V2); + xmh.xmh_version = 2; + + if (metadump.obfuscate) + compat_flags |= XFS_MD2_INCOMPAT_OBFUSCATED; + if (!metadump.zero_stale_data) + compat_flags |= XFS_MD2_INCOMPAT_FULLBLOCKS; + if (metadump.dirty_log) + compat_flags |= XFS_MD2_INCOMPAT_DIRTYLOG; + + xmh.xmh_compat_flags = cpu_to_be32(compat_flags); + + if (fwrite(&xmh, sizeof(xmh), 1, metadump.outf) != 1) { + print_warning("error writing to target file"); + return -1; + } + + return 0; +} + +static int +write_metadump_v2( + enum typnm type, + char *data, + int64_t off, + int len) +{ + struct xfs_meta_extent xme; + uint64_t addr; + + addr = off; + if (type == TYP_ELOG) + addr |= XME_ADDR_LOG_DEVICE; + else + addr |= XME_ADDR_DATA_DEVICE; + + xme.xme_addr = cpu_to_be64(addr); + xme.xme_len = cpu_to_be32(len); + + if (fwrite(&xme, sizeof(xme), 1, metadump.outf) != 1) { + print_warning("error writing to target file"); + return -EIO; + } + + if (fwrite(data, len << BBSHIFT, 1, metadump.outf) != 1) { + print_warning("error writing to target file"); + return -EIO; + } + + return 0; +} + +static struct metadump_ops metadump2_ops = { + .init_metadump = init_metadump_v2, + .write_metadump = write_metadump_v2, +}; + static int metadump_f( int argc, @@ -3178,7 +3241,10 @@ metadump_f( } } - metadump.mdops = &metadump1_ops; + if (metadump.version == 1) + metadump.mdops = &metadump1_ops; + else + metadump.mdops = &metadump2_ops; ret = metadump.mdops->init_metadump(); if (ret) @@ -3203,7 +3269,7 @@ metadump_f( exitcode = !copy_log(log_type); /* write the remaining index */ - if (!exitcode) + if (!exitcode && metadump.mdops->end_write_metadump) exitcode = metadump.mdops->end_write_metadump() < 0; if (metadump.progress_since_warning) @@ -3223,7 +3289,8 @@ metadump_f( while (iocur_sp > start_iocur_sp) pop_cur(); - metadump.mdops->release_metadump(); + if (metadump.mdops->release_metadump) + metadump.mdops->release_metadump(); out: return 0; -- 2.39.1