diff mbox series

[35/50] xfs_mdrestore: restore rt group superblocks to realtime device

Message ID 173405323720.1228937.8741858826144010013.stgit@frogsfrogsfrogs (mailing list archive)
State New
Headers show
Series None | expand

Commit Message

Darrick J. Wong Dec. 13, 2024, 1:29 a.m. UTC
From: Darrick J. Wong <djwong@kernel.org>

Support restoring realtime device metadata to the realtime device, if
the dumped filesystem had one.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
 man/man8/xfs_mdrestore.8  |   10 ++++++++++
 mdrestore/xfs_mdrestore.c |   47 ++++++++++++++++++++++++++++++++++++---------
 2 files changed, 48 insertions(+), 9 deletions(-)

Comments

Andrey Albershteyn Dec. 20, 2024, 2:38 p.m. UTC | #1
On 2024-12-12 17:29:22, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Support restoring realtime device metadata to the realtime device, if
> the dumped filesystem had one.
> 
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>

LGTM
Reviewed-by: Andrey Albershteyn <aalbersh@kernel.org>

> ---
>  man/man8/xfs_mdrestore.8  |   10 ++++++++++
>  mdrestore/xfs_mdrestore.c |   47 ++++++++++++++++++++++++++++++++++++---------
>  2 files changed, 48 insertions(+), 9 deletions(-)
> 
> 
> diff --git a/man/man8/xfs_mdrestore.8 b/man/man8/xfs_mdrestore.8
> index f60e7b56ebf0d1..6f6e14e96c6a5c 100644
> --- a/man/man8/xfs_mdrestore.8
> +++ b/man/man8/xfs_mdrestore.8
> @@ -8,6 +8,9 @@ .SH SYNOPSIS
>  ] [
>  .B \-l
>  .I logdev
> +] [
> +.B \-r
> +.I rtdev
>  ]
>  .I source
>  .I target
> @@ -17,6 +20,9 @@ .SH SYNOPSIS
>  [
>  .B \-l
>  .I logdev
> +] [
> +.B \-r
> +.I rtdev
>  ]
>  .I source
>  .br
> @@ -61,6 +67,10 @@ .SH OPTIONS
>  In such a scenario, the user has to provide a device to which the log device
>  contents from the metadump file are copied.
>  .TP
> +.BI \-r " rtdev"
> +Restore realtime device metadata to this device.
> +This is only required for a metadump in v2 format.
> +.TP
>  .B \-V
>  Prints the version number and exits.
>  .SH DIAGNOSTICS
> diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
> index c5584fec68813e..d5014981b15a68 100644
> --- a/mdrestore/xfs_mdrestore.c
> +++ b/mdrestore/xfs_mdrestore.c
> @@ -28,7 +28,8 @@ struct mdrestore_ops {
>  	void (*show_info)(union mdrestore_headers *header, const char *md_file);
>  	void (*restore)(union mdrestore_headers *header, FILE *md_fp,
>  			const struct mdrestore_dev *ddev,
> -			const struct mdrestore_dev *logdev);
> +			const struct mdrestore_dev *logdev,
> +			const struct mdrestore_dev *rtdev);
>  };
>  
>  static struct mdrestore {
> @@ -37,6 +38,7 @@ static struct mdrestore {
>  	bool			show_info;
>  	bool			progress_since_warning;
>  	bool			external_log;
> +	bool			realtime_data;
>  } mdrestore;
>  
>  static void
> @@ -212,7 +214,8 @@ restore_v1(
>  	union mdrestore_headers		*h,
>  	FILE				*md_fp,
>  	const struct mdrestore_dev	*ddev,
> -	const struct mdrestore_dev	*logdev)
> +	const struct mdrestore_dev	*logdev,
> +	const struct mdrestore_dev	*rtdev)
>  {
>  	struct xfs_metablock	*metablock;	/* header + index + blocks */
>  	__be64			*block_index;
> @@ -336,8 +339,9 @@ read_header_v2(
>  	if (!mdrestore.external_log && (compat & XFS_MD2_COMPAT_EXTERNALLOG))
>  		fatal("External Log device is required\n");
>  
> -	if (h->v2.xmh_incompat_flags & cpu_to_be32(XFS_MD2_INCOMPAT_RTDEVICE))
> -		fatal("Realtime device not yet supported\n");
> +	if ((h->v2.xmh_incompat_flags & cpu_to_be32(XFS_MD2_INCOMPAT_RTDEVICE)) &&
> +	    !mdrestore.realtime_data)
> +		fatal("Realtime device is required\n");
>  }
>  
>  static void
> @@ -346,14 +350,17 @@ show_info_v2(
>  	const char		*md_file)
>  {
>  	uint32_t		compat_flags;
> +	uint32_t		incompat_flags;
>  
>  	compat_flags = be32_to_cpu(h->v2.xmh_compat_flags);
> +	incompat_flags = be32_to_cpu(h->v2.xmh_incompat_flags);
>  
> -	printf("%s: %sobfuscated, %s log, external log contents are %sdumped, %s metadata blocks,\n",
> +	printf("%s: %sobfuscated, %s log, external log contents are %sdumped, rt device contents are %sdumped, %s metadata blocks,\n",
>  		md_file,
>  		compat_flags & XFS_MD2_COMPAT_OBFUSCATED ? "":"not ",
>  		compat_flags & XFS_MD2_COMPAT_DIRTYLOG ? "dirty":"clean",
>  		compat_flags & XFS_MD2_COMPAT_EXTERNALLOG ? "":"not ",
> +		incompat_flags & XFS_MD2_INCOMPAT_RTDEVICE ? "":"not ",
>  		compat_flags & XFS_MD2_COMPAT_FULLBLOCKS ? "full":"zeroed");
>  }
>  
> @@ -390,7 +397,8 @@ restore_v2(
>  	union mdrestore_headers		*h,
>  	FILE				*md_fp,
>  	const struct mdrestore_dev	*ddev,
> -	const struct mdrestore_dev	*logdev)
> +	const struct mdrestore_dev	*logdev,
> +	const struct mdrestore_dev	*rtdev)
>  {
>  	struct xfs_sb		sb;
>  	struct xfs_meta_extent	xme;
> @@ -431,6 +439,11 @@ restore_v2(
>  		verify_device_size(logdev, sb.sb_logblocks, sb.sb_blocksize);
>  	}
>  
> +	if (sb.sb_rblocks > 0) {
> +		ASSERT(mdrestore.realtime_data == true);
> +		verify_device_size(rtdev, sb.sb_rblocks, sb.sb_blocksize);
> +	}
> +
>  	if (pwrite(ddev->fd, block_buffer, len, 0) < 0)
>  		fatal("error writing primary superblock: %s\n",
>  			strerror(errno));
> @@ -459,6 +472,10 @@ restore_v2(
>  			device = "log";
>  			fd = logdev->fd;
>  			break;
> +		case XME_ADDR_RT_DEVICE:
> +			device = "rt";
> +			fd = rtdev->fd;
> +			break;
>  		default:
>  			fatal("Invalid device found in metadump\n");
>  			break;
> @@ -488,7 +505,7 @@ static struct mdrestore_ops mdrestore_ops_v2 = {
>  static void
>  usage(void)
>  {
> -	fprintf(stderr, "Usage: %s [-V] [-g] [-i] [-l logdev] source target\n",
> +	fprintf(stderr, "Usage: %s [-V] [-g] [-i] [-l logdev] [-r rtdev] source target\n",
>  		progname);
>  	exit(1);
>  }
> @@ -501,18 +518,21 @@ main(
>  	union mdrestore_headers	headers;
>  	DEFINE_MDRESTORE_DEV(ddev);
>  	DEFINE_MDRESTORE_DEV(logdev);
> +	DEFINE_MDRESTORE_DEV(rtdev);
>  	FILE			*src_f;
>  	char			*logdev_path = NULL;
> +	char			*rtdev_path = NULL;
>  	int			c;
>  
>  	mdrestore.show_progress = false;
>  	mdrestore.show_info = false;
>  	mdrestore.progress_since_warning = false;
>  	mdrestore.external_log = false;
> +	mdrestore.realtime_data = false;
>  
>  	progname = basename(argv[0]);
>  
> -	while ((c = getopt(argc, argv, "gil:V")) != EOF) {
> +	while ((c = getopt(argc, argv, "gil:r:V")) != EOF) {
>  		switch (c) {
>  			case 'g':
>  				mdrestore.show_progress = true;
> @@ -524,6 +544,10 @@ main(
>  				logdev_path = optarg;
>  				mdrestore.external_log = true;
>  				break;
> +			case 'r':
> +				rtdev_path = optarg;
> +				mdrestore.realtime_data = true;
> +				break;
>  			case 'V':
>  				printf("%s version %s\n", progname, VERSION);
>  				exit(0);
> @@ -592,10 +616,15 @@ main(
>  	if (mdrestore.external_log)
>  		open_device(&logdev, logdev_path);
>  
> -	mdrestore.mdrops->restore(&headers, src_f, &ddev, &logdev);
> +	/* check and open realtime device */
> +	if (mdrestore.realtime_data)
> +		open_device(&rtdev, rtdev_path);
> +
> +	mdrestore.mdrops->restore(&headers, src_f, &ddev, &logdev, &rtdev);
>  
>  	close_device(&ddev);
>  	close_device(&logdev);
> +	close_device(&rtdev);
>  
>  	if (src_f != stdin)
>  		fclose(src_f);
>
diff mbox series

Patch

diff --git a/man/man8/xfs_mdrestore.8 b/man/man8/xfs_mdrestore.8
index f60e7b56ebf0d1..6f6e14e96c6a5c 100644
--- a/man/man8/xfs_mdrestore.8
+++ b/man/man8/xfs_mdrestore.8
@@ -8,6 +8,9 @@  .SH SYNOPSIS
 ] [
 .B \-l
 .I logdev
+] [
+.B \-r
+.I rtdev
 ]
 .I source
 .I target
@@ -17,6 +20,9 @@  .SH SYNOPSIS
 [
 .B \-l
 .I logdev
+] [
+.B \-r
+.I rtdev
 ]
 .I source
 .br
@@ -61,6 +67,10 @@  .SH OPTIONS
 In such a scenario, the user has to provide a device to which the log device
 contents from the metadump file are copied.
 .TP
+.BI \-r " rtdev"
+Restore realtime device metadata to this device.
+This is only required for a metadump in v2 format.
+.TP
 .B \-V
 Prints the version number and exits.
 .SH DIAGNOSTICS
diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
index c5584fec68813e..d5014981b15a68 100644
--- a/mdrestore/xfs_mdrestore.c
+++ b/mdrestore/xfs_mdrestore.c
@@ -28,7 +28,8 @@  struct mdrestore_ops {
 	void (*show_info)(union mdrestore_headers *header, const char *md_file);
 	void (*restore)(union mdrestore_headers *header, FILE *md_fp,
 			const struct mdrestore_dev *ddev,
-			const struct mdrestore_dev *logdev);
+			const struct mdrestore_dev *logdev,
+			const struct mdrestore_dev *rtdev);
 };
 
 static struct mdrestore {
@@ -37,6 +38,7 @@  static struct mdrestore {
 	bool			show_info;
 	bool			progress_since_warning;
 	bool			external_log;
+	bool			realtime_data;
 } mdrestore;
 
 static void
@@ -212,7 +214,8 @@  restore_v1(
 	union mdrestore_headers		*h,
 	FILE				*md_fp,
 	const struct mdrestore_dev	*ddev,
-	const struct mdrestore_dev	*logdev)
+	const struct mdrestore_dev	*logdev,
+	const struct mdrestore_dev	*rtdev)
 {
 	struct xfs_metablock	*metablock;	/* header + index + blocks */
 	__be64			*block_index;
@@ -336,8 +339,9 @@  read_header_v2(
 	if (!mdrestore.external_log && (compat & XFS_MD2_COMPAT_EXTERNALLOG))
 		fatal("External Log device is required\n");
 
-	if (h->v2.xmh_incompat_flags & cpu_to_be32(XFS_MD2_INCOMPAT_RTDEVICE))
-		fatal("Realtime device not yet supported\n");
+	if ((h->v2.xmh_incompat_flags & cpu_to_be32(XFS_MD2_INCOMPAT_RTDEVICE)) &&
+	    !mdrestore.realtime_data)
+		fatal("Realtime device is required\n");
 }
 
 static void
@@ -346,14 +350,17 @@  show_info_v2(
 	const char		*md_file)
 {
 	uint32_t		compat_flags;
+	uint32_t		incompat_flags;
 
 	compat_flags = be32_to_cpu(h->v2.xmh_compat_flags);
+	incompat_flags = be32_to_cpu(h->v2.xmh_incompat_flags);
 
-	printf("%s: %sobfuscated, %s log, external log contents are %sdumped, %s metadata blocks,\n",
+	printf("%s: %sobfuscated, %s log, external log contents are %sdumped, rt device contents are %sdumped, %s metadata blocks,\n",
 		md_file,
 		compat_flags & XFS_MD2_COMPAT_OBFUSCATED ? "":"not ",
 		compat_flags & XFS_MD2_COMPAT_DIRTYLOG ? "dirty":"clean",
 		compat_flags & XFS_MD2_COMPAT_EXTERNALLOG ? "":"not ",
+		incompat_flags & XFS_MD2_INCOMPAT_RTDEVICE ? "":"not ",
 		compat_flags & XFS_MD2_COMPAT_FULLBLOCKS ? "full":"zeroed");
 }
 
@@ -390,7 +397,8 @@  restore_v2(
 	union mdrestore_headers		*h,
 	FILE				*md_fp,
 	const struct mdrestore_dev	*ddev,
-	const struct mdrestore_dev	*logdev)
+	const struct mdrestore_dev	*logdev,
+	const struct mdrestore_dev	*rtdev)
 {
 	struct xfs_sb		sb;
 	struct xfs_meta_extent	xme;
@@ -431,6 +439,11 @@  restore_v2(
 		verify_device_size(logdev, sb.sb_logblocks, sb.sb_blocksize);
 	}
 
+	if (sb.sb_rblocks > 0) {
+		ASSERT(mdrestore.realtime_data == true);
+		verify_device_size(rtdev, sb.sb_rblocks, sb.sb_blocksize);
+	}
+
 	if (pwrite(ddev->fd, block_buffer, len, 0) < 0)
 		fatal("error writing primary superblock: %s\n",
 			strerror(errno));
@@ -459,6 +472,10 @@  restore_v2(
 			device = "log";
 			fd = logdev->fd;
 			break;
+		case XME_ADDR_RT_DEVICE:
+			device = "rt";
+			fd = rtdev->fd;
+			break;
 		default:
 			fatal("Invalid device found in metadump\n");
 			break;
@@ -488,7 +505,7 @@  static struct mdrestore_ops mdrestore_ops_v2 = {
 static void
 usage(void)
 {
-	fprintf(stderr, "Usage: %s [-V] [-g] [-i] [-l logdev] source target\n",
+	fprintf(stderr, "Usage: %s [-V] [-g] [-i] [-l logdev] [-r rtdev] source target\n",
 		progname);
 	exit(1);
 }
@@ -501,18 +518,21 @@  main(
 	union mdrestore_headers	headers;
 	DEFINE_MDRESTORE_DEV(ddev);
 	DEFINE_MDRESTORE_DEV(logdev);
+	DEFINE_MDRESTORE_DEV(rtdev);
 	FILE			*src_f;
 	char			*logdev_path = NULL;
+	char			*rtdev_path = NULL;
 	int			c;
 
 	mdrestore.show_progress = false;
 	mdrestore.show_info = false;
 	mdrestore.progress_since_warning = false;
 	mdrestore.external_log = false;
+	mdrestore.realtime_data = false;
 
 	progname = basename(argv[0]);
 
-	while ((c = getopt(argc, argv, "gil:V")) != EOF) {
+	while ((c = getopt(argc, argv, "gil:r:V")) != EOF) {
 		switch (c) {
 			case 'g':
 				mdrestore.show_progress = true;
@@ -524,6 +544,10 @@  main(
 				logdev_path = optarg;
 				mdrestore.external_log = true;
 				break;
+			case 'r':
+				rtdev_path = optarg;
+				mdrestore.realtime_data = true;
+				break;
 			case 'V':
 				printf("%s version %s\n", progname, VERSION);
 				exit(0);
@@ -592,10 +616,15 @@  main(
 	if (mdrestore.external_log)
 		open_device(&logdev, logdev_path);
 
-	mdrestore.mdrops->restore(&headers, src_f, &ddev, &logdev);
+	/* check and open realtime device */
+	if (mdrestore.realtime_data)
+		open_device(&rtdev, rtdev_path);
+
+	mdrestore.mdrops->restore(&headers, src_f, &ddev, &logdev, &rtdev);
 
 	close_device(&ddev);
 	close_device(&logdev);
+	close_device(&rtdev);
 
 	if (src_f != stdin)
 		fclose(src_f);