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