@@ -2736,6 +2736,70 @@ static struct metadump_ops metadump1_ops = {
.release = 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 = cpu_to_be32(2);
+
+ if (metadump.obfuscate)
+ compat_flags |= XFS_MD2_COMPAT_OBFUSCATED;
+ if (!metadump.zero_stale_data)
+ compat_flags |= XFS_MD2_COMPAT_FULLBLOCKS;
+ if (metadump.dirty_log)
+ compat_flags |= XFS_MD2_COMPAT_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,
+ const char *data,
+ xfs_daddr_t off,
+ int len)
+{
+ struct xfs_meta_extent xme;
+ uint64_t addr;
+
+ addr = off;
+ if (type == TYP_LOG &&
+ mp->m_logdev_targp->bt_bdev != mp->m_ddev_targp->bt_bdev)
+ 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 = init_metadump_v2,
+ .write = write_metadump_v2,
+};
+
static int
metadump_f(
int argc,
@@ -2872,7 +2936,10 @@ metadump_f(
}
}
- metadump.mdops = &metadump1_ops;
+ if (metadump.version == 1)
+ metadump.mdops = &metadump1_ops;
+ else
+ metadump.mdops = &metadump2_ops;
ret = metadump.mdops->init();
if (ret)
@@ -2896,7 +2963,7 @@ metadump_f(
exitcode = !copy_log();
/* write the remaining index */
- if (!exitcode)
+ if (!exitcode && metadump.mdops->finish_dump)
exitcode = metadump.mdops->finish_dump() < 0;
if (metadump.progress_since_warning)
@@ -2916,7 +2983,8 @@ metadump_f(
while (iocur_sp > start_iocur_sp)
pop_cur();
- metadump.mdops->release();
+ if (metadump.mdops->release)
+ metadump.mdops->release();
out:
return 0;