Blame SOURCES/xfsprogs-5.0.0-xfs_db-metadump-should-handle-symlinks-properly.patch

3d5736
From 0e81250e5125dc664e1938288e47ff52b1cacbe4 Mon Sep 17 00:00:00 2001
3d5736
From: "Darrick J. Wong" <darrick.wong@oracle.com>
3d5736
Date: Fri, 26 Apr 2019 15:40:28 -0500
3d5736
Subject: [PATCH] xfs_db: metadump should handle symlinks properly
3d5736
3d5736
Remote symlink target blocks are multi-fsb objects on XFS v5 filesystems
3d5736
because we only write one rmt header per data fork extent.  For fs
3d5736
blocksize >= 2048 we never have more than one block and therefore nobody
3d5736
noticed, but for blocksize == 1024 this is definitely not true and leads
3d5736
to metadump spraying error messages about symlink block crc errors.
3d5736
Therefore, reformulate the symlink metadump into a multi-fsb dump
3d5736
function.
3d5736
3d5736
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
3d5736
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
3d5736
[sandeen: shrink the map declaration]
3d5736
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
3d5736
---
3d5736
 db/metadump.c | 43 ++++++++++++++++++++++++++++++++++++-------
3d5736
 1 file changed, 36 insertions(+), 7 deletions(-)
3d5736
3d5736
Index: xfsprogs-4.5.0/db/metadump.c
3d5736
===================================================================
3d5736
--- xfsprogs-4.5.0.orig/db/metadump.c
3d5736
+++ xfsprogs-4.5.0/db/metadump.c
3d5736
@@ -1425,11 +1425,34 @@ process_dir_data_block(
3d5736
 	}
3d5736
 }
3d5736
 
3d5736
-static void
3d5736
+static int
3d5736
 process_symlink_block(
3d5736
-	char			*block)
3d5736
+	xfs_fileoff_t	o,
3d5736
+	xfs_fsblock_t	s,
3d5736
+	xfs_filblks_t	c,
3d5736
+	typnm_t		btype,
3d5736
+	xfs_fileoff_t	last)
3d5736
 {
3d5736
-	char *link = block;
3d5736
+	struct bbmap	map;
3d5736
+	char		*link;
3d5736
+	int		ret = 0;
3d5736
+
3d5736
+	push_cur();
3d5736
+	map.nmaps = 1;
3d5736
+	map.b[0].bm_bn = XFS_FSB_TO_DADDR(mp, s);
3d5736
+	map.b[0].bm_len = XFS_FSB_TO_BB(mp, c);
3d5736
+	set_cur(&typtab[btype], 0, 0, DB_RING_IGN, &map);
3d5736
+	if (!iocur_top->data) {
3d5736
+		xfs_agnumber_t	agno = XFS_FSB_TO_AGNO(mp, s);
3d5736
+		xfs_agblock_t	agbno = XFS_FSB_TO_AGBNO(mp, s);
3d5736
+
3d5736
+		print_warning("cannot read %s block %u/%u (%llu)",
3d5736
+				typtab[btype].name, agno, agbno, s);
3d5736
+		if (stop_on_read_error)
3d5736
+			ret = -1;
3d5736
+		goto out_pop;
3d5736
+	}
3d5736
+	link = iocur_top->data;
3d5736
 
3d5736
 	if (xfs_sb_version_hascrc(&(mp)->m_sb))
3d5736
 		link += sizeof(struct xfs_dsymlink_hdr);
3d5736
@@ -1447,6 +1470,12 @@ process_symlink_block(
3d5736
 		if (zlen < mp->m_sb.sb_blocksize)
3d5736
 			memset(link + linklen, 0, zlen);
3d5736
 	}
3d5736
+
3d5736
+	iocur_top->need_crc = 1;
3d5736
+	ret = write_buf(iocur_top);
3d5736
+out_pop:
3d5736
+	pop_cur();
3d5736
+	return ret;
3d5736
 }
3d5736
 
3d5736
 #define MAX_REMOTE_VALS		4095
3d5736
@@ -1663,10 +1692,6 @@ process_single_fsb_objects(
3d5736
 					 last == mp->m_dir_geo->fsbcount);
3d5736
 			iocur_top->need_crc = 1;
3d5736
 			break;
3d5736
-		case TYP_SYMLINK:
3d5736
-			process_symlink_block(dp);
3d5736
-			iocur_top->need_crc = 1;
3d5736
-			break;
3d5736
 		case TYP_ATTR:
3d5736
 			process_attr_block(dp, o);
3d5736
 			iocur_top->need_crc = 1;
3d5736
@@ -1764,6 +1789,8 @@ is_multi_fsb_object(
3d5736
 {
3d5736
 	if (btype == TYP_DIR2 && mp->m_dir_geo->fsbcount > 1)
3d5736
 		return true;
3d5736
+	if (btype == TYP_SYMLINK)
3d5736
+		return true;
3d5736
 	return false;
3d5736
 }
3d5736
 
3d5736
@@ -1778,6 +1805,8 @@ process_multi_fsb_objects(
3d5736
 	switch (btype) {
3d5736
 	case TYP_DIR2:
3d5736
 		return process_multi_fsb_dir(o, s, c, btype, last);
3d5736
+	case TYP_SYMLINK:
3d5736
+		return process_symlink_block(o, s, c, btype, last);
3d5736
 	default:
3d5736
 		print_warning("bad type for multi-fsb object %d", btype);
3d5736
 		return -EINVAL;