* [PATCH V3 01/23] metadump: Use boolean values true/false instead of 1/0
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 02/23] mdrestore: Fix logic used to check if target device is large enough Chandan Babu R
` (22 subsequent siblings)
23 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
db/metadump.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/db/metadump.c b/db/metadump.c
index 27d1df43..6bcfd5bb 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -2421,12 +2421,12 @@ process_inode(
case S_IFDIR:
rval = process_inode_data(dip, TYP_DIR2);
if (dip->di_format == XFS_DINODE_FMT_LOCAL)
- need_new_crc = 1;
+ need_new_crc = true;
break;
case S_IFLNK:
rval = process_inode_data(dip, TYP_SYMLINK);
if (dip->di_format == XFS_DINODE_FMT_LOCAL)
- need_new_crc = 1;
+ need_new_crc = true;
break;
case S_IFREG:
rval = process_inode_data(dip, TYP_DATA);
@@ -2436,7 +2436,7 @@ process_inode(
case S_IFBLK:
case S_IFSOCK:
process_dev_inode(dip);
- need_new_crc = 1;
+ need_new_crc = true;
break;
default:
break;
@@ -2450,7 +2450,7 @@ process_inode(
attr_data.remote_val_count = 0;
switch (dip->di_aformat) {
case XFS_DINODE_FMT_LOCAL:
- need_new_crc = 1;
+ need_new_crc = true;
if (obfuscate || zero_stale_data)
process_sf_attr(dip);
break;
@@ -2469,7 +2469,7 @@ process_inode(
done:
/* Heavy handed but low cost; just do it as a catch-all. */
if (zero_stale_data)
- need_new_crc = 1;
+ need_new_crc = true;
if (crc_was_ok && need_new_crc)
libxfs_dinode_calc_crc(mp, dip);
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH V3 02/23] mdrestore: Fix logic used to check if target device is large enough
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 01/23] metadump: Use boolean values true/false instead of 1/0 Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 03/23] metadump: Declare boolean variables with bool type Chandan Babu R
` (21 subsequent siblings)
23 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
The device size verification code should be writing XFS_MAX_SECTORSIZE bytes
to the end of the device rather than "sizeof(char *) * XFS_MAX_SECTORSIZE"
bytes.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
mdrestore/xfs_mdrestore.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
index 7c1a66c4..333282ed 100644
--- a/mdrestore/xfs_mdrestore.c
+++ b/mdrestore/xfs_mdrestore.c
@@ -115,7 +115,7 @@ perform_restore(
} else {
/* ensure device is sufficiently large enough */
- char *lb[XFS_MAX_SECTORSIZE] = { NULL };
+ char lb[XFS_MAX_SECTORSIZE] = { 0 };
off64_t off;
off = sb.sb_dblocks * sb.sb_blocksize - sizeof(lb);
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH V3 03/23] metadump: Declare boolean variables with bool type
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 01/23] metadump: Use boolean values true/false instead of 1/0 Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 02/23] mdrestore: Fix logic used to check if target device is large enough Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 04/23] metadump: Define and use struct metadump Chandan Babu R
` (20 subsequent siblings)
23 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
db/metadump.c | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/db/metadump.c b/db/metadump.c
index 6bcfd5bb..8b33fbfb 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -51,13 +51,13 @@ static int cur_index;
static xfs_ino_t cur_ino;
-static int show_progress = 0;
-static int stop_on_read_error = 0;
+static bool show_progress = false;
+static bool stop_on_read_error = false;
static int max_extent_size = DEFAULT_MAX_EXT_SIZE;
-static int obfuscate = 1;
-static int zero_stale_data = 1;
-static int show_warnings = 0;
-static int progress_since_warning = 0;
+static bool obfuscate = true;
+static bool zero_stale_data = true;
+static bool show_warnings = false;
+static bool progress_since_warning = false;
static bool stdout_metadump;
void
@@ -100,7 +100,7 @@ print_warning(const char *fmt, ...)
fprintf(stderr, "%s%s: %s\n", progress_since_warning ? "\n" : "",
progname, buf);
- progress_since_warning = 0;
+ progress_since_warning = false;
}
static void
@@ -121,7 +121,7 @@ print_progress(const char *fmt, ...)
f = stdout_metadump ? stderr : stdout;
fprintf(f, "\r%-59s", buf);
fflush(f);
- progress_since_warning = 1;
+ progress_since_warning = true;
}
/*
@@ -2979,9 +2979,9 @@ metadump_f(
char *p;
exitcode = 1;
- show_progress = 0;
- show_warnings = 0;
- stop_on_read_error = 0;
+ show_progress = false;
+ show_warnings = false;
+ stop_on_read_error = false;
if (mp->m_sb.sb_magicnum != XFS_SB_MAGIC) {
print_warning("bad superblock magic number %x, giving up",
@@ -3002,13 +3002,13 @@ metadump_f(
while ((c = getopt(argc, argv, "aegm:ow")) != EOF) {
switch (c) {
case 'a':
- zero_stale_data = 0;
+ zero_stale_data = false;
break;
case 'e':
- stop_on_read_error = 1;
+ stop_on_read_error = true;
break;
case 'g':
- show_progress = 1;
+ show_progress = true;
break;
case 'm':
max_extent_size = (int)strtol(optarg, &p, 0);
@@ -3019,10 +3019,10 @@ metadump_f(
}
break;
case 'o':
- obfuscate = 0;
+ obfuscate = false;
break;
case 'w':
- show_warnings = 1;
+ show_warnings = true;
break;
default:
print_warning("bad option for metadump command");
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH V3 04/23] metadump: Define and use struct metadump
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (2 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 03/23] metadump: Declare boolean variables with bool type Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 05/23] metadump: Add initialization and release functions Chandan Babu R
` (19 subsequent siblings)
23 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem, Carlos Maiolino
This commit collects all state tracking variables in a new "struct metadump"
structure. This is done to collect all the global variables in one place
rather than having them spread across the file. A new structure member of type
"struct metadump_ops *" will be added by a future commit to support the two
versions of metadump.
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
db/metadump.c | 458 +++++++++++++++++++++++++++-----------------------
1 file changed, 244 insertions(+), 214 deletions(-)
diff --git a/db/metadump.c b/db/metadump.c
index 8b33fbfb..c24947ec 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -40,25 +40,27 @@ static const cmdinfo_t metadump_cmd =
N_("[-a] [-e] [-g] [-m max_extent] [-w] [-o] filename"),
N_("dump metadata to a file"), metadump_help };
-static FILE *outf; /* metadump file */
-
-static xfs_metablock_t *metablock; /* header + index + buffers */
-static __be64 *block_index;
-static char *block_buffer;
-
-static int num_indices;
-static int cur_index;
-
-static xfs_ino_t cur_ino;
-
-static bool show_progress = false;
-static bool stop_on_read_error = false;
-static int max_extent_size = DEFAULT_MAX_EXT_SIZE;
-static bool obfuscate = true;
-static bool zero_stale_data = true;
-static bool show_warnings = false;
-static bool progress_since_warning = false;
-static bool stdout_metadump;
+static struct metadump {
+ int version;
+ bool show_progress;
+ bool stop_on_read_error;
+ int max_extent_size;
+ bool show_warnings;
+ bool obfuscate;
+ bool zero_stale_data;
+ bool progress_since_warning;
+ bool dirty_log;
+ bool stdout_metadump;
+ xfs_ino_t cur_ino;
+ /* Metadump file */
+ FILE *outf;
+ /* header + index + buffers */
+ struct xfs_metablock *metablock;
+ __be64 *block_index;
+ char *block_buffer;
+ int num_indices;
+ int cur_index;
+} metadump;
void
metadump_init(void)
@@ -98,9 +100,10 @@ print_warning(const char *fmt, ...)
va_end(ap);
buf[sizeof(buf)-1] = '\0';
- fprintf(stderr, "%s%s: %s\n", progress_since_warning ? "\n" : "",
+ fprintf(stderr, "%s%s: %s\n",
+ metadump.progress_since_warning ? "\n" : "",
progname, buf);
- progress_since_warning = false;
+ metadump.progress_since_warning = false;
}
static void
@@ -118,10 +121,10 @@ print_progress(const char *fmt, ...)
va_end(ap);
buf[sizeof(buf)-1] = '\0';
- f = stdout_metadump ? stderr : stdout;
+ f = metadump.stdout_metadump ? stderr : stdout;
fprintf(f, "\r%-59s", buf);
fflush(f);
- progress_since_warning = true;
+ metadump.progress_since_warning = true;
}
/*
@@ -136,17 +139,19 @@ print_progress(const char *fmt, ...)
static int
write_index(void)
{
+ struct xfs_metablock *metablock = metadump.metablock;
/*
* write index block and following data blocks (streaming)
*/
- metablock->mb_count = cpu_to_be16(cur_index);
- if (fwrite(metablock, (cur_index + 1) << BBSHIFT, 1, outf) != 1) {
+ metablock->mb_count = cpu_to_be16(metadump.cur_index);
+ if (fwrite(metablock, (metadump.cur_index + 1) << BBSHIFT, 1,
+ metadump.outf) != 1) {
print_warning("error writing to target file");
return -1;
}
- memset(block_index, 0, num_indices * sizeof(__be64));
- cur_index = 0;
+ memset(metadump.block_index, 0, metadump.num_indices * sizeof(__be64));
+ metadump.cur_index = 0;
return 0;
}
@@ -163,9 +168,10 @@ write_buf_segment(
int ret;
for (i = 0; i < len; i++, off++, data += BBSIZE) {
- block_index[cur_index] = cpu_to_be64(off);
- memcpy(&block_buffer[cur_index << BBSHIFT], data, BBSIZE);
- if (++cur_index == num_indices) {
+ metadump.block_index[metadump.cur_index] = cpu_to_be64(off);
+ memcpy(&metadump.block_buffer[metadump.cur_index << BBSHIFT],
+ data, BBSIZE);
+ if (++metadump.cur_index == metadump.num_indices) {
ret = write_index();
if (ret)
return -EIO;
@@ -388,11 +394,11 @@ scan_btree(
if (iocur_top->data == NULL) {
print_warning("cannot read %s block %u/%u", typtab[btype].name,
agno, agbno);
- rval = !stop_on_read_error;
+ rval = !metadump.stop_on_read_error;
goto pop_out;
}
- if (zero_stale_data) {
+ if (metadump.zero_stale_data) {
zero_btree_block(iocur_top->data, btype);
iocur_top->need_crc = 1;
}
@@ -446,7 +452,7 @@ scanfunc_freesp(
numrecs = be16_to_cpu(block->bb_numrecs);
if (numrecs > mp->m_alloc_mxr[1]) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid numrecs (%u) in %s block %u/%u",
numrecs, typtab[btype].name, agno, agbno);
return 1;
@@ -455,7 +461,7 @@ scanfunc_freesp(
pp = XFS_ALLOC_PTR_ADDR(mp, block, 1, mp->m_alloc_mxr[1]);
for (i = 0; i < numrecs; i++) {
if (!valid_bno(agno, be32_to_cpu(pp[i]))) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid block number (%u/%u) "
"in %s block %u/%u",
agno, be32_to_cpu(pp[i]),
@@ -482,13 +488,13 @@ copy_free_bno_btree(
/* validate root and levels before processing the tree */
if (root == 0 || root > mp->m_sb.sb_agblocks) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid block number (%u) in bnobt "
"root in agf %u", root, agno);
return 1;
}
if (levels > mp->m_alloc_maxlevels) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid level (%u) in bnobt root "
"in agf %u", levels, agno);
return 1;
@@ -510,13 +516,13 @@ copy_free_cnt_btree(
/* validate root and levels before processing the tree */
if (root == 0 || root > mp->m_sb.sb_agblocks) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid block number (%u) in cntbt "
"root in agf %u", root, agno);
return 1;
}
if (levels > mp->m_alloc_maxlevels) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid level (%u) in cntbt root "
"in agf %u", levels, agno);
return 1;
@@ -543,7 +549,7 @@ scanfunc_rmapbt(
numrecs = be16_to_cpu(block->bb_numrecs);
if (numrecs > mp->m_rmap_mxr[1]) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid numrecs (%u) in %s block %u/%u",
numrecs, typtab[btype].name, agno, agbno);
return 1;
@@ -552,7 +558,7 @@ scanfunc_rmapbt(
pp = XFS_RMAP_PTR_ADDR(block, 1, mp->m_rmap_mxr[1]);
for (i = 0; i < numrecs; i++) {
if (!valid_bno(agno, be32_to_cpu(pp[i]))) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid block number (%u/%u) "
"in %s block %u/%u",
agno, be32_to_cpu(pp[i]),
@@ -582,13 +588,13 @@ copy_rmap_btree(
/* validate root and levels before processing the tree */
if (root == 0 || root > mp->m_sb.sb_agblocks) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid block number (%u) in rmapbt "
"root in agf %u", root, agno);
return 1;
}
if (levels > mp->m_rmap_maxlevels) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid level (%u) in rmapbt root "
"in agf %u", levels, agno);
return 1;
@@ -615,7 +621,7 @@ scanfunc_refcntbt(
numrecs = be16_to_cpu(block->bb_numrecs);
if (numrecs > mp->m_refc_mxr[1]) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid numrecs (%u) in %s block %u/%u",
numrecs, typtab[btype].name, agno, agbno);
return 1;
@@ -624,7 +630,7 @@ scanfunc_refcntbt(
pp = XFS_REFCOUNT_PTR_ADDR(block, 1, mp->m_refc_mxr[1]);
for (i = 0; i < numrecs; i++) {
if (!valid_bno(agno, be32_to_cpu(pp[i]))) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid block number (%u/%u) "
"in %s block %u/%u",
agno, be32_to_cpu(pp[i]),
@@ -654,13 +660,13 @@ copy_refcount_btree(
/* validate root and levels before processing the tree */
if (root == 0 || root > mp->m_sb.sb_agblocks) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid block number (%u) in refcntbt "
"root in agf %u", root, agno);
return 1;
}
if (levels > mp->m_refc_maxlevels) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid level (%u) in refcntbt root "
"in agf %u", levels, agno);
return 1;
@@ -785,7 +791,8 @@ in_lost_found(
/* Record the "lost+found" inode if we haven't done so already */
ASSERT(ino != 0);
- if (!orphanage_ino && is_orphanage_dir(mp, cur_ino, namelen, name))
+ if (!orphanage_ino && is_orphanage_dir(mp, metadump.cur_ino, namelen,
+ name))
orphanage_ino = ino;
/* We don't obfuscate the "lost+found" directory itself */
@@ -795,7 +802,7 @@ in_lost_found(
/* Most files aren't in "lost+found" at all */
- if (cur_ino != orphanage_ino)
+ if (metadump.cur_ino != orphanage_ino)
return 0;
/*
@@ -1219,7 +1226,7 @@ generate_obfuscated_name(
print_warning("duplicate name for inode %llu "
"in dir inode %llu\n",
(unsigned long long) ino,
- (unsigned long long) cur_ino);
+ (unsigned long long) metadump.cur_ino);
return;
}
@@ -1229,7 +1236,7 @@ generate_obfuscated_name(
print_warning("unable to record name for inode %llu "
"in dir inode %llu\n",
(unsigned long long) ino,
- (unsigned long long) cur_ino);
+ (unsigned long long) metadump.cur_ino);
}
static void
@@ -1245,9 +1252,9 @@ process_sf_dir(
ino_dir_size = be64_to_cpu(dip->di_size);
if (ino_dir_size > XFS_DFORK_DSIZE(dip, mp)) {
ino_dir_size = XFS_DFORK_DSIZE(dip, mp);
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid size in dir inode %llu",
- (long long)cur_ino);
+ (long long)metadump.cur_ino);
}
sfep = xfs_dir2_sf_firstentry(sfp);
@@ -1261,9 +1268,9 @@ process_sf_dir(
int namelen = sfep->namelen;
if (namelen == 0) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("zero length entry in dir inode "
- "%llu", (long long)cur_ino);
+ "%llu", (long long)metadump.cur_ino);
if (i != sfp->count - 1)
break;
namelen = ino_dir_size - ((char *)&sfep->name[0] -
@@ -1271,16 +1278,17 @@ process_sf_dir(
} else if ((char *)sfep - (char *)sfp +
libxfs_dir2_sf_entsize(mp, sfp, sfep->namelen) >
ino_dir_size) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("entry length in dir inode %llu "
- "overflows space", (long long)cur_ino);
+ "overflows space",
+ (long long)metadump.cur_ino);
if (i != sfp->count - 1)
break;
namelen = ino_dir_size - ((char *)&sfep->name[0] -
(char *)sfp);
}
- if (obfuscate)
+ if (metadump.obfuscate)
generate_obfuscated_name(
libxfs_dir2_sf_get_ino(mp, sfp, sfep),
namelen, &sfep->name[0]);
@@ -1290,7 +1298,8 @@ process_sf_dir(
}
/* zero stale data in rest of space in data fork, if any */
- if (zero_stale_data && (ino_dir_size < XFS_DFORK_DSIZE(dip, mp)))
+ if (metadump.zero_stale_data &&
+ (ino_dir_size < XFS_DFORK_DSIZE(dip, mp)))
memset(sfep, 0, XFS_DFORK_DSIZE(dip, mp) - ino_dir_size);
}
@@ -1346,18 +1355,18 @@ process_sf_symlink(
len = be64_to_cpu(dip->di_size);
if (len > XFS_DFORK_DSIZE(dip, mp)) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid size (%d) in symlink inode %llu",
- len, (long long)cur_ino);
+ len, (long long)metadump.cur_ino);
len = XFS_DFORK_DSIZE(dip, mp);
}
buf = (char *)XFS_DFORK_DPTR(dip);
- if (obfuscate)
+ if (metadump.obfuscate)
obfuscate_path_components(buf, len);
/* zero stale data in rest of space in data fork, if any */
- if (zero_stale_data && len < XFS_DFORK_DSIZE(dip, mp))
+ if (metadump.zero_stale_data && len < XFS_DFORK_DSIZE(dip, mp))
memset(&buf[len], 0, XFS_DFORK_DSIZE(dip, mp) - len);
}
@@ -1382,9 +1391,9 @@ process_sf_attr(
ino_attr_size = be16_to_cpu(asfp->hdr.totsize);
if (ino_attr_size > XFS_DFORK_ASIZE(dip, mp)) {
ino_attr_size = XFS_DFORK_ASIZE(dip, mp);
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid attr size in inode %llu",
- (long long)cur_ino);
+ (long long)metadump.cur_ino);
}
asfep = &asfp->list[0];
@@ -1394,19 +1403,20 @@ process_sf_attr(
int namelen = asfep->namelen;
if (namelen == 0) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("zero length attr entry in inode "
- "%llu", (long long)cur_ino);
+ "%llu", (long long)metadump.cur_ino);
break;
} else if ((char *)asfep - (char *)asfp +
xfs_attr_sf_entsize(asfep) > ino_attr_size) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("attr entry length in inode %llu "
- "overflows space", (long long)cur_ino);
+ "overflows space",
+ (long long)metadump.cur_ino);
break;
}
- if (obfuscate) {
+ if (metadump.obfuscate) {
generate_obfuscated_name(0, asfep->namelen,
&asfep->nameval[0]);
memset(&asfep->nameval[asfep->namelen], 'v',
@@ -1418,7 +1428,8 @@ process_sf_attr(
}
/* zero stale data in rest of space in attr fork, if any */
- if (zero_stale_data && (ino_attr_size < XFS_DFORK_ASIZE(dip, mp)))
+ if (metadump.zero_stale_data &&
+ (ino_attr_size < XFS_DFORK_ASIZE(dip, mp)))
memset(asfep, 0, XFS_DFORK_ASIZE(dip, mp) - ino_attr_size);
}
@@ -1429,7 +1440,7 @@ process_dir_free_block(
struct xfs_dir2_free *free;
struct xfs_dir3_icfree_hdr freehdr;
- if (!zero_stale_data)
+ if (!metadump.zero_stale_data)
return;
free = (struct xfs_dir2_free *)block;
@@ -1451,10 +1462,10 @@ process_dir_free_block(
break;
}
default:
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid magic in dir inode %llu "
"free block",
- (unsigned long long)cur_ino);
+ (unsigned long long)metadump.cur_ino);
break;
}
}
@@ -1466,7 +1477,7 @@ process_dir_leaf_block(
struct xfs_dir2_leaf *leaf;
struct xfs_dir3_icleaf_hdr leafhdr;
- if (!zero_stale_data)
+ if (!metadump.zero_stale_data)
return;
/* Yes, this works for dir2 & dir3. Difference is padding. */
@@ -1549,10 +1560,10 @@ process_dir_data_block(
}
if (be32_to_cpu(datahdr->magic) != wantmagic) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning(
"invalid magic in dir inode %llu block %ld",
- (unsigned long long)cur_ino, (long)offset);
+ (unsigned long long)metadump.cur_ino, (long)offset);
return;
}
@@ -1572,10 +1583,10 @@ process_dir_data_block(
if (dir_offset + free_length > end_of_data ||
!free_length ||
(free_length & (XFS_DIR2_DATA_ALIGN - 1))) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning(
"invalid length for dir free space in inode %llu",
- (long long)cur_ino);
+ (long long)metadump.cur_ino);
return;
}
if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) !=
@@ -1588,7 +1599,7 @@ process_dir_data_block(
* actually at a variable offset, so zeroing &dup->tag
* is zeroing the free space in between
*/
- if (zero_stale_data) {
+ if (metadump.zero_stale_data) {
int zlen = free_length -
sizeof(xfs_dir2_data_unused_t);
@@ -1606,23 +1617,23 @@ process_dir_data_block(
if (dir_offset + length > end_of_data ||
ptr + length > endptr) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning(
"invalid length for dir entry name in inode %llu",
- (long long)cur_ino);
+ (long long)metadump.cur_ino);
return;
}
if (be16_to_cpu(*libxfs_dir2_data_entry_tag_p(mp, dep)) !=
dir_offset)
return;
- if (obfuscate)
+ if (metadump.obfuscate)
generate_obfuscated_name(be64_to_cpu(dep->inumber),
dep->namelen, &dep->name[0]);
dir_offset += length;
ptr += length;
/* Zero the unused space after name, up to the tag */
- if (zero_stale_data) {
+ if (metadump.zero_stale_data) {
/* 1 byte for ftype; don't bother with conditional */
int zlen =
(char *)libxfs_dir2_data_entry_tag_p(mp, dep) -
@@ -1658,7 +1669,7 @@ process_symlink_block(
print_warning("cannot read %s block %u/%u (%llu)",
typtab[btype].name, agno, agbno, s);
- rval = !stop_on_read_error;
+ rval = !metadump.stop_on_read_error;
goto out_pop;
}
link = iocur_top->data;
@@ -1666,10 +1677,10 @@ process_symlink_block(
if (xfs_has_crc((mp)))
link += sizeof(struct xfs_dsymlink_hdr);
- if (obfuscate)
+ if (metadump.obfuscate)
obfuscate_path_components(link, XFS_SYMLINK_BUF_SPACE(mp,
mp->m_sb.sb_blocksize));
- if (zero_stale_data) {
+ if (metadump.zero_stale_data) {
size_t linklen, zlen;
linklen = strlen(link);
@@ -1736,7 +1747,8 @@ process_attr_block(
if ((be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) &&
(be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR3_LEAF_MAGIC)) {
for (i = 0; i < attr_data.remote_val_count; i++) {
- if (obfuscate && attr_data.remote_vals[i] == offset)
+ if (metadump.obfuscate &&
+ attr_data.remote_vals[i] == offset)
/* Macros to handle both attr and attr3 */
memset(block +
(bs - XFS_ATTR3_RMT_BUF_SPACE(mp, bs)),
@@ -1753,9 +1765,9 @@ process_attr_block(
nentries * sizeof(xfs_attr_leaf_entry_t) +
xfs_attr3_leaf_hdr_size(leaf) >
XFS_ATTR3_RMT_BUF_SPACE(mp, bs)) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid attr count in inode %llu",
- (long long)cur_ino);
+ (long long)metadump.cur_ino);
return;
}
@@ -1770,22 +1782,22 @@ process_attr_block(
first_name = xfs_attr3_leaf_name(leaf, i);
if (be16_to_cpu(entry->nameidx) > mp->m_sb.sb_blocksize) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning(
"invalid attr nameidx in inode %llu",
- (long long)cur_ino);
+ (long long)metadump.cur_ino);
break;
}
if (entry->flags & XFS_ATTR_LOCAL) {
local = xfs_attr3_leaf_name_local(leaf, i);
if (local->namelen == 0) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning(
"zero length for attr name in inode %llu",
- (long long)cur_ino);
+ (long long)metadump.cur_ino);
break;
}
- if (obfuscate) {
+ if (metadump.obfuscate) {
generate_obfuscated_name(0, local->namelen,
&local->nameval[0]);
memset(&local->nameval[local->namelen], 'v',
@@ -1797,18 +1809,18 @@ process_attr_block(
zlen = xfs_attr_leaf_entsize_local(nlen, vlen) -
(sizeof(xfs_attr_leaf_name_local_t) - 1 +
nlen + vlen);
- if (zero_stale_data)
+ if (metadump.zero_stale_data)
memset(&local->nameval[nlen + vlen], 0, zlen);
} else {
remote = xfs_attr3_leaf_name_remote(leaf, i);
if (remote->namelen == 0 || remote->valueblk == 0) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning(
"invalid attr entry in inode %llu",
- (long long)cur_ino);
+ (long long)metadump.cur_ino);
break;
}
- if (obfuscate) {
+ if (metadump.obfuscate) {
generate_obfuscated_name(0, remote->namelen,
&remote->name[0]);
add_remote_vals(be32_to_cpu(remote->valueblk),
@@ -1819,13 +1831,13 @@ process_attr_block(
zlen = xfs_attr_leaf_entsize_remote(nlen) -
(sizeof(xfs_attr_leaf_name_remote_t) - 1 +
nlen);
- if (zero_stale_data)
+ if (metadump.zero_stale_data)
memset(&remote->name[nlen], 0, zlen);
}
}
/* Zero from end of entries array to the first name/val */
- if (zero_stale_data) {
+ if (metadump.zero_stale_data) {
struct xfs_attr_leaf_entry *entries;
entries = xfs_attr3_leaf_entryp(leaf);
@@ -1858,16 +1870,16 @@ process_single_fsb_objects(
print_warning("cannot read %s block %u/%u (%llu)",
typtab[btype].name, agno, agbno, s);
- rval = !stop_on_read_error;
+ rval = !metadump.stop_on_read_error;
goto out_pop;
}
- if (!obfuscate && !zero_stale_data)
+ if (!metadump.obfuscate && !metadump.zero_stale_data)
goto write;
/* Zero unused part of interior nodes */
- if (zero_stale_data) {
+ if (metadump.zero_stale_data) {
xfs_da_intnode_t *node = iocur_top->data;
int magic = be16_to_cpu(node->hdr.info.magic);
@@ -1978,12 +1990,12 @@ process_multi_fsb_dir(
print_warning("cannot read %s block %u/%u (%llu)",
typtab[btype].name, agno, agbno, s);
- rval = !stop_on_read_error;
+ rval = !metadump.stop_on_read_error;
goto out_pop;
}
- if (!obfuscate && !zero_stale_data)
+ if (!metadump.obfuscate && !metadump.zero_stale_data)
goto write;
dp = iocur_top->data;
@@ -2075,25 +2087,27 @@ process_bmbt_reclist(
* one is found, stop processing remaining extents
*/
if (i > 0 && op + cp > o) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("bmap extent %d in %s ino %llu "
"starts at %llu, previous extent "
"ended at %llu", i,
- typtab[btype].name, (long long)cur_ino,
+ typtab[btype].name,
+ (long long)metadump.cur_ino,
o, op + cp - 1);
break;
}
- if (c > max_extent_size) {
+ if (c > metadump.max_extent_size) {
/*
* since we are only processing non-data extents,
* large numbers of blocks in a metadata extent is
* extremely rare and more than likely to be corrupt.
*/
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("suspicious count %u in bmap "
"extent %d in %s ino %llu", c, i,
- typtab[btype].name, (long long)cur_ino);
+ typtab[btype].name,
+ (long long)metadump.cur_ino);
break;
}
@@ -2104,19 +2118,21 @@ process_bmbt_reclist(
agbno = XFS_FSB_TO_AGBNO(mp, s);
if (!valid_bno(agno, agbno)) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid block number %u/%u "
"(%llu) in bmap extent %d in %s ino "
"%llu", agno, agbno, s, i,
- typtab[btype].name, (long long)cur_ino);
+ typtab[btype].name,
+ (long long)metadump.cur_ino);
break;
}
if (!valid_bno(agno, agbno + c - 1)) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("bmap extent %i in %s inode %llu "
"overflows AG (end is %u/%u)", i,
- typtab[btype].name, (long long)cur_ino,
+ typtab[btype].name,
+ (long long)metadump.cur_ino,
agno, agbno + c - 1);
break;
}
@@ -2152,7 +2168,7 @@ scanfunc_bmap(
if (level == 0) {
if (nrecs > mp->m_bmap_dmxr[0]) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid numrecs (%u) in %s "
"block %u/%u", nrecs,
typtab[btype].name, agno, agbno);
@@ -2163,7 +2179,7 @@ scanfunc_bmap(
}
if (nrecs > mp->m_bmap_dmxr[1]) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid numrecs (%u) in %s block %u/%u",
nrecs, typtab[btype].name, agno, agbno);
return 1;
@@ -2178,7 +2194,7 @@ scanfunc_bmap(
if (bno == 0 || bno > mp->m_sb.sb_agblocks ||
ag > mp->m_sb.sb_agcount) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid block number (%u/%u) "
"in %s block %u/%u", ag, bno,
typtab[btype].name, agno, agbno);
@@ -2213,10 +2229,10 @@ process_btinode(
nrecs = be16_to_cpu(dib->bb_numrecs);
if (level > XFS_BM_MAXLEVELS(mp, whichfork)) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid level (%u) in inode %lld %s "
- "root", level, (long long)cur_ino,
- typtab[btype].name);
+ "root", level, (long long)metadump.cur_ino,
+ typtab[btype].name);
return 1;
}
@@ -2227,16 +2243,16 @@ process_btinode(
maxrecs = libxfs_bmdr_maxrecs(XFS_DFORK_SIZE(dip, mp, whichfork), 0);
if (nrecs > maxrecs) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid numrecs (%u) in inode %lld %s "
- "root", nrecs, (long long)cur_ino,
- typtab[btype].name);
+ "root", nrecs, (long long)metadump.cur_ino,
+ typtab[btype].name);
return 1;
}
pp = XFS_BMDR_PTR_ADDR(dib, 1, maxrecs);
- if (zero_stale_data) {
+ if (metadump.zero_stale_data) {
char *top;
/* Unused btree key space */
@@ -2257,11 +2273,11 @@ process_btinode(
if (bno == 0 || bno > mp->m_sb.sb_agblocks ||
ag > mp->m_sb.sb_agcount) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid block number (%u/%u) "
- "in inode %llu %s root", ag,
- bno, (long long)cur_ino,
- typtab[btype].name);
+ "in inode %llu %s root", ag, bno,
+ (long long)metadump.cur_ino,
+ typtab[btype].name);
continue;
}
@@ -2288,14 +2304,16 @@ process_exinode(
whichfork);
used = nex * sizeof(xfs_bmbt_rec_t);
if (nex > max_nex || used > XFS_DFORK_SIZE(dip, mp, whichfork)) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("bad number of extents %llu in inode %lld",
- (unsigned long long)nex, (long long)cur_ino);
+ (unsigned long long)nex,
+ (long long)metadump.cur_ino);
return 1;
}
/* Zero unused data fork past used extents */
- if (zero_stale_data && (used < XFS_DFORK_SIZE(dip, mp, whichfork)))
+ if (metadump.zero_stale_data &&
+ (used < XFS_DFORK_SIZE(dip, mp, whichfork)))
memset(XFS_DFORK_PTR(dip, whichfork) + used, 0,
XFS_DFORK_SIZE(dip, mp, whichfork) - used);
@@ -2311,7 +2329,7 @@ process_inode_data(
{
switch (dip->di_format) {
case XFS_DINODE_FMT_LOCAL:
- if (!(obfuscate || zero_stale_data))
+ if (!(metadump.obfuscate || metadump.zero_stale_data))
break;
/*
@@ -2323,7 +2341,7 @@ process_inode_data(
print_warning(
"Invalid data fork size (%d) in inode %llu, preserving contents!",
XFS_DFORK_DSIZE(dip, mp),
- (long long)cur_ino);
+ (long long)metadump.cur_ino);
break;
}
@@ -2355,9 +2373,9 @@ process_dev_inode(
struct xfs_dinode *dip)
{
if (xfs_dfork_data_extents(dip)) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("inode %llu has unexpected extents",
- (unsigned long long)cur_ino);
+ (unsigned long long)metadump.cur_ino);
return;
}
@@ -2369,11 +2387,11 @@ process_dev_inode(
if (XFS_DFORK_DSIZE(dip, mp) > XFS_LITINO(mp)) {
print_warning(
"Invalid data fork size (%d) in inode %llu, preserving contents!",
- XFS_DFORK_DSIZE(dip, mp), (long long)cur_ino);
+ XFS_DFORK_DSIZE(dip, mp), (long long)metadump.cur_ino);
return;
}
- if (zero_stale_data) {
+ if (metadump.zero_stale_data) {
unsigned int size = sizeof(xfs_dev_t);
memset(XFS_DFORK_DPTR(dip) + size, 0,
@@ -2399,17 +2417,17 @@ process_inode(
bool crc_was_ok = false; /* no recalc by default */
bool need_new_crc = false;
- cur_ino = XFS_AGINO_TO_INO(mp, agno, agino);
+ metadump.cur_ino = XFS_AGINO_TO_INO(mp, agno, agino);
/* we only care about crc recalculation if we will modify the inode. */
- if (obfuscate || zero_stale_data) {
+ if (metadump.obfuscate || metadump.zero_stale_data) {
crc_was_ok = libxfs_verify_cksum((char *)dip,
mp->m_sb.sb_inodesize,
offsetof(struct xfs_dinode, di_crc));
}
if (free_inode) {
- if (zero_stale_data) {
+ if (metadump.zero_stale_data) {
/* Zero all of the inode literal area */
memset(XFS_DFORK_DPTR(dip), 0, XFS_LITINO(mp));
}
@@ -2451,7 +2469,8 @@ process_inode(
switch (dip->di_aformat) {
case XFS_DINODE_FMT_LOCAL:
need_new_crc = true;
- if (obfuscate || zero_stale_data)
+ if (metadump.obfuscate ||
+ metadump.zero_stale_data)
process_sf_attr(dip);
break;
@@ -2468,7 +2487,7 @@ process_inode(
done:
/* Heavy handed but low cost; just do it as a catch-all. */
- if (zero_stale_data)
+ if (metadump.zero_stale_data)
need_new_crc = true;
if (crc_was_ok && need_new_crc)
@@ -2528,7 +2547,7 @@ copy_inode_chunk(
if (agino == 0 || agino == NULLAGINO || !valid_bno(agno, agbno) ||
!valid_bno(agno, XFS_AGINO_TO_AGBNO(mp,
agino + XFS_INODES_PER_CHUNK - 1))) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("bad inode number %llu (%u/%u)",
XFS_AGINO_TO_INO(mp, agno, agino), agno, agino);
return 1;
@@ -2544,7 +2563,7 @@ copy_inode_chunk(
(xfs_has_align(mp) &&
mp->m_sb.sb_inoalignmt != 0 &&
agbno % mp->m_sb.sb_inoalignmt != 0)) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("badly aligned inode (start = %llu)",
XFS_AGINO_TO_INO(mp, agno, agino));
return 1;
@@ -2561,7 +2580,7 @@ copy_inode_chunk(
if (iocur_top->data == NULL) {
print_warning("cannot read inode block %u/%u",
agno, agbno);
- rval = !stop_on_read_error;
+ rval = !metadump.stop_on_read_error;
goto pop_out;
}
@@ -2587,7 +2606,7 @@ next_bp:
ioff += inodes_per_buf;
}
- if (show_progress)
+ if (metadump.show_progress)
print_progress("Copied %u of %u inodes (%u of %u AGs)",
inodes_copied, mp->m_sb.sb_icount, agno,
mp->m_sb.sb_agcount);
@@ -2617,7 +2636,7 @@ scanfunc_ino(
if (level == 0) {
if (numrecs > igeo->inobt_mxr[0]) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid numrecs %d in %s "
"block %u/%u", numrecs,
typtab[btype].name, agno, agbno);
@@ -2640,7 +2659,7 @@ scanfunc_ino(
}
if (numrecs > igeo->inobt_mxr[1]) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid numrecs %d in %s block %u/%u",
numrecs, typtab[btype].name, agno, agbno);
numrecs = igeo->inobt_mxr[1];
@@ -2649,7 +2668,7 @@ scanfunc_ino(
pp = XFS_INOBT_PTR_ADDR(mp, block, 1, igeo->inobt_mxr[1]);
for (i = 0; i < numrecs; i++) {
if (!valid_bno(agno, be32_to_cpu(pp[i]))) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid block number (%u/%u) "
"in %s block %u/%u",
agno, be32_to_cpu(pp[i]),
@@ -2677,13 +2696,13 @@ copy_inodes(
/* validate root and levels before processing the tree */
if (root == 0 || root > mp->m_sb.sb_agblocks) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid block number (%u) in inobt "
"root in agi %u", root, agno);
return 1;
}
if (levels > M_IGEO(mp)->inobt_maxlevels) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid level (%u) in inobt root "
"in agi %u", levels, agno);
return 1;
@@ -2697,7 +2716,7 @@ copy_inodes(
levels = be32_to_cpu(agi->agi_free_level);
if (root == 0 || root > mp->m_sb.sb_agblocks) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid block number (%u) in "
"finobt root in agi %u", root,
agno);
@@ -2705,7 +2724,7 @@ copy_inodes(
}
if (levels > M_IGEO(mp)->inobt_maxlevels) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid level (%u) in finobt "
"root in agi %u", levels, agno);
return 1;
@@ -2736,11 +2755,11 @@ scan_ag(
XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL);
if (!iocur_top->data) {
print_warning("cannot read superblock for ag %u", agno);
- if (stop_on_read_error)
+ if (metadump.stop_on_read_error)
goto pop_out;
} else {
/* Replace any filesystem label with "L's" */
- if (obfuscate) {
+ if (metadump.obfuscate) {
struct xfs_sb *sb = iocur_top->data;
memset(sb->sb_fname, 'L',
min(strlen(sb->sb_fname), sizeof(sb->sb_fname)));
@@ -2758,7 +2777,7 @@ scan_ag(
agf = iocur_top->data;
if (iocur_top->data == NULL) {
print_warning("cannot read agf block for ag %u", agno);
- if (stop_on_read_error)
+ if (metadump.stop_on_read_error)
goto pop_out;
} else {
if (write_buf(iocur_top))
@@ -2773,7 +2792,7 @@ scan_ag(
agi = iocur_top->data;
if (iocur_top->data == NULL) {
print_warning("cannot read agi block for ag %u", agno);
- if (stop_on_read_error)
+ if (metadump.stop_on_read_error)
goto pop_out;
} else {
if (write_buf(iocur_top))
@@ -2787,10 +2806,10 @@ scan_ag(
XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL);
if (iocur_top->data == NULL) {
print_warning("cannot read agfl block for ag %u", agno);
- if (stop_on_read_error)
+ if (metadump.stop_on_read_error)
goto pop_out;
} else {
- if (agf && zero_stale_data) {
+ if (agf && metadump.zero_stale_data) {
/* Zero out unused bits of agfl */
int i;
__be32 *agfl_bno;
@@ -2813,7 +2832,7 @@ scan_ag(
/* copy AG free space btrees */
if (agf) {
- if (show_progress)
+ if (metadump.show_progress)
print_progress("Copying free space trees of AG %u",
agno);
if (!copy_free_bno_btree(agno, agf))
@@ -2859,7 +2878,7 @@ copy_ino(
if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
offset >= mp->m_sb.sb_inopblock) {
- if (show_warnings)
+ if (metadump.show_warnings)
print_warning("invalid %s inode number (%lld)",
typtab[itype].name, (long long)ino);
return 1;
@@ -2871,12 +2890,12 @@ copy_ino(
if (iocur_top->data == NULL) {
print_warning("cannot read %s inode %lld",
typtab[itype].name, (long long)ino);
- rval = !stop_on_read_error;
+ rval = !metadump.stop_on_read_error;
goto pop_out;
}
off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize);
- cur_ino = ino;
+ metadump.cur_ino = ino;
rval = process_inode_data(iocur_top->data, itype);
pop_out:
pop_cur();
@@ -2912,7 +2931,7 @@ copy_log(void)
int logversion;
int cycle = XLOG_INIT_CYCLE;
- if (show_progress)
+ if (metadump.show_progress)
print_progress("Copying log");
push_cur();
@@ -2921,11 +2940,11 @@ copy_log(void)
if (iocur_top->data == NULL) {
pop_cur();
print_warning("cannot read log");
- return !stop_on_read_error;
+ return !metadump.stop_on_read_error;
}
/* If not obfuscating or zeroing, just copy the log as it is */
- if (!obfuscate && !zero_stale_data)
+ if (!metadump.obfuscate && !metadump.zero_stale_data)
goto done;
dirty = xlog_is_dirty(mp, &log, &x, 0);
@@ -2933,7 +2952,7 @@ copy_log(void)
switch (dirty) {
case 0:
/* clear out a clean log */
- if (show_progress)
+ if (metadump.show_progress)
print_progress("Zeroing clean log");
logstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart);
@@ -2948,7 +2967,7 @@ copy_log(void)
break;
case 1:
/* keep the dirty log */
- if (obfuscate)
+ if (metadump.obfuscate)
print_warning(
_("Warning: log recovery of an obfuscated metadata image can leak "
"unobfuscated metadata and/or cause image corruption. If possible, "
@@ -2956,7 +2975,7 @@ _("Warning: log recovery of an obfuscated metadata image can leak "
break;
case -1:
/* log detection error */
- if (obfuscate)
+ if (metadump.obfuscate)
print_warning(
_("Could not discern log; image will contain unobfuscated metadata in log."));
break;
@@ -2979,9 +2998,15 @@ metadump_f(
char *p;
exitcode = 1;
- show_progress = false;
- show_warnings = false;
- stop_on_read_error = false;
+
+ metadump.version = 1;
+ metadump.show_progress = false;
+ metadump.stop_on_read_error = false;
+ metadump.max_extent_size = DEFAULT_MAX_EXT_SIZE;
+ metadump.show_warnings = false;
+ metadump.obfuscate = true;
+ metadump.zero_stale_data = true;
+ metadump.dirty_log = false;
if (mp->m_sb.sb_magicnum != XFS_SB_MAGIC) {
print_warning("bad superblock magic number %x, giving up",
@@ -3002,27 +3027,29 @@ metadump_f(
while ((c = getopt(argc, argv, "aegm:ow")) != EOF) {
switch (c) {
case 'a':
- zero_stale_data = false;
+ metadump.zero_stale_data = false;
break;
case 'e':
- stop_on_read_error = true;
+ metadump.stop_on_read_error = true;
break;
case 'g':
- show_progress = true;
+ metadump.show_progress = true;
break;
case 'm':
- max_extent_size = (int)strtol(optarg, &p, 0);
- if (*p != '\0' || max_extent_size <= 0) {
+ metadump.max_extent_size =
+ (int)strtol(optarg, &p, 0);
+ if (*p != '\0' ||
+ metadump.max_extent_size <= 0) {
print_warning("bad max extent size %s",
optarg);
return 0;
}
break;
case 'o':
- obfuscate = false;
+ metadump.obfuscate = false;
break;
case 'w':
- show_warnings = true;
+ metadump.show_warnings = true;
break;
default:
print_warning("bad option for metadump command");
@@ -3035,21 +3062,6 @@ metadump_f(
return 0;
}
- metablock = (xfs_metablock_t *)calloc(BBSIZE + 1, BBSIZE);
- if (metablock == NULL) {
- print_warning("memory allocation failure");
- return 0;
- }
- metablock->mb_blocklog = BBSHIFT;
- metablock->mb_magic = cpu_to_be32(XFS_MD_MAGIC);
-
- /* Set flags about state of metadump */
- metablock->mb_info = XFS_METADUMP_INFO_FLAGS;
- if (obfuscate)
- metablock->mb_info |= XFS_METADUMP_OBFUSCATED;
- if (!zero_stale_data)
- metablock->mb_info |= XFS_METADUMP_FULLBLOCKS;
-
/* If we'll copy the log, see if the log is dirty */
if (mp->m_sb.sb_logstart) {
push_cur();
@@ -3060,34 +3072,52 @@ metadump_f(
struct xlog log;
if (xlog_is_dirty(mp, &log, &x, 0))
- metablock->mb_info |= XFS_METADUMP_DIRTYLOG;
+ metadump.dirty_log = true;
}
pop_cur();
}
- block_index = (__be64 *)((char *)metablock + sizeof(xfs_metablock_t));
- block_buffer = (char *)metablock + BBSIZE;
- num_indices = (BBSIZE - sizeof(xfs_metablock_t)) / sizeof(__be64);
+ metadump.metablock = (xfs_metablock_t *)calloc(BBSIZE + 1, BBSIZE);
+ if (metadump.metablock == NULL) {
+ print_warning("memory allocation failure");
+ return -1;
+ }
+ metadump.metablock->mb_blocklog = BBSHIFT;
+ metadump.metablock->mb_magic = cpu_to_be32(XFS_MD_MAGIC);
+
+ /* Set flags about state of metadump */
+ metadump.metablock->mb_info = XFS_METADUMP_INFO_FLAGS;
+ if (metadump.obfuscate)
+ metadump.metablock->mb_info |= XFS_METADUMP_OBFUSCATED;
+ if (!metadump.zero_stale_data)
+ metadump.metablock->mb_info |= XFS_METADUMP_FULLBLOCKS;
+ if (metadump.dirty_log)
+ metadump.metablock->mb_info |= XFS_METADUMP_DIRTYLOG;
+
+ metadump.block_index = (__be64 *)((char *)metadump.metablock +
+ sizeof(xfs_metablock_t));
+ metadump.block_buffer = (char *)metadump.metablock + BBSIZE;
+ metadump.num_indices = (BBSIZE - sizeof(xfs_metablock_t)) /
+ sizeof(__be64);
/*
* A metadump block can hold at most num_indices of BBSIZE sectors;
* do not try to dump a filesystem with a sector size which does not
* fit within num_indices (i.e. within a single metablock).
*/
- if (mp->m_sb.sb_sectsize > num_indices * BBSIZE) {
+ if (mp->m_sb.sb_sectsize > metadump.num_indices * BBSIZE) {
print_warning("Cannot dump filesystem with sector size %u",
mp->m_sb.sb_sectsize);
- free(metablock);
+ free(metadump.metablock);
return 0;
}
- cur_index = 0;
start_iocur_sp = iocur_sp;
if (strcmp(argv[optind], "-") == 0) {
if (isatty(fileno(stdout))) {
print_warning("cannot write to a terminal");
- free(metablock);
+ free(metadump.metablock);
return 0;
}
/*
@@ -3111,17 +3141,17 @@ metadump_f(
close(outfd);
goto out;
}
- outf = fdopen(outfd, "a");
- if (outf == NULL) {
+ metadump.outf = fdopen(outfd, "a");
+ if (metadump.outf == NULL) {
fprintf(stderr, "cannot create dump stream\n");
dup2(outfd, STDOUT_FILENO);
close(outfd);
goto out;
}
- stdout_metadump = true;
+ metadump.stdout_metadump = true;
} else {
- outf = fopen(argv[optind], "wb");
- if (outf == NULL) {
+ metadump.outf = fopen(argv[optind], "wb");
+ if (metadump.outf == NULL) {
print_warning("cannot create dump file");
goto out;
}
@@ -3148,24 +3178,24 @@ metadump_f(
if (!exitcode)
exitcode = write_index() < 0;
- if (progress_since_warning)
- fputc('\n', stdout_metadump ? stderr : stdout);
+ if (metadump.progress_since_warning)
+ fputc('\n', metadump.stdout_metadump ? stderr : stdout);
- if (stdout_metadump) {
- fflush(outf);
+ if (metadump.stdout_metadump) {
+ fflush(metadump.outf);
fflush(stdout);
ret = dup2(outfd, STDOUT_FILENO);
if (ret < 0)
perror("un-redirecting stdout");
- stdout_metadump = false;
+ metadump.stdout_metadump = false;
}
- fclose(outf);
+ fclose(metadump.outf);
/* cleanup iocur stack */
while (iocur_sp > start_iocur_sp)
pop_cur();
out:
- free(metablock);
+ free(metadump.metablock);
return 0;
}
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH V3 05/23] metadump: Add initialization and release functions
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (3 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 04/23] metadump: Define and use struct metadump Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 06/23] metadump: Postpone invocation of init_metadump() Chandan Babu R
` (18 subsequent siblings)
23 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
Move metadump initialization and release functionality into corresponding
functions. There are no functional changes made in this commit.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
db/metadump.c | 88 ++++++++++++++++++++++++++++++---------------------
1 file changed, 52 insertions(+), 36 deletions(-)
diff --git a/db/metadump.c b/db/metadump.c
index c24947ec..8bc97a6c 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -2985,6 +2985,54 @@ done:
return !write_buf(iocur_top);
}
+static int
+init_metadump(void)
+{
+ metadump.metablock = (xfs_metablock_t *)calloc(BBSIZE + 1, BBSIZE);
+ if (metadump.metablock == NULL) {
+ print_warning("memory allocation failure");
+ return -1;
+ }
+ metadump.metablock->mb_blocklog = BBSHIFT;
+ metadump.metablock->mb_magic = cpu_to_be32(XFS_MD_MAGIC);
+
+ /* Set flags about state of metadump */
+ metadump.metablock->mb_info = XFS_METADUMP_INFO_FLAGS;
+ if (metadump.obfuscate)
+ metadump.metablock->mb_info |= XFS_METADUMP_OBFUSCATED;
+ if (!metadump.zero_stale_data)
+ metadump.metablock->mb_info |= XFS_METADUMP_FULLBLOCKS;
+ if (metadump.dirty_log)
+ metadump.metablock->mb_info |= XFS_METADUMP_DIRTYLOG;
+
+ metadump.block_index = (__be64 *)((char *)metadump.metablock +
+ sizeof(xfs_metablock_t));
+ metadump.block_buffer = (char *)(metadump.metablock) + BBSIZE;
+ metadump.num_indices = (BBSIZE - sizeof(xfs_metablock_t)) / sizeof(__be64);
+
+ /*
+ * A metadump block can hold at most num_indices of BBSIZE sectors;
+ * do not try to dump a filesystem with a sector size which does not
+ * fit within num_indices (i.e. within a single metablock).
+ */
+ if (mp->m_sb.sb_sectsize > metadump.num_indices * BBSIZE) {
+ print_warning("Cannot dump filesystem with sector size %u",
+ mp->m_sb.sb_sectsize);
+ free(metadump.metablock);
+ return -1;
+ }
+
+ metadump.cur_index = 0;
+
+ return 0;
+}
+
+static void
+release_metadump(void)
+{
+ free(metadump.metablock);
+}
+
static int
metadump_f(
int argc,
@@ -3077,48 +3125,16 @@ metadump_f(
pop_cur();
}
- metadump.metablock = (xfs_metablock_t *)calloc(BBSIZE + 1, BBSIZE);
- if (metadump.metablock == NULL) {
- print_warning("memory allocation failure");
- return -1;
- }
- metadump.metablock->mb_blocklog = BBSHIFT;
- metadump.metablock->mb_magic = cpu_to_be32(XFS_MD_MAGIC);
-
- /* Set flags about state of metadump */
- metadump.metablock->mb_info = XFS_METADUMP_INFO_FLAGS;
- if (metadump.obfuscate)
- metadump.metablock->mb_info |= XFS_METADUMP_OBFUSCATED;
- if (!metadump.zero_stale_data)
- metadump.metablock->mb_info |= XFS_METADUMP_FULLBLOCKS;
- if (metadump.dirty_log)
- metadump.metablock->mb_info |= XFS_METADUMP_DIRTYLOG;
-
- metadump.block_index = (__be64 *)((char *)metadump.metablock +
- sizeof(xfs_metablock_t));
- metadump.block_buffer = (char *)metadump.metablock + BBSIZE;
- metadump.num_indices = (BBSIZE - sizeof(xfs_metablock_t)) /
- sizeof(__be64);
-
- /*
- * A metadump block can hold at most num_indices of BBSIZE sectors;
- * do not try to dump a filesystem with a sector size which does not
- * fit within num_indices (i.e. within a single metablock).
- */
- if (mp->m_sb.sb_sectsize > metadump.num_indices * BBSIZE) {
- print_warning("Cannot dump filesystem with sector size %u",
- mp->m_sb.sb_sectsize);
- free(metadump.metablock);
+ ret = init_metadump();
+ if (ret)
return 0;
- }
start_iocur_sp = iocur_sp;
if (strcmp(argv[optind], "-") == 0) {
if (isatty(fileno(stdout))) {
print_warning("cannot write to a terminal");
- free(metadump.metablock);
- return 0;
+ goto out;
}
/*
* Redirect stdout to stderr for the duration of the
@@ -3195,7 +3211,7 @@ metadump_f(
while (iocur_sp > start_iocur_sp)
pop_cur();
out:
- free(metadump.metablock);
+ release_metadump();
return 0;
}
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH V3 06/23] metadump: Postpone invocation of init_metadump()
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (4 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 05/23] metadump: Add initialization and release functions Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 07/23] metadump: Introduce struct metadump_ops Chandan Babu R
` (17 subsequent siblings)
23 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
The metadump v2 initialization function (introduced in a later commit) writes
the header structure into the metadump file. This will require the program to
open the metadump file before the initialization function has been invoked.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
db/metadump.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/db/metadump.c b/db/metadump.c
index 8bc97a6c..aa30483b 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -3125,10 +3125,6 @@ metadump_f(
pop_cur();
}
- ret = init_metadump();
- if (ret)
- return 0;
-
start_iocur_sp = iocur_sp;
if (strcmp(argv[optind], "-") == 0) {
@@ -3173,6 +3169,10 @@ metadump_f(
}
}
+ ret = init_metadump();
+ if (ret)
+ goto out;
+
exitcode = 0;
for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
@@ -3210,8 +3210,9 @@ metadump_f(
/* cleanup iocur stack */
while (iocur_sp > start_iocur_sp)
pop_cur();
-out:
+
release_metadump();
+out:
return 0;
}
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH V3 07/23] metadump: Introduce struct metadump_ops
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (5 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 06/23] metadump: Postpone invocation of init_metadump() Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 08/23] metadump: Introduce metadump v1 operations Chandan Babu R
` (16 subsequent siblings)
23 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
We will need two sets of functions to implement two versions of metadump. This
commit adds the definition for 'struct metadump_ops' to hold pointers to
version specific metadump functions.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
db/metadump.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/db/metadump.c b/db/metadump.c
index aa30483b..a138453f 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -40,6 +40,30 @@ static const cmdinfo_t metadump_cmd =
N_("[-a] [-e] [-g] [-m max_extent] [-w] [-o] filename"),
N_("dump metadata to a file"), metadump_help };
+struct metadump_ops {
+ /*
+ * Initialize Metadump. This may perform actions such as
+ * 1. Allocating memory for structures required for dumping the
+ * metadata.
+ * 2. Writing a header to the beginning of the metadump file.
+ */
+ int (*init)(void);
+ /*
+ * Write metadata to the metadump file along with the required ancillary
+ * data. @off and @len are in units of 512 byte blocks.
+ */
+ int (*write)(enum typnm type, const char *data, xfs_daddr_t off,
+ int len);
+ /*
+ * Flush any in-memory remanents of metadata to the metadump file.
+ */
+ int (*finish_dump)(void);
+ /*
+ * Free resources allocated during metadump process.
+ */
+ void (*release)(void);
+};
+
static struct metadump {
int version;
bool show_progress;
@@ -54,6 +78,7 @@ static struct metadump {
xfs_ino_t cur_ino;
/* Metadump file */
FILE *outf;
+ struct metadump_ops *mdops;
/* header + index + buffers */
struct xfs_metablock *metablock;
__be64 *block_index;
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH V3 08/23] metadump: Introduce metadump v1 operations
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (6 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 07/23] metadump: Introduce struct metadump_ops Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-08-01 23:44 ` Darrick J. Wong
2023-07-24 4:35 ` [PATCH V3 09/23] metadump: Rename XFS_MD_MAGIC to XFS_MD_MAGIC_V1 Chandan Babu R
` (15 subsequent siblings)
23 siblings, 1 reply; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
This commit moves functionality associated with writing metadump to disk into
a new function. It also renames metadump initialization, write and release
functions to reflect the fact that they work with v1 metadump files.
The metadump initialization, write and release functions are now invoked via
metadump_ops->init(), metadump_ops->write() and metadump_ops->release()
respectively.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
db/metadump.c | 124 +++++++++++++++++++++++++-------------------------
1 file changed, 62 insertions(+), 62 deletions(-)
diff --git a/db/metadump.c b/db/metadump.c
index a138453f..c26a49ad 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -152,59 +152,6 @@ print_progress(const char *fmt, ...)
metadump.progress_since_warning = true;
}
-/*
- * A complete dump file will have a "zero" entry in the last index block,
- * even if the dump is exactly aligned, the last index will be full of
- * zeros. If the last index entry is non-zero, the dump is incomplete.
- * Correspondingly, the last chunk will have a count < num_indices.
- *
- * Return 0 for success, -1 for failure.
- */
-
-static int
-write_index(void)
-{
- struct xfs_metablock *metablock = metadump.metablock;
- /*
- * write index block and following data blocks (streaming)
- */
- metablock->mb_count = cpu_to_be16(metadump.cur_index);
- if (fwrite(metablock, (metadump.cur_index + 1) << BBSHIFT, 1,
- metadump.outf) != 1) {
- print_warning("error writing to target file");
- return -1;
- }
-
- memset(metadump.block_index, 0, metadump.num_indices * sizeof(__be64));
- metadump.cur_index = 0;
- return 0;
-}
-
-/*
- * Return 0 for success, -errno for failure.
- */
-static int
-write_buf_segment(
- char *data,
- int64_t off,
- int len)
-{
- int i;
- int ret;
-
- for (i = 0; i < len; i++, off++, data += BBSIZE) {
- metadump.block_index[metadump.cur_index] = cpu_to_be64(off);
- memcpy(&metadump.block_buffer[metadump.cur_index << BBSHIFT],
- data, BBSIZE);
- if (++metadump.cur_index == metadump.num_indices) {
- ret = write_index();
- if (ret)
- return -EIO;
- }
- }
- return 0;
-}
-
/*
* we want to preserve the state of the metadata in the dump - whether it is
* intact or corrupt, so even if the buffer has a verifier attached to it we
@@ -241,15 +188,17 @@ write_buf(
/* handle discontiguous buffers */
if (!buf->bbmap) {
- ret = write_buf_segment(buf->data, buf->bb, buf->blen);
+ ret = metadump.mdops->write(buf->typ->typnm, buf->data, buf->bb,
+ buf->blen);
if (ret)
return ret;
} else {
int len = 0;
for (i = 0; i < buf->bbmap->nmaps; i++) {
- ret = write_buf_segment(buf->data + BBTOB(len),
- buf->bbmap->b[i].bm_bn,
- buf->bbmap->b[i].bm_len);
+ ret = metadump.mdops->write(buf->typ->typnm,
+ buf->data + BBTOB(len),
+ buf->bbmap->b[i].bm_bn,
+ buf->bbmap->b[i].bm_len);
if (ret)
return ret;
len += buf->bbmap->b[i].bm_len;
@@ -3011,7 +2960,7 @@ done:
}
static int
-init_metadump(void)
+init_metadump_v1(void)
{
metadump.metablock = (xfs_metablock_t *)calloc(BBSIZE + 1, BBSIZE);
if (metadump.metablock == NULL) {
@@ -3052,12 +3001,61 @@ init_metadump(void)
return 0;
}
+static int
+finish_dump_metadump_v1(void)
+{
+ /*
+ * write index block and following data blocks (streaming)
+ */
+ metadump.metablock->mb_count = cpu_to_be16(metadump.cur_index);
+ if (fwrite(metadump.metablock, (metadump.cur_index + 1) << BBSHIFT, 1,
+ metadump.outf) != 1) {
+ print_warning("error writing to target file");
+ return -1;
+ }
+
+ memset(metadump.block_index, 0, metadump.num_indices * sizeof(__be64));
+ metadump.cur_index = 0;
+ return 0;
+}
+
+static int
+write_metadump_v1(
+ enum typnm type,
+ const char *data,
+ xfs_daddr_t off,
+ int len)
+{
+ int i;
+ int ret;
+
+ for (i = 0; i < len; i++, off++, data += BBSIZE) {
+ metadump.block_index[metadump.cur_index] = cpu_to_be64(off);
+ memcpy(&metadump.block_buffer[metadump.cur_index << BBSHIFT],
+ data, BBSIZE);
+ if (++metadump.cur_index == metadump.num_indices) {
+ ret = finish_dump_metadump_v1();
+ if (ret)
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
static void
-release_metadump(void)
+release_metadump_v1(void)
{
free(metadump.metablock);
}
+static struct metadump_ops metadump1_ops = {
+ .init = init_metadump_v1,
+ .write = write_metadump_v1,
+ .finish_dump = finish_dump_metadump_v1,
+ .release = release_metadump_v1,
+};
+
static int
metadump_f(
int argc,
@@ -3194,7 +3192,9 @@ metadump_f(
}
}
- ret = init_metadump();
+ metadump.mdops = &metadump1_ops;
+
+ ret = metadump.mdops->init();
if (ret)
goto out;
@@ -3217,7 +3217,7 @@ metadump_f(
/* write the remaining index */
if (!exitcode)
- exitcode = write_index() < 0;
+ exitcode = metadump.mdops->finish_dump() < 0;
if (metadump.progress_since_warning)
fputc('\n', metadump.stdout_metadump ? stderr : stdout);
@@ -3236,7 +3236,7 @@ metadump_f(
while (iocur_sp > start_iocur_sp)
pop_cur();
- release_metadump();
+ metadump.mdops->release();
out:
return 0;
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH V3 08/23] metadump: Introduce metadump v1 operations
2023-07-24 4:35 ` [PATCH V3 08/23] metadump: Introduce metadump v1 operations Chandan Babu R
@ 2023-08-01 23:44 ` Darrick J. Wong
0 siblings, 0 replies; 41+ messages in thread
From: Darrick J. Wong @ 2023-08-01 23:44 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs, cem
On Mon, Jul 24, 2023 at 10:05:12AM +0530, Chandan Babu R wrote:
> This commit moves functionality associated with writing metadump to disk into
> a new function. It also renames metadump initialization, write and release
> functions to reflect the fact that they work with v1 metadump files.
>
> The metadump initialization, write and release functions are now invoked via
> metadump_ops->init(), metadump_ops->write() and metadump_ops->release()
> respectively.
>
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
Looks good,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
--D
> ---
> db/metadump.c | 124 +++++++++++++++++++++++++-------------------------
> 1 file changed, 62 insertions(+), 62 deletions(-)
>
> diff --git a/db/metadump.c b/db/metadump.c
> index a138453f..c26a49ad 100644
> --- a/db/metadump.c
> +++ b/db/metadump.c
> @@ -152,59 +152,6 @@ print_progress(const char *fmt, ...)
> metadump.progress_since_warning = true;
> }
>
> -/*
> - * A complete dump file will have a "zero" entry in the last index block,
> - * even if the dump is exactly aligned, the last index will be full of
> - * zeros. If the last index entry is non-zero, the dump is incomplete.
> - * Correspondingly, the last chunk will have a count < num_indices.
> - *
> - * Return 0 for success, -1 for failure.
> - */
> -
> -static int
> -write_index(void)
> -{
> - struct xfs_metablock *metablock = metadump.metablock;
> - /*
> - * write index block and following data blocks (streaming)
> - */
> - metablock->mb_count = cpu_to_be16(metadump.cur_index);
> - if (fwrite(metablock, (metadump.cur_index + 1) << BBSHIFT, 1,
> - metadump.outf) != 1) {
> - print_warning("error writing to target file");
> - return -1;
> - }
> -
> - memset(metadump.block_index, 0, metadump.num_indices * sizeof(__be64));
> - metadump.cur_index = 0;
> - return 0;
> -}
> -
> -/*
> - * Return 0 for success, -errno for failure.
> - */
> -static int
> -write_buf_segment(
> - char *data,
> - int64_t off,
> - int len)
> -{
> - int i;
> - int ret;
> -
> - for (i = 0; i < len; i++, off++, data += BBSIZE) {
> - metadump.block_index[metadump.cur_index] = cpu_to_be64(off);
> - memcpy(&metadump.block_buffer[metadump.cur_index << BBSHIFT],
> - data, BBSIZE);
> - if (++metadump.cur_index == metadump.num_indices) {
> - ret = write_index();
> - if (ret)
> - return -EIO;
> - }
> - }
> - return 0;
> -}
> -
> /*
> * we want to preserve the state of the metadata in the dump - whether it is
> * intact or corrupt, so even if the buffer has a verifier attached to it we
> @@ -241,15 +188,17 @@ write_buf(
>
> /* handle discontiguous buffers */
> if (!buf->bbmap) {
> - ret = write_buf_segment(buf->data, buf->bb, buf->blen);
> + ret = metadump.mdops->write(buf->typ->typnm, buf->data, buf->bb,
> + buf->blen);
> if (ret)
> return ret;
> } else {
> int len = 0;
> for (i = 0; i < buf->bbmap->nmaps; i++) {
> - ret = write_buf_segment(buf->data + BBTOB(len),
> - buf->bbmap->b[i].bm_bn,
> - buf->bbmap->b[i].bm_len);
> + ret = metadump.mdops->write(buf->typ->typnm,
> + buf->data + BBTOB(len),
> + buf->bbmap->b[i].bm_bn,
> + buf->bbmap->b[i].bm_len);
> if (ret)
> return ret;
> len += buf->bbmap->b[i].bm_len;
> @@ -3011,7 +2960,7 @@ done:
> }
>
> static int
> -init_metadump(void)
> +init_metadump_v1(void)
> {
> metadump.metablock = (xfs_metablock_t *)calloc(BBSIZE + 1, BBSIZE);
> if (metadump.metablock == NULL) {
> @@ -3052,12 +3001,61 @@ init_metadump(void)
> return 0;
> }
>
> +static int
> +finish_dump_metadump_v1(void)
> +{
> + /*
> + * write index block and following data blocks (streaming)
> + */
> + metadump.metablock->mb_count = cpu_to_be16(metadump.cur_index);
> + if (fwrite(metadump.metablock, (metadump.cur_index + 1) << BBSHIFT, 1,
> + metadump.outf) != 1) {
> + print_warning("error writing to target file");
> + return -1;
> + }
> +
> + memset(metadump.block_index, 0, metadump.num_indices * sizeof(__be64));
> + metadump.cur_index = 0;
> + return 0;
> +}
> +
> +static int
> +write_metadump_v1(
> + enum typnm type,
> + const char *data,
> + xfs_daddr_t off,
> + int len)
> +{
> + int i;
> + int ret;
> +
> + for (i = 0; i < len; i++, off++, data += BBSIZE) {
> + metadump.block_index[metadump.cur_index] = cpu_to_be64(off);
> + memcpy(&metadump.block_buffer[metadump.cur_index << BBSHIFT],
> + data, BBSIZE);
> + if (++metadump.cur_index == metadump.num_indices) {
> + ret = finish_dump_metadump_v1();
> + if (ret)
> + return -EIO;
> + }
> + }
> +
> + return 0;
> +}
> +
> static void
> -release_metadump(void)
> +release_metadump_v1(void)
> {
> free(metadump.metablock);
> }
>
> +static struct metadump_ops metadump1_ops = {
> + .init = init_metadump_v1,
> + .write = write_metadump_v1,
> + .finish_dump = finish_dump_metadump_v1,
> + .release = release_metadump_v1,
> +};
> +
> static int
> metadump_f(
> int argc,
> @@ -3194,7 +3192,9 @@ metadump_f(
> }
> }
>
> - ret = init_metadump();
> + metadump.mdops = &metadump1_ops;
> +
> + ret = metadump.mdops->init();
> if (ret)
> goto out;
>
> @@ -3217,7 +3217,7 @@ metadump_f(
>
> /* write the remaining index */
> if (!exitcode)
> - exitcode = write_index() < 0;
> + exitcode = metadump.mdops->finish_dump() < 0;
>
> if (metadump.progress_since_warning)
> fputc('\n', metadump.stdout_metadump ? stderr : stdout);
> @@ -3236,7 +3236,7 @@ metadump_f(
> while (iocur_sp > start_iocur_sp)
> pop_cur();
>
> - release_metadump();
> + metadump.mdops->release();
>
> out:
> return 0;
> --
> 2.39.1
>
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH V3 09/23] metadump: Rename XFS_MD_MAGIC to XFS_MD_MAGIC_V1
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (7 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 08/23] metadump: Introduce metadump v1 operations Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 10/23] metadump: Define metadump v2 ondisk format structures and macros Chandan Babu R
` (14 subsequent siblings)
23 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
db/metadump.c | 2 +-
include/xfs_metadump.h | 2 +-
mdrestore/xfs_mdrestore.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/db/metadump.c b/db/metadump.c
index c26a49ad..7f4f0f07 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -2968,7 +2968,7 @@ init_metadump_v1(void)
return -1;
}
metadump.metablock->mb_blocklog = BBSHIFT;
- metadump.metablock->mb_magic = cpu_to_be32(XFS_MD_MAGIC);
+ metadump.metablock->mb_magic = cpu_to_be32(XFS_MD_MAGIC_V1);
/* Set flags about state of metadump */
metadump.metablock->mb_info = XFS_METADUMP_INFO_FLAGS;
diff --git a/include/xfs_metadump.h b/include/xfs_metadump.h
index fbd99023..a4dca25c 100644
--- a/include/xfs_metadump.h
+++ b/include/xfs_metadump.h
@@ -7,7 +7,7 @@
#ifndef _XFS_METADUMP_H_
#define _XFS_METADUMP_H_
-#define XFS_MD_MAGIC 0x5846534d /* 'XFSM' */
+#define XFS_MD_MAGIC_V1 0x5846534d /* 'XFSM' */
typedef struct xfs_metablock {
__be32 mb_magic;
diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
index 333282ed..481dd00c 100644
--- a/mdrestore/xfs_mdrestore.c
+++ b/mdrestore/xfs_mdrestore.c
@@ -240,7 +240,7 @@ main(
if (fread(&mb, sizeof(mb), 1, src_f) != 1)
fatal("error reading from metadump file\n");
- if (mb.mb_magic != cpu_to_be32(XFS_MD_MAGIC))
+ if (mb.mb_magic != cpu_to_be32(XFS_MD_MAGIC_V1))
fatal("specified file is not a metadata dump\n");
if (show_info) {
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH V3 10/23] metadump: Define metadump v2 ondisk format structures and macros
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (8 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 09/23] metadump: Rename XFS_MD_MAGIC to XFS_MD_MAGIC_V1 Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-08-01 23:47 ` Darrick J. Wong
2023-07-24 4:35 ` [PATCH V3 11/23] metadump: Define metadump ops for v2 format Chandan Babu R
` (13 subsequent siblings)
23 siblings, 1 reply; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
The corresponding metadump file's disk layout is as shown below,
|------------------------------|
| struct xfs_metadump_header |
|------------------------------|
| struct xfs_meta_extent 0 |
| Extent 0's data |
| struct xfs_meta_extent 1 |
| Extent 1's data |
| ... |
| struct xfs_meta_extent (n-1) |
| Extent (n-1)'s data |
|------------------------------|
The "struct xfs_metadump_header" is followed by alternating series of "struct
xfs_meta_extent" and the extent itself.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
include/xfs_metadump.h | 68 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/include/xfs_metadump.h b/include/xfs_metadump.h
index a4dca25c..50175ef0 100644
--- a/include/xfs_metadump.h
+++ b/include/xfs_metadump.h
@@ -8,7 +8,9 @@
#define _XFS_METADUMP_H_
#define XFS_MD_MAGIC_V1 0x5846534d /* 'XFSM' */
+#define XFS_MD_MAGIC_V2 0x584D4432 /* 'XMD2' */
+/* Metadump v1 */
typedef struct xfs_metablock {
__be32 mb_magic;
__be16 mb_count;
@@ -23,4 +25,70 @@ typedef struct xfs_metablock {
#define XFS_METADUMP_FULLBLOCKS (1 << 2)
#define XFS_METADUMP_DIRTYLOG (1 << 3)
+/*
+ * Metadump v2
+ *
+ * The following diagram depicts the ondisk layout of the metadump v2 format.
+ *
+ * |------------------------------|
+ * | struct xfs_metadump_header |
+ * |------------------------------|
+ * | struct xfs_meta_extent 0 |
+ * | Extent 0's data |
+ * | struct xfs_meta_extent 1 |
+ * | Extent 1's data |
+ * | ... |
+ * | struct xfs_meta_extent (n-1) |
+ * | Extent (n-1)'s data |
+ * |------------------------------|
+ *
+ * The "struct xfs_metadump_header" is followed by alternating series of "struct
+ * xfs_meta_extent" and the extent itself.
+ */
+struct xfs_metadump_header {
+ __be32 xmh_magic;
+ __be32 xmh_version;
+ __be32 xmh_compat_flags;
+ __be32 xmh_incompat_flags;
+ __be64 xmh_reserved;
+} __packed;
+
+/*
+ * User-supplied directory entry and extended attribute names have been
+ * obscured, and extended attribute values are zeroed to protect privacy.
+ */
+#define XFS_MD2_INCOMPAT_OBFUSCATED (1 << 0)
+
+/* Full blocks have been dumped. */
+#define XFS_MD2_INCOMPAT_FULLBLOCKS (1 << 1)
+
+/* Log was dirty. */
+#define XFS_MD2_INCOMPAT_DIRTYLOG (1 << 2)
+
+/* Dump contains external log contents. */
+#define XFS_MD2_INCOMPAT_EXTERNALLOG (1 << 3)
+
+struct xfs_meta_extent {
+ /*
+ * Lowest 54 bits are used to store 512 byte addresses.
+ * Next 2 bits is used for indicating the device.
+ * 00 - Data device
+ * 01 - External log
+ */
+ __be64 xme_addr;
+ /* In units of 512 byte blocks */
+ __be32 xme_len;
+} __packed;
+
+#define XME_ADDR_DEVICE_SHIFT 54
+
+#define XME_ADDR_DADDR_MASK ((1ULL << XME_ADDR_DEVICE_SHIFT) - 1)
+
+/* Extent was copied from the data device */
+#define XME_ADDR_DATA_DEVICE (0ULL << XME_ADDR_DEVICE_SHIFT)
+/* Extent was copied from the log device */
+#define XME_ADDR_LOG_DEVICE (1ULL << XME_ADDR_DEVICE_SHIFT)
+
+#define XME_ADDR_DEVICE_MASK (3ULL << XME_ADDR_DEVICE_SHIFT)
+
#endif /* _XFS_METADUMP_H_ */
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH V3 10/23] metadump: Define metadump v2 ondisk format structures and macros
2023-07-24 4:35 ` [PATCH V3 10/23] metadump: Define metadump v2 ondisk format structures and macros Chandan Babu R
@ 2023-08-01 23:47 ` Darrick J. Wong
2023-08-02 13:08 ` Chandan Babu R
0 siblings, 1 reply; 41+ messages in thread
From: Darrick J. Wong @ 2023-08-01 23:47 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs, cem
On Mon, Jul 24, 2023 at 10:05:14AM +0530, Chandan Babu R wrote:
> The corresponding metadump file's disk layout is as shown below,
>
> |------------------------------|
> | struct xfs_metadump_header |
> |------------------------------|
> | struct xfs_meta_extent 0 |
> | Extent 0's data |
> | struct xfs_meta_extent 1 |
> | Extent 1's data |
> | ... |
> | struct xfs_meta_extent (n-1) |
> | Extent (n-1)'s data |
> |------------------------------|
>
> The "struct xfs_metadump_header" is followed by alternating series of "struct
> xfs_meta_extent" and the extent itself.
>
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
Looks good,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Could you please post a patch describing the metadump2 file format for
https://git.kernel.org/pub/scm/fs/xfs/xfs-documentation.git/ ?
(Sorry I posted an earlier reply to the truncated submission.)
--D
> ---
> include/xfs_metadump.h | 68 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 68 insertions(+)
>
> diff --git a/include/xfs_metadump.h b/include/xfs_metadump.h
> index a4dca25c..50175ef0 100644
> --- a/include/xfs_metadump.h
> +++ b/include/xfs_metadump.h
> @@ -8,7 +8,9 @@
> #define _XFS_METADUMP_H_
>
> #define XFS_MD_MAGIC_V1 0x5846534d /* 'XFSM' */
> +#define XFS_MD_MAGIC_V2 0x584D4432 /* 'XMD2' */
>
> +/* Metadump v1 */
> typedef struct xfs_metablock {
> __be32 mb_magic;
> __be16 mb_count;
> @@ -23,4 +25,70 @@ typedef struct xfs_metablock {
> #define XFS_METADUMP_FULLBLOCKS (1 << 2)
> #define XFS_METADUMP_DIRTYLOG (1 << 3)
>
> +/*
> + * Metadump v2
> + *
> + * The following diagram depicts the ondisk layout of the metadump v2 format.
> + *
> + * |------------------------------|
> + * | struct xfs_metadump_header |
> + * |------------------------------|
> + * | struct xfs_meta_extent 0 |
> + * | Extent 0's data |
> + * | struct xfs_meta_extent 1 |
> + * | Extent 1's data |
> + * | ... |
> + * | struct xfs_meta_extent (n-1) |
> + * | Extent (n-1)'s data |
> + * |------------------------------|
> + *
> + * The "struct xfs_metadump_header" is followed by alternating series of "struct
> + * xfs_meta_extent" and the extent itself.
> + */
> +struct xfs_metadump_header {
> + __be32 xmh_magic;
> + __be32 xmh_version;
> + __be32 xmh_compat_flags;
> + __be32 xmh_incompat_flags;
> + __be64 xmh_reserved;
> +} __packed;
> +
> +/*
> + * User-supplied directory entry and extended attribute names have been
> + * obscured, and extended attribute values are zeroed to protect privacy.
> + */
> +#define XFS_MD2_INCOMPAT_OBFUSCATED (1 << 0)
> +
> +/* Full blocks have been dumped. */
> +#define XFS_MD2_INCOMPAT_FULLBLOCKS (1 << 1)
> +
> +/* Log was dirty. */
> +#define XFS_MD2_INCOMPAT_DIRTYLOG (1 << 2)
> +
> +/* Dump contains external log contents. */
> +#define XFS_MD2_INCOMPAT_EXTERNALLOG (1 << 3)
> +
> +struct xfs_meta_extent {
> + /*
> + * Lowest 54 bits are used to store 512 byte addresses.
> + * Next 2 bits is used for indicating the device.
> + * 00 - Data device
> + * 01 - External log
> + */
> + __be64 xme_addr;
> + /* In units of 512 byte blocks */
> + __be32 xme_len;
> +} __packed;
> +
> +#define XME_ADDR_DEVICE_SHIFT 54
> +
> +#define XME_ADDR_DADDR_MASK ((1ULL << XME_ADDR_DEVICE_SHIFT) - 1)
> +
> +/* Extent was copied from the data device */
> +#define XME_ADDR_DATA_DEVICE (0ULL << XME_ADDR_DEVICE_SHIFT)
> +/* Extent was copied from the log device */
> +#define XME_ADDR_LOG_DEVICE (1ULL << XME_ADDR_DEVICE_SHIFT)
> +
> +#define XME_ADDR_DEVICE_MASK (3ULL << XME_ADDR_DEVICE_SHIFT)
> +
> #endif /* _XFS_METADUMP_H_ */
> --
> 2.39.1
>
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH V3 10/23] metadump: Define metadump v2 ondisk format structures and macros
2023-08-01 23:47 ` Darrick J. Wong
@ 2023-08-02 13:08 ` Chandan Babu R
0 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-08-02 13:08 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: linux-xfs, cem
On Tue, Aug 01, 2023 at 04:47:53 PM -0700, Darrick J. Wong wrote:
> On Mon, Jul 24, 2023 at 10:05:14AM +0530, Chandan Babu R wrote:
>> The corresponding metadump file's disk layout is as shown below,
>>
>> |------------------------------|
>> | struct xfs_metadump_header |
>> |------------------------------|
>> | struct xfs_meta_extent 0 |
>> | Extent 0's data |
>> | struct xfs_meta_extent 1 |
>> | Extent 1's data |
>> | ... |
>> | struct xfs_meta_extent (n-1) |
>> | Extent (n-1)'s data |
>> |------------------------------|
>>
>> The "struct xfs_metadump_header" is followed by alternating series of "struct
>> xfs_meta_extent" and the extent itself.
>>
>> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
>
> Looks good,
> Reviewed-by: Darrick J. Wong <djwong@kernel.org>
>
> Could you please post a patch describing the metadump2 file format for
> https://git.kernel.org/pub/scm/fs/xfs/xfs-documentation.git/ ?
Sure, I will do that.
>
> (Sorry I posted an earlier reply to the truncated submission.)
>
> --D
>
--
chandan
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH V3 11/23] metadump: Define metadump ops for v2 format
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (9 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 10/23] metadump: Define metadump v2 ondisk format structures and macros Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-08-01 23:49 ` Darrick J. Wong
2023-07-24 4:35 ` [PATCH V3 12/23] xfs_db: Add support to read from external log device Chandan Babu R
` (12 subsequent siblings)
23 siblings, 1 reply; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
This commit adds functionality to dump metadata from an XFS filesystem in
newly introduced v2 format.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
db/metadump.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 71 insertions(+), 3 deletions(-)
diff --git a/db/metadump.c b/db/metadump.c
index 7f4f0f07..9b4ed70d 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -3056,6 +3056,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_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,
+ 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,
@@ -3192,7 +3256,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)
@@ -3216,7 +3283,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)
@@ -3236,7 +3303,8 @@ metadump_f(
while (iocur_sp > start_iocur_sp)
pop_cur();
- metadump.mdops->release();
+ if (metadump.mdops->release)
+ metadump.mdops->release();
out:
return 0;
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH V3 11/23] metadump: Define metadump ops for v2 format
2023-07-24 4:35 ` [PATCH V3 11/23] metadump: Define metadump ops for v2 format Chandan Babu R
@ 2023-08-01 23:49 ` Darrick J. Wong
2023-08-02 13:08 ` Chandan Babu R
0 siblings, 1 reply; 41+ messages in thread
From: Darrick J. Wong @ 2023-08-01 23:49 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs, cem
On Mon, Jul 24, 2023 at 10:05:15AM +0530, Chandan Babu R wrote:
> This commit adds functionality to dump metadata from an XFS filesystem in
> newly introduced v2 format.
>
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
> ---
> db/metadump.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 71 insertions(+), 3 deletions(-)
>
> diff --git a/db/metadump.c b/db/metadump.c
> index 7f4f0f07..9b4ed70d 100644
> --- a/db/metadump.c
> +++ b/db/metadump.c
> @@ -3056,6 +3056,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;
Indentation ^ of the local variables should be tabs, not a space.
> +
> + xmh.xmh_magic = cpu_to_be32(XFS_MD_MAGIC_V2);
> + xmh.xmh_version = cpu_to_be32(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,
> + const char *data,
> + xfs_daddr_t off,
> + int len)
> +{
> + struct xfs_meta_extent xme;
> + uint64_t addr;
Please line up the ^ ^ columns.
With that fixed,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
--D
> +
> + 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,
> @@ -3192,7 +3256,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)
> @@ -3216,7 +3283,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)
> @@ -3236,7 +3303,8 @@ metadump_f(
> while (iocur_sp > start_iocur_sp)
> pop_cur();
>
> - metadump.mdops->release();
> + if (metadump.mdops->release)
> + metadump.mdops->release();
>
> out:
> return 0;
> --
> 2.39.1
>
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH V3 11/23] metadump: Define metadump ops for v2 format
2023-08-01 23:49 ` Darrick J. Wong
@ 2023-08-02 13:08 ` Chandan Babu R
0 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-08-02 13:08 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: linux-xfs, cem
On Tue, Aug 01, 2023 at 04:49:19 PM -0700, Darrick J. Wong wrote:
> On Mon, Jul 24, 2023 at 10:05:15AM +0530, Chandan Babu R wrote:
>> This commit adds functionality to dump metadata from an XFS filesystem in
>> newly introduced v2 format.
>>
>> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
>> ---
>> db/metadump.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++---
>> 1 file changed, 71 insertions(+), 3 deletions(-)
>>
>> diff --git a/db/metadump.c b/db/metadump.c
>> index 7f4f0f07..9b4ed70d 100644
>> --- a/db/metadump.c
>> +++ b/db/metadump.c
>> @@ -3056,6 +3056,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;
>
> Indentation ^ of the local variables should be tabs, not a space.
>
>> +
>> + xmh.xmh_magic = cpu_to_be32(XFS_MD_MAGIC_V2);
>> + xmh.xmh_version = cpu_to_be32(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,
>> + const char *data,
>> + xfs_daddr_t off,
>> + int len)
>> +{
>> + struct xfs_meta_extent xme;
>> + uint64_t addr;
>
> Please line up the ^ ^ columns.
>
Sorry, I missed those. I will fix them.
> With that fixed,
> Reviewed-by: Darrick J. Wong <djwong@kernel.org>
>
--
chandan
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH V3 12/23] xfs_db: Add support to read from external log device
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (10 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 11/23] metadump: Define metadump ops for v2 format Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-08-01 23:49 ` Darrick J. Wong
2023-07-24 4:35 ` [PATCH V3 13/23] metadump: Add support for passing version option Chandan Babu R
` (11 subsequent siblings)
23 siblings, 1 reply; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
This commit introduces a new function set_log_cur() allowing xfs_db to read
from an external log device. This is required by a future commit which will
add the ability to dump metadata from external log devices.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
db/io.c | 56 +++++++++++++++++++++++++++++++++++++++++++-------------
db/io.h | 2 ++
2 files changed, 45 insertions(+), 13 deletions(-)
diff --git a/db/io.c b/db/io.c
index 3d257236..5ccfe3b5 100644
--- a/db/io.c
+++ b/db/io.c
@@ -508,18 +508,19 @@ write_cur(void)
}
-void
-set_cur(
- const typ_t *type,
- xfs_daddr_t blknum,
- int len,
- int ring_flag,
- bbmap_t *bbmap)
+static void
+__set_cur(
+ struct xfs_buftarg *btargp,
+ const typ_t *type,
+ xfs_daddr_t blknum,
+ int len,
+ int ring_flag,
+ bbmap_t *bbmap)
{
- struct xfs_buf *bp;
- xfs_ino_t dirino;
- xfs_ino_t ino;
- uint16_t mode;
+ struct xfs_buf *bp;
+ xfs_ino_t dirino;
+ xfs_ino_t ino;
+ uint16_t mode;
const struct xfs_buf_ops *ops = type ? type->bops : NULL;
int error;
@@ -548,11 +549,11 @@ set_cur(
if (!iocur_top->bbmap)
return;
memcpy(iocur_top->bbmap, bbmap, sizeof(struct bbmap));
- error = -libxfs_buf_read_map(mp->m_ddev_targp, bbmap->b,
+ error = -libxfs_buf_read_map(btargp, bbmap->b,
bbmap->nmaps, LIBXFS_READBUF_SALVAGE, &bp,
ops);
} else {
- error = -libxfs_buf_read(mp->m_ddev_targp, blknum, len,
+ error = -libxfs_buf_read(btargp, blknum, len,
LIBXFS_READBUF_SALVAGE, &bp, ops);
iocur_top->bbmap = NULL;
}
@@ -589,6 +590,35 @@ set_cur(
ring_add();
}
+void
+set_cur(
+ const typ_t *type,
+ xfs_daddr_t blknum,
+ int len,
+ int ring_flag,
+ bbmap_t *bbmap)
+{
+ __set_cur(mp->m_ddev_targp, type, blknum, len, ring_flag, bbmap);
+}
+
+void
+set_log_cur(
+ const typ_t *type,
+ xfs_daddr_t blknum,
+ int len,
+ int ring_flag,
+ bbmap_t *bbmap)
+{
+ if (mp->m_logdev_targp->bt_bdev == mp->m_ddev_targp->bt_bdev) {
+ fprintf(stderr, "no external log specified\n");
+ exitcode = 1;
+ return;
+ }
+
+ __set_cur(mp->m_logdev_targp, type, blknum, len, ring_flag, bbmap);
+}
+
+
void
set_iocur_type(
const typ_t *type)
diff --git a/db/io.h b/db/io.h
index c29a7488..bd86c31f 100644
--- a/db/io.h
+++ b/db/io.h
@@ -49,6 +49,8 @@ extern void push_cur_and_set_type(void);
extern void write_cur(void);
extern void set_cur(const struct typ *type, xfs_daddr_t blknum,
int len, int ring_add, bbmap_t *bbmap);
+extern void set_log_cur(const struct typ *type, xfs_daddr_t blknum,
+ int len, int ring_add, bbmap_t *bbmap);
extern void ring_add(void);
extern void set_iocur_type(const struct typ *type);
extern void xfs_dummy_verify(struct xfs_buf *bp);
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH V3 12/23] xfs_db: Add support to read from external log device
2023-07-24 4:35 ` [PATCH V3 12/23] xfs_db: Add support to read from external log device Chandan Babu R
@ 2023-08-01 23:49 ` Darrick J. Wong
0 siblings, 0 replies; 41+ messages in thread
From: Darrick J. Wong @ 2023-08-01 23:49 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs, cem
On Mon, Jul 24, 2023 at 10:05:16AM +0530, Chandan Babu R wrote:
> This commit introduces a new function set_log_cur() allowing xfs_db to read
> from an external log device. This is required by a future commit which will
> add the ability to dump metadata from external log devices.
>
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
Looks good now,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
--D
> ---
> db/io.c | 56 +++++++++++++++++++++++++++++++++++++++++++-------------
> db/io.h | 2 ++
> 2 files changed, 45 insertions(+), 13 deletions(-)
>
> diff --git a/db/io.c b/db/io.c
> index 3d257236..5ccfe3b5 100644
> --- a/db/io.c
> +++ b/db/io.c
> @@ -508,18 +508,19 @@ write_cur(void)
>
> }
>
> -void
> -set_cur(
> - const typ_t *type,
> - xfs_daddr_t blknum,
> - int len,
> - int ring_flag,
> - bbmap_t *bbmap)
> +static void
> +__set_cur(
> + struct xfs_buftarg *btargp,
> + const typ_t *type,
> + xfs_daddr_t blknum,
> + int len,
> + int ring_flag,
> + bbmap_t *bbmap)
> {
> - struct xfs_buf *bp;
> - xfs_ino_t dirino;
> - xfs_ino_t ino;
> - uint16_t mode;
> + struct xfs_buf *bp;
> + xfs_ino_t dirino;
> + xfs_ino_t ino;
> + uint16_t mode;
> const struct xfs_buf_ops *ops = type ? type->bops : NULL;
> int error;
>
> @@ -548,11 +549,11 @@ set_cur(
> if (!iocur_top->bbmap)
> return;
> memcpy(iocur_top->bbmap, bbmap, sizeof(struct bbmap));
> - error = -libxfs_buf_read_map(mp->m_ddev_targp, bbmap->b,
> + error = -libxfs_buf_read_map(btargp, bbmap->b,
> bbmap->nmaps, LIBXFS_READBUF_SALVAGE, &bp,
> ops);
> } else {
> - error = -libxfs_buf_read(mp->m_ddev_targp, blknum, len,
> + error = -libxfs_buf_read(btargp, blknum, len,
> LIBXFS_READBUF_SALVAGE, &bp, ops);
> iocur_top->bbmap = NULL;
> }
> @@ -589,6 +590,35 @@ set_cur(
> ring_add();
> }
>
> +void
> +set_cur(
> + const typ_t *type,
> + xfs_daddr_t blknum,
> + int len,
> + int ring_flag,
> + bbmap_t *bbmap)
> +{
> + __set_cur(mp->m_ddev_targp, type, blknum, len, ring_flag, bbmap);
> +}
> +
> +void
> +set_log_cur(
> + const typ_t *type,
> + xfs_daddr_t blknum,
> + int len,
> + int ring_flag,
> + bbmap_t *bbmap)
> +{
> + if (mp->m_logdev_targp->bt_bdev == mp->m_ddev_targp->bt_bdev) {
> + fprintf(stderr, "no external log specified\n");
> + exitcode = 1;
> + return;
> + }
> +
> + __set_cur(mp->m_logdev_targp, type, blknum, len, ring_flag, bbmap);
> +}
> +
> +
> void
> set_iocur_type(
> const typ_t *type)
> diff --git a/db/io.h b/db/io.h
> index c29a7488..bd86c31f 100644
> --- a/db/io.h
> +++ b/db/io.h
> @@ -49,6 +49,8 @@ extern void push_cur_and_set_type(void);
> extern void write_cur(void);
> extern void set_cur(const struct typ *type, xfs_daddr_t blknum,
> int len, int ring_add, bbmap_t *bbmap);
> +extern void set_log_cur(const struct typ *type, xfs_daddr_t blknum,
> + int len, int ring_add, bbmap_t *bbmap);
> extern void ring_add(void);
> extern void set_iocur_type(const struct typ *type);
> extern void xfs_dummy_verify(struct xfs_buf *bp);
> --
> 2.39.1
>
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH V3 13/23] metadump: Add support for passing version option
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (11 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 12/23] xfs_db: Add support to read from external log device Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-08-01 23:51 ` Darrick J. Wong
2023-07-24 4:35 ` [PATCH V3 14/23] mdrestore: Declare boolean variables with bool type Chandan Babu R
` (10 subsequent siblings)
23 siblings, 1 reply; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
The new option allows the user to explicitly specify the version of metadump
to use. However, we will default to using the v1 format.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
db/metadump.c | 81 +++++++++++++++++++++++++++++++++++------
db/xfs_metadump.sh | 3 +-
man/man8/xfs_metadump.8 | 14 +++++++
3 files changed, 86 insertions(+), 12 deletions(-)
diff --git a/db/metadump.c b/db/metadump.c
index 9b4ed70d..9fe9fe65 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -37,7 +37,7 @@ static void metadump_help(void);
static const cmdinfo_t metadump_cmd =
{ "metadump", NULL, metadump_f, 0, -1, 0,
- N_("[-a] [-e] [-g] [-m max_extent] [-w] [-o] filename"),
+ N_("[-a] [-e] [-g] [-m max_extent] [-w] [-o] [-v 1|2] filename"),
N_("dump metadata to a file"), metadump_help };
struct metadump_ops {
@@ -74,6 +74,7 @@ static struct metadump {
bool zero_stale_data;
bool progress_since_warning;
bool dirty_log;
+ bool external_log;
bool stdout_metadump;
xfs_ino_t cur_ino;
/* Metadump file */
@@ -107,6 +108,7 @@ metadump_help(void)
" -g -- Display dump progress\n"
" -m -- Specify max extent size in blocks to copy (default = %d blocks)\n"
" -o -- Don't obfuscate names and extended attributes\n"
+" -v -- Metadump version to be used\n"
" -w -- Show warnings of bad metadata information\n"
"\n"), DEFAULT_MAX_EXT_SIZE);
}
@@ -2909,8 +2911,20 @@ copy_log(void)
print_progress("Copying log");
push_cur();
- set_cur(&typtab[TYP_LOG], XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
- mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN, NULL);
+ if (metadump.external_log) {
+ ASSERT(mp->m_sb.sb_logstart == 0);
+ set_log_cur(&typtab[TYP_LOG],
+ XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
+ mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN,
+ NULL);
+ } else {
+ ASSERT(mp->m_sb.sb_logstart != 0);
+ set_cur(&typtab[TYP_LOG],
+ XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
+ mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN,
+ NULL);
+ }
+
if (iocur_top->data == NULL) {
pop_cur();
print_warning("cannot read log");
@@ -3071,6 +3085,8 @@ init_metadump_v2(void)
compat_flags |= XFS_MD2_INCOMPAT_FULLBLOCKS;
if (metadump.dirty_log)
compat_flags |= XFS_MD2_INCOMPAT_DIRTYLOG;
+ if (metadump.external_log)
+ compat_flags |= XFS_MD2_INCOMPAT_EXTERNALLOG;
xmh.xmh_compat_flags = cpu_to_be32(compat_flags);
@@ -3131,6 +3147,7 @@ metadump_f(
int outfd = -1;
int ret;
char *p;
+ bool version_opt_set = false;
exitcode = 1;
@@ -3142,6 +3159,7 @@ metadump_f(
metadump.obfuscate = true;
metadump.zero_stale_data = true;
metadump.dirty_log = false;
+ metadump.external_log = false;
if (mp->m_sb.sb_magicnum != XFS_SB_MAGIC) {
print_warning("bad superblock magic number %x, giving up",
@@ -3159,7 +3177,7 @@ metadump_f(
return 0;
}
- while ((c = getopt(argc, argv, "aegm:ow")) != EOF) {
+ while ((c = getopt(argc, argv, "aegm:ov:w")) != EOF) {
switch (c) {
case 'a':
metadump.zero_stale_data = false;
@@ -3183,6 +3201,17 @@ metadump_f(
case 'o':
metadump.obfuscate = false;
break;
+ case 'v':
+ metadump.version = (int)strtol(optarg, &p, 0);
+ if (*p != '\0' ||
+ (metadump.version != 1 &&
+ metadump.version != 2)) {
+ print_warning("bad metadump version: %s",
+ optarg);
+ return 0;
+ }
+ version_opt_set = true;
+ break;
case 'w':
metadump.show_warnings = true;
break;
@@ -3197,12 +3226,42 @@ metadump_f(
return 0;
}
- /* If we'll copy the log, see if the log is dirty */
- if (mp->m_sb.sb_logstart) {
+ if (mp->m_logdev_targp->bt_bdev != mp->m_ddev_targp->bt_bdev)
+ metadump.external_log = true;
+
+ if (metadump.external_log && !version_opt_set)
+ metadump.version = 2;
+
+ if (metadump.version == 2 && mp->m_sb.sb_logstart == 0 &&
+ !metadump.external_log) {
+ print_warning("external log device not loaded, use -l");
+ return -ENODEV;
+ }
+
+ /*
+ * If we'll copy the log, see if the log is dirty.
+ *
+ * Metadump v1 does not support dumping the contents of an external
+ * log. Hence we skip the dirty log check.
+ */
+ if (!(metadump.version == 1 && metadump.external_log)) {
push_cur();
- set_cur(&typtab[TYP_LOG],
- XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
- mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN, NULL);
+ if (metadump.external_log) {
+ ASSERT(mp->m_sb.sb_logstart == 0);
+ set_log_cur(&typtab[TYP_LOG],
+ XFS_FSB_TO_DADDR(mp,
+ mp->m_sb.sb_logstart),
+ mp->m_sb.sb_logblocks * blkbb,
+ DB_RING_IGN, NULL);
+ } else {
+ ASSERT(mp->m_sb.sb_logstart != 0);
+ set_cur(&typtab[TYP_LOG],
+ XFS_FSB_TO_DADDR(mp,
+ mp->m_sb.sb_logstart),
+ mp->m_sb.sb_logblocks * blkbb,
+ DB_RING_IGN, NULL);
+ }
+
if (iocur_top->data) { /* best effort */
struct xlog log;
@@ -3278,8 +3337,8 @@ metadump_f(
if (!exitcode)
exitcode = !copy_sb_inodes();
- /* copy log if it's internal */
- if ((mp->m_sb.sb_logstart != 0) && !exitcode)
+ /* copy log */
+ if (!exitcode && !(metadump.version == 1 && metadump.external_log))
exitcode = !copy_log();
/* write the remaining index */
diff --git a/db/xfs_metadump.sh b/db/xfs_metadump.sh
index 9852a5bc..9e8f86e5 100755
--- a/db/xfs_metadump.sh
+++ b/db/xfs_metadump.sh
@@ -8,7 +8,7 @@ OPTS=" "
DBOPTS=" "
USAGE="Usage: xfs_metadump [-aefFogwV] [-m max_extents] [-l logdev] source target"
-while getopts "aefgl:m:owFV" c
+while getopts "aefgl:m:owFv:V" c
do
case $c in
a) OPTS=$OPTS"-a ";;
@@ -20,6 +20,7 @@ do
f) DBOPTS=$DBOPTS" -f";;
l) DBOPTS=$DBOPTS" -l "$OPTARG" ";;
F) DBOPTS=$DBOPTS" -F";;
+ v) OPTS=$OPTS"-v "$OPTARG" ";;
V) xfs_db -p xfs_metadump -V
status=$?
exit $status
diff --git a/man/man8/xfs_metadump.8 b/man/man8/xfs_metadump.8
index c0e79d77..1732012c 100644
--- a/man/man8/xfs_metadump.8
+++ b/man/man8/xfs_metadump.8
@@ -11,6 +11,9 @@ xfs_metadump \- copy XFS filesystem metadata to a file
] [
.B \-l
.I logdev
+] [
+.B \-v
+.I version
]
.I source
.I target
@@ -74,6 +77,12 @@ metadata such as filenames is not considered sensitive. If obfuscation
is required on a metadump with a dirty log, please inform the recipient
of the metadump image about this situation.
.PP
+The contents of an external log device can be dumped only when using the v2
+format.
+Metadump in v2 format can be generated by passing the "-v 2" option.
+Metadump in v2 format is generated by default if the filesystem has an
+external log and the metadump version to use is not explicitly mentioned.
+.PP
.B xfs_metadump
should not be used for any purposes other than for debugging and reporting
filesystem problems. The most common usage scenario for this tool is when
@@ -134,6 +143,11 @@ this value. The default size is 2097151 blocks.
.B \-o
Disables obfuscation of file names and extended attributes.
.TP
+.B \-v
+The format of the metadump file to be produced.
+Valid values are 1 and 2.
+The default metadump format is 1.
+.TP
.B \-w
Prints warnings of inconsistent metadata encountered to stderr. Bad metadata
is still copied.
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH V3 13/23] metadump: Add support for passing version option
2023-07-24 4:35 ` [PATCH V3 13/23] metadump: Add support for passing version option Chandan Babu R
@ 2023-08-01 23:51 ` Darrick J. Wong
2023-08-02 13:18 ` Chandan Babu R
0 siblings, 1 reply; 41+ messages in thread
From: Darrick J. Wong @ 2023-08-01 23:51 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs, cem
On Mon, Jul 24, 2023 at 10:05:17AM +0530, Chandan Babu R wrote:
> The new option allows the user to explicitly specify the version of metadump
> to use. However, we will default to using the v1 format.
>
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
Why did this lose its RVB tag from v2?
--D
> ---
> db/metadump.c | 81 +++++++++++++++++++++++++++++++++++------
> db/xfs_metadump.sh | 3 +-
> man/man8/xfs_metadump.8 | 14 +++++++
> 3 files changed, 86 insertions(+), 12 deletions(-)
>
> diff --git a/db/metadump.c b/db/metadump.c
> index 9b4ed70d..9fe9fe65 100644
> --- a/db/metadump.c
> +++ b/db/metadump.c
> @@ -37,7 +37,7 @@ static void metadump_help(void);
>
> static const cmdinfo_t metadump_cmd =
> { "metadump", NULL, metadump_f, 0, -1, 0,
> - N_("[-a] [-e] [-g] [-m max_extent] [-w] [-o] filename"),
> + N_("[-a] [-e] [-g] [-m max_extent] [-w] [-o] [-v 1|2] filename"),
> N_("dump metadata to a file"), metadump_help };
>
> struct metadump_ops {
> @@ -74,6 +74,7 @@ static struct metadump {
> bool zero_stale_data;
> bool progress_since_warning;
> bool dirty_log;
> + bool external_log;
> bool stdout_metadump;
> xfs_ino_t cur_ino;
> /* Metadump file */
> @@ -107,6 +108,7 @@ metadump_help(void)
> " -g -- Display dump progress\n"
> " -m -- Specify max extent size in blocks to copy (default = %d blocks)\n"
> " -o -- Don't obfuscate names and extended attributes\n"
> +" -v -- Metadump version to be used\n"
> " -w -- Show warnings of bad metadata information\n"
> "\n"), DEFAULT_MAX_EXT_SIZE);
> }
> @@ -2909,8 +2911,20 @@ copy_log(void)
> print_progress("Copying log");
>
> push_cur();
> - set_cur(&typtab[TYP_LOG], XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
> - mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN, NULL);
> + if (metadump.external_log) {
> + ASSERT(mp->m_sb.sb_logstart == 0);
> + set_log_cur(&typtab[TYP_LOG],
> + XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
> + mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN,
> + NULL);
> + } else {
> + ASSERT(mp->m_sb.sb_logstart != 0);
> + set_cur(&typtab[TYP_LOG],
> + XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
> + mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN,
> + NULL);
> + }
> +
> if (iocur_top->data == NULL) {
> pop_cur();
> print_warning("cannot read log");
> @@ -3071,6 +3085,8 @@ init_metadump_v2(void)
> compat_flags |= XFS_MD2_INCOMPAT_FULLBLOCKS;
> if (metadump.dirty_log)
> compat_flags |= XFS_MD2_INCOMPAT_DIRTYLOG;
> + if (metadump.external_log)
> + compat_flags |= XFS_MD2_INCOMPAT_EXTERNALLOG;
>
> xmh.xmh_compat_flags = cpu_to_be32(compat_flags);
>
> @@ -3131,6 +3147,7 @@ metadump_f(
> int outfd = -1;
> int ret;
> char *p;
> + bool version_opt_set = false;
>
> exitcode = 1;
>
> @@ -3142,6 +3159,7 @@ metadump_f(
> metadump.obfuscate = true;
> metadump.zero_stale_data = true;
> metadump.dirty_log = false;
> + metadump.external_log = false;
>
> if (mp->m_sb.sb_magicnum != XFS_SB_MAGIC) {
> print_warning("bad superblock magic number %x, giving up",
> @@ -3159,7 +3177,7 @@ metadump_f(
> return 0;
> }
>
> - while ((c = getopt(argc, argv, "aegm:ow")) != EOF) {
> + while ((c = getopt(argc, argv, "aegm:ov:w")) != EOF) {
> switch (c) {
> case 'a':
> metadump.zero_stale_data = false;
> @@ -3183,6 +3201,17 @@ metadump_f(
> case 'o':
> metadump.obfuscate = false;
> break;
> + case 'v':
> + metadump.version = (int)strtol(optarg, &p, 0);
> + if (*p != '\0' ||
> + (metadump.version != 1 &&
> + metadump.version != 2)) {
> + print_warning("bad metadump version: %s",
> + optarg);
> + return 0;
> + }
> + version_opt_set = true;
> + break;
> case 'w':
> metadump.show_warnings = true;
> break;
> @@ -3197,12 +3226,42 @@ metadump_f(
> return 0;
> }
>
> - /* If we'll copy the log, see if the log is dirty */
> - if (mp->m_sb.sb_logstart) {
> + if (mp->m_logdev_targp->bt_bdev != mp->m_ddev_targp->bt_bdev)
> + metadump.external_log = true;
> +
> + if (metadump.external_log && !version_opt_set)
> + metadump.version = 2;
> +
> + if (metadump.version == 2 && mp->m_sb.sb_logstart == 0 &&
> + !metadump.external_log) {
> + print_warning("external log device not loaded, use -l");
> + return -ENODEV;
> + }
> +
> + /*
> + * If we'll copy the log, see if the log is dirty.
> + *
> + * Metadump v1 does not support dumping the contents of an external
> + * log. Hence we skip the dirty log check.
> + */
> + if (!(metadump.version == 1 && metadump.external_log)) {
> push_cur();
> - set_cur(&typtab[TYP_LOG],
> - XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
> - mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN, NULL);
> + if (metadump.external_log) {
> + ASSERT(mp->m_sb.sb_logstart == 0);
> + set_log_cur(&typtab[TYP_LOG],
> + XFS_FSB_TO_DADDR(mp,
> + mp->m_sb.sb_logstart),
> + mp->m_sb.sb_logblocks * blkbb,
> + DB_RING_IGN, NULL);
> + } else {
> + ASSERT(mp->m_sb.sb_logstart != 0);
> + set_cur(&typtab[TYP_LOG],
> + XFS_FSB_TO_DADDR(mp,
> + mp->m_sb.sb_logstart),
> + mp->m_sb.sb_logblocks * blkbb,
> + DB_RING_IGN, NULL);
> + }
> +
> if (iocur_top->data) { /* best effort */
> struct xlog log;
>
> @@ -3278,8 +3337,8 @@ metadump_f(
> if (!exitcode)
> exitcode = !copy_sb_inodes();
>
> - /* copy log if it's internal */
> - if ((mp->m_sb.sb_logstart != 0) && !exitcode)
> + /* copy log */
> + if (!exitcode && !(metadump.version == 1 && metadump.external_log))
> exitcode = !copy_log();
>
> /* write the remaining index */
> diff --git a/db/xfs_metadump.sh b/db/xfs_metadump.sh
> index 9852a5bc..9e8f86e5 100755
> --- a/db/xfs_metadump.sh
> +++ b/db/xfs_metadump.sh
> @@ -8,7 +8,7 @@ OPTS=" "
> DBOPTS=" "
> USAGE="Usage: xfs_metadump [-aefFogwV] [-m max_extents] [-l logdev] source target"
>
> -while getopts "aefgl:m:owFV" c
> +while getopts "aefgl:m:owFv:V" c
> do
> case $c in
> a) OPTS=$OPTS"-a ";;
> @@ -20,6 +20,7 @@ do
> f) DBOPTS=$DBOPTS" -f";;
> l) DBOPTS=$DBOPTS" -l "$OPTARG" ";;
> F) DBOPTS=$DBOPTS" -F";;
> + v) OPTS=$OPTS"-v "$OPTARG" ";;
> V) xfs_db -p xfs_metadump -V
> status=$?
> exit $status
> diff --git a/man/man8/xfs_metadump.8 b/man/man8/xfs_metadump.8
> index c0e79d77..1732012c 100644
> --- a/man/man8/xfs_metadump.8
> +++ b/man/man8/xfs_metadump.8
> @@ -11,6 +11,9 @@ xfs_metadump \- copy XFS filesystem metadata to a file
> ] [
> .B \-l
> .I logdev
> +] [
> +.B \-v
> +.I version
> ]
> .I source
> .I target
> @@ -74,6 +77,12 @@ metadata such as filenames is not considered sensitive. If obfuscation
> is required on a metadump with a dirty log, please inform the recipient
> of the metadump image about this situation.
> .PP
> +The contents of an external log device can be dumped only when using the v2
> +format.
> +Metadump in v2 format can be generated by passing the "-v 2" option.
> +Metadump in v2 format is generated by default if the filesystem has an
> +external log and the metadump version to use is not explicitly mentioned.
> +.PP
> .B xfs_metadump
> should not be used for any purposes other than for debugging and reporting
> filesystem problems. The most common usage scenario for this tool is when
> @@ -134,6 +143,11 @@ this value. The default size is 2097151 blocks.
> .B \-o
> Disables obfuscation of file names and extended attributes.
> .TP
> +.B \-v
> +The format of the metadump file to be produced.
> +Valid values are 1 and 2.
> +The default metadump format is 1.
> +.TP
> .B \-w
> Prints warnings of inconsistent metadata encountered to stderr. Bad metadata
> is still copied.
> --
> 2.39.1
>
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH V3 13/23] metadump: Add support for passing version option
2023-08-01 23:51 ` Darrick J. Wong
@ 2023-08-02 13:18 ` Chandan Babu R
2023-08-02 17:14 ` Darrick J. Wong
0 siblings, 1 reply; 41+ messages in thread
From: Chandan Babu R @ 2023-08-02 13:18 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: linux-xfs, cem
On Tue, Aug 01, 2023 at 04:51:20 PM -0700, Darrick J. Wong wrote:
> On Mon, Jul 24, 2023 at 10:05:17AM +0530, Chandan Babu R wrote:
>> The new option allows the user to explicitly specify the version of metadump
>> to use. However, we will default to using the v1 format.
>>
>> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
>
> Why did this lose its RVB tag from v2?
copy_log() and metadump_f() were invoking set_log_cur() for both
"internal log" and "external log". In this version of the patchset, I
have modified the copy_log() function to,
1. Invoke set_log_cur() when the filesystem has an external log.
2. Invoke set_cur() when the filesystem has an internal log.
I think the above changes warrant a review. Hence, I had to remove your
RVB.
>
> --D
>
>> ---
>> db/metadump.c | 81 +++++++++++++++++++++++++++++++++++------
>> db/xfs_metadump.sh | 3 +-
>> man/man8/xfs_metadump.8 | 14 +++++++
>> 3 files changed, 86 insertions(+), 12 deletions(-)
>>
>> diff --git a/db/metadump.c b/db/metadump.c
>> index 9b4ed70d..9fe9fe65 100644
>> --- a/db/metadump.c
>> +++ b/db/metadump.c
>> @@ -37,7 +37,7 @@ static void metadump_help(void);
>>
>> static const cmdinfo_t metadump_cmd =
>> { "metadump", NULL, metadump_f, 0, -1, 0,
>> - N_("[-a] [-e] [-g] [-m max_extent] [-w] [-o] filename"),
>> + N_("[-a] [-e] [-g] [-m max_extent] [-w] [-o] [-v 1|2] filename"),
>> N_("dump metadata to a file"), metadump_help };
>>
>> struct metadump_ops {
>> @@ -74,6 +74,7 @@ static struct metadump {
>> bool zero_stale_data;
>> bool progress_since_warning;
>> bool dirty_log;
>> + bool external_log;
>> bool stdout_metadump;
>> xfs_ino_t cur_ino;
>> /* Metadump file */
>> @@ -107,6 +108,7 @@ metadump_help(void)
>> " -g -- Display dump progress\n"
>> " -m -- Specify max extent size in blocks to copy (default = %d blocks)\n"
>> " -o -- Don't obfuscate names and extended attributes\n"
>> +" -v -- Metadump version to be used\n"
>> " -w -- Show warnings of bad metadata information\n"
>> "\n"), DEFAULT_MAX_EXT_SIZE);
>> }
>> @@ -2909,8 +2911,20 @@ copy_log(void)
>> print_progress("Copying log");
>>
>> push_cur();
>> - set_cur(&typtab[TYP_LOG], XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
>> - mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN, NULL);
>> + if (metadump.external_log) {
>> + ASSERT(mp->m_sb.sb_logstart == 0);
>> + set_log_cur(&typtab[TYP_LOG],
>> + XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
>> + mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN,
>> + NULL);
>> + } else {
>> + ASSERT(mp->m_sb.sb_logstart != 0);
>> + set_cur(&typtab[TYP_LOG],
>> + XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
>> + mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN,
>> + NULL);
>> + }
>> +
>> if (iocur_top->data == NULL) {
>> pop_cur();
>> print_warning("cannot read log");
>> @@ -3071,6 +3085,8 @@ init_metadump_v2(void)
>> compat_flags |= XFS_MD2_INCOMPAT_FULLBLOCKS;
>> if (metadump.dirty_log)
>> compat_flags |= XFS_MD2_INCOMPAT_DIRTYLOG;
>> + if (metadump.external_log)
>> + compat_flags |= XFS_MD2_INCOMPAT_EXTERNALLOG;
>>
>> xmh.xmh_compat_flags = cpu_to_be32(compat_flags);
>>
>> @@ -3131,6 +3147,7 @@ metadump_f(
>> int outfd = -1;
>> int ret;
>> char *p;
>> + bool version_opt_set = false;
>>
>> exitcode = 1;
>>
>> @@ -3142,6 +3159,7 @@ metadump_f(
>> metadump.obfuscate = true;
>> metadump.zero_stale_data = true;
>> metadump.dirty_log = false;
>> + metadump.external_log = false;
>>
>> if (mp->m_sb.sb_magicnum != XFS_SB_MAGIC) {
>> print_warning("bad superblock magic number %x, giving up",
>> @@ -3159,7 +3177,7 @@ metadump_f(
>> return 0;
>> }
>>
>> - while ((c = getopt(argc, argv, "aegm:ow")) != EOF) {
>> + while ((c = getopt(argc, argv, "aegm:ov:w")) != EOF) {
>> switch (c) {
>> case 'a':
>> metadump.zero_stale_data = false;
>> @@ -3183,6 +3201,17 @@ metadump_f(
>> case 'o':
>> metadump.obfuscate = false;
>> break;
>> + case 'v':
>> + metadump.version = (int)strtol(optarg, &p, 0);
>> + if (*p != '\0' ||
>> + (metadump.version != 1 &&
>> + metadump.version != 2)) {
>> + print_warning("bad metadump version: %s",
>> + optarg);
>> + return 0;
>> + }
>> + version_opt_set = true;
>> + break;
>> case 'w':
>> metadump.show_warnings = true;
>> break;
>> @@ -3197,12 +3226,42 @@ metadump_f(
>> return 0;
>> }
>>
>> - /* If we'll copy the log, see if the log is dirty */
>> - if (mp->m_sb.sb_logstart) {
>> + if (mp->m_logdev_targp->bt_bdev != mp->m_ddev_targp->bt_bdev)
>> + metadump.external_log = true;
>> +
>> + if (metadump.external_log && !version_opt_set)
>> + metadump.version = 2;
>> +
>> + if (metadump.version == 2 && mp->m_sb.sb_logstart == 0 &&
>> + !metadump.external_log) {
>> + print_warning("external log device not loaded, use -l");
>> + return -ENODEV;
>> + }
>> +
>> + /*
>> + * If we'll copy the log, see if the log is dirty.
>> + *
>> + * Metadump v1 does not support dumping the contents of an external
>> + * log. Hence we skip the dirty log check.
>> + */
>> + if (!(metadump.version == 1 && metadump.external_log)) {
>> push_cur();
>> - set_cur(&typtab[TYP_LOG],
>> - XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
>> - mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN, NULL);
>> + if (metadump.external_log) {
>> + ASSERT(mp->m_sb.sb_logstart == 0);
>> + set_log_cur(&typtab[TYP_LOG],
>> + XFS_FSB_TO_DADDR(mp,
>> + mp->m_sb.sb_logstart),
>> + mp->m_sb.sb_logblocks * blkbb,
>> + DB_RING_IGN, NULL);
>> + } else {
>> + ASSERT(mp->m_sb.sb_logstart != 0);
>> + set_cur(&typtab[TYP_LOG],
>> + XFS_FSB_TO_DADDR(mp,
>> + mp->m_sb.sb_logstart),
>> + mp->m_sb.sb_logblocks * blkbb,
>> + DB_RING_IGN, NULL);
>> + }
>> +
>> if (iocur_top->data) { /* best effort */
>> struct xlog log;
>>
>> @@ -3278,8 +3337,8 @@ metadump_f(
>> if (!exitcode)
>> exitcode = !copy_sb_inodes();
>>
>> - /* copy log if it's internal */
>> - if ((mp->m_sb.sb_logstart != 0) && !exitcode)
>> + /* copy log */
>> + if (!exitcode && !(metadump.version == 1 && metadump.external_log))
>> exitcode = !copy_log();
>>
>> /* write the remaining index */
>> diff --git a/db/xfs_metadump.sh b/db/xfs_metadump.sh
>> index 9852a5bc..9e8f86e5 100755
>> --- a/db/xfs_metadump.sh
>> +++ b/db/xfs_metadump.sh
>> @@ -8,7 +8,7 @@ OPTS=" "
>> DBOPTS=" "
>> USAGE="Usage: xfs_metadump [-aefFogwV] [-m max_extents] [-l logdev] source target"
>>
>> -while getopts "aefgl:m:owFV" c
>> +while getopts "aefgl:m:owFv:V" c
>> do
>> case $c in
>> a) OPTS=$OPTS"-a ";;
>> @@ -20,6 +20,7 @@ do
>> f) DBOPTS=$DBOPTS" -f";;
>> l) DBOPTS=$DBOPTS" -l "$OPTARG" ";;
>> F) DBOPTS=$DBOPTS" -F";;
>> + v) OPTS=$OPTS"-v "$OPTARG" ";;
>> V) xfs_db -p xfs_metadump -V
>> status=$?
>> exit $status
>> diff --git a/man/man8/xfs_metadump.8 b/man/man8/xfs_metadump.8
>> index c0e79d77..1732012c 100644
>> --- a/man/man8/xfs_metadump.8
>> +++ b/man/man8/xfs_metadump.8
>> @@ -11,6 +11,9 @@ xfs_metadump \- copy XFS filesystem metadata to a file
>> ] [
>> .B \-l
>> .I logdev
>> +] [
>> +.B \-v
>> +.I version
>> ]
>> .I source
>> .I target
>> @@ -74,6 +77,12 @@ metadata such as filenames is not considered sensitive. If obfuscation
>> is required on a metadump with a dirty log, please inform the recipient
>> of the metadump image about this situation.
>> .PP
>> +The contents of an external log device can be dumped only when using the v2
>> +format.
>> +Metadump in v2 format can be generated by passing the "-v 2" option.
>> +Metadump in v2 format is generated by default if the filesystem has an
>> +external log and the metadump version to use is not explicitly mentioned.
>> +.PP
>> .B xfs_metadump
>> should not be used for any purposes other than for debugging and reporting
>> filesystem problems. The most common usage scenario for this tool is when
>> @@ -134,6 +143,11 @@ this value. The default size is 2097151 blocks.
>> .B \-o
>> Disables obfuscation of file names and extended attributes.
>> .TP
>> +.B \-v
>> +The format of the metadump file to be produced.
>> +Valid values are 1 and 2.
>> +The default metadump format is 1.
>> +.TP
>> .B \-w
>> Prints warnings of inconsistent metadata encountered to stderr. Bad metadata
>> is still copied.
>> --
>> 2.39.1
>>
--
chandan
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH V3 13/23] metadump: Add support for passing version option
2023-08-02 13:18 ` Chandan Babu R
@ 2023-08-02 17:14 ` Darrick J. Wong
0 siblings, 0 replies; 41+ messages in thread
From: Darrick J. Wong @ 2023-08-02 17:14 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs, cem
On Wed, Aug 02, 2023 at 06:48:31PM +0530, Chandan Babu R wrote:
> On Tue, Aug 01, 2023 at 04:51:20 PM -0700, Darrick J. Wong wrote:
> > On Mon, Jul 24, 2023 at 10:05:17AM +0530, Chandan Babu R wrote:
> >> The new option allows the user to explicitly specify the version of metadump
> >> to use. However, we will default to using the v1 format.
> >>
> >> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
> >
> > Why did this lose its RVB tag from v2?
>
> copy_log() and metadump_f() were invoking set_log_cur() for both
> "internal log" and "external log". In this version of the patchset, I
> have modified the copy_log() function to,
> 1. Invoke set_log_cur() when the filesystem has an external log.
> 2. Invoke set_cur() when the filesystem has an internal log.
>
> I think the above changes warrant a review. Hence, I had to remove your
> RVB.
Ah, ok. Well, this looks fine still, so...
> >
> > --D
> >
> >> ---
> >> db/metadump.c | 81 +++++++++++++++++++++++++++++++++++------
> >> db/xfs_metadump.sh | 3 +-
> >> man/man8/xfs_metadump.8 | 14 +++++++
> >> 3 files changed, 86 insertions(+), 12 deletions(-)
> >>
> >> diff --git a/db/metadump.c b/db/metadump.c
> >> index 9b4ed70d..9fe9fe65 100644
> >> --- a/db/metadump.c
> >> +++ b/db/metadump.c
> >> @@ -37,7 +37,7 @@ static void metadump_help(void);
> >>
> >> static const cmdinfo_t metadump_cmd =
> >> { "metadump", NULL, metadump_f, 0, -1, 0,
> >> - N_("[-a] [-e] [-g] [-m max_extent] [-w] [-o] filename"),
> >> + N_("[-a] [-e] [-g] [-m max_extent] [-w] [-o] [-v 1|2] filename"),
> >> N_("dump metadata to a file"), metadump_help };
> >>
> >> struct metadump_ops {
> >> @@ -74,6 +74,7 @@ static struct metadump {
> >> bool zero_stale_data;
> >> bool progress_since_warning;
> >> bool dirty_log;
> >> + bool external_log;
> >> bool stdout_metadump;
> >> xfs_ino_t cur_ino;
> >> /* Metadump file */
> >> @@ -107,6 +108,7 @@ metadump_help(void)
> >> " -g -- Display dump progress\n"
> >> " -m -- Specify max extent size in blocks to copy (default = %d blocks)\n"
> >> " -o -- Don't obfuscate names and extended attributes\n"
> >> +" -v -- Metadump version to be used\n"
> >> " -w -- Show warnings of bad metadata information\n"
> >> "\n"), DEFAULT_MAX_EXT_SIZE);
> >> }
> >> @@ -2909,8 +2911,20 @@ copy_log(void)
> >> print_progress("Copying log");
> >>
> >> push_cur();
> >> - set_cur(&typtab[TYP_LOG], XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
> >> - mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN, NULL);
> >> + if (metadump.external_log) {
> >> + ASSERT(mp->m_sb.sb_logstart == 0);
> >> + set_log_cur(&typtab[TYP_LOG],
> >> + XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
> >> + mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN,
> >> + NULL);
> >> + } else {
> >> + ASSERT(mp->m_sb.sb_logstart != 0);
> >> + set_cur(&typtab[TYP_LOG],
> >> + XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
> >> + mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN,
> >> + NULL);
> >> + }
> >> +
> >> if (iocur_top->data == NULL) {
> >> pop_cur();
> >> print_warning("cannot read log");
> >> @@ -3071,6 +3085,8 @@ init_metadump_v2(void)
> >> compat_flags |= XFS_MD2_INCOMPAT_FULLBLOCKS;
> >> if (metadump.dirty_log)
> >> compat_flags |= XFS_MD2_INCOMPAT_DIRTYLOG;
> >> + if (metadump.external_log)
> >> + compat_flags |= XFS_MD2_INCOMPAT_EXTERNALLOG;
> >>
> >> xmh.xmh_compat_flags = cpu_to_be32(compat_flags);
> >>
> >> @@ -3131,6 +3147,7 @@ metadump_f(
> >> int outfd = -1;
> >> int ret;
> >> char *p;
> >> + bool version_opt_set = false;
> >>
> >> exitcode = 1;
> >>
> >> @@ -3142,6 +3159,7 @@ metadump_f(
> >> metadump.obfuscate = true;
> >> metadump.zero_stale_data = true;
> >> metadump.dirty_log = false;
> >> + metadump.external_log = false;
> >>
> >> if (mp->m_sb.sb_magicnum != XFS_SB_MAGIC) {
> >> print_warning("bad superblock magic number %x, giving up",
> >> @@ -3159,7 +3177,7 @@ metadump_f(
> >> return 0;
> >> }
> >>
> >> - while ((c = getopt(argc, argv, "aegm:ow")) != EOF) {
> >> + while ((c = getopt(argc, argv, "aegm:ov:w")) != EOF) {
> >> switch (c) {
> >> case 'a':
> >> metadump.zero_stale_data = false;
> >> @@ -3183,6 +3201,17 @@ metadump_f(
> >> case 'o':
> >> metadump.obfuscate = false;
> >> break;
> >> + case 'v':
> >> + metadump.version = (int)strtol(optarg, &p, 0);
> >> + if (*p != '\0' ||
> >> + (metadump.version != 1 &&
> >> + metadump.version != 2)) {
> >> + print_warning("bad metadump version: %s",
> >> + optarg);
> >> + return 0;
> >> + }
> >> + version_opt_set = true;
> >> + break;
> >> case 'w':
> >> metadump.show_warnings = true;
> >> break;
> >> @@ -3197,12 +3226,42 @@ metadump_f(
> >> return 0;
> >> }
> >>
> >> - /* If we'll copy the log, see if the log is dirty */
> >> - if (mp->m_sb.sb_logstart) {
> >> + if (mp->m_logdev_targp->bt_bdev != mp->m_ddev_targp->bt_bdev)
> >> + metadump.external_log = true;
> >> +
> >> + if (metadump.external_log && !version_opt_set)
> >> + metadump.version = 2;
> >> +
> >> + if (metadump.version == 2 && mp->m_sb.sb_logstart == 0 &&
> >> + !metadump.external_log) {
> >> + print_warning("external log device not loaded, use -l");
> >> + return -ENODEV;
/me notes that any nonzero return from a *_f() function will stop
command processing, not just negative errnos:
pushfile(stdin);
while (!done) {
if ((input = fetchline()) == NULL)
break;
v = breakline(input, &c);
if (c)
done = command(c, v);
doneline(input, v);
}
The actual value here doesn't matter, so it's not a bug, just nitpicking
on my part.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
--D
> >> + }
> >> +
> >> + /*
> >> + * If we'll copy the log, see if the log is dirty.
> >> + *
> >> + * Metadump v1 does not support dumping the contents of an external
> >> + * log. Hence we skip the dirty log check.
> >> + */
> >> + if (!(metadump.version == 1 && metadump.external_log)) {
> >> push_cur();
> >> - set_cur(&typtab[TYP_LOG],
> >> - XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
> >> - mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN, NULL);
> >> + if (metadump.external_log) {
> >> + ASSERT(mp->m_sb.sb_logstart == 0);
> >> + set_log_cur(&typtab[TYP_LOG],
> >> + XFS_FSB_TO_DADDR(mp,
> >> + mp->m_sb.sb_logstart),
> >> + mp->m_sb.sb_logblocks * blkbb,
> >> + DB_RING_IGN, NULL);
> >> + } else {
> >> + ASSERT(mp->m_sb.sb_logstart != 0);
> >> + set_cur(&typtab[TYP_LOG],
> >> + XFS_FSB_TO_DADDR(mp,
> >> + mp->m_sb.sb_logstart),
> >> + mp->m_sb.sb_logblocks * blkbb,
> >> + DB_RING_IGN, NULL);
> >> + }
> >> +
> >> if (iocur_top->data) { /* best effort */
> >> struct xlog log;
> >>
> >> @@ -3278,8 +3337,8 @@ metadump_f(
> >> if (!exitcode)
> >> exitcode = !copy_sb_inodes();
> >>
> >> - /* copy log if it's internal */
> >> - if ((mp->m_sb.sb_logstart != 0) && !exitcode)
> >> + /* copy log */
> >> + if (!exitcode && !(metadump.version == 1 && metadump.external_log))
> >> exitcode = !copy_log();
> >>
> >> /* write the remaining index */
> >> diff --git a/db/xfs_metadump.sh b/db/xfs_metadump.sh
> >> index 9852a5bc..9e8f86e5 100755
> >> --- a/db/xfs_metadump.sh
> >> +++ b/db/xfs_metadump.sh
> >> @@ -8,7 +8,7 @@ OPTS=" "
> >> DBOPTS=" "
> >> USAGE="Usage: xfs_metadump [-aefFogwV] [-m max_extents] [-l logdev] source target"
> >>
> >> -while getopts "aefgl:m:owFV" c
> >> +while getopts "aefgl:m:owFv:V" c
> >> do
> >> case $c in
> >> a) OPTS=$OPTS"-a ";;
> >> @@ -20,6 +20,7 @@ do
> >> f) DBOPTS=$DBOPTS" -f";;
> >> l) DBOPTS=$DBOPTS" -l "$OPTARG" ";;
> >> F) DBOPTS=$DBOPTS" -F";;
> >> + v) OPTS=$OPTS"-v "$OPTARG" ";;
> >> V) xfs_db -p xfs_metadump -V
> >> status=$?
> >> exit $status
> >> diff --git a/man/man8/xfs_metadump.8 b/man/man8/xfs_metadump.8
> >> index c0e79d77..1732012c 100644
> >> --- a/man/man8/xfs_metadump.8
> >> +++ b/man/man8/xfs_metadump.8
> >> @@ -11,6 +11,9 @@ xfs_metadump \- copy XFS filesystem metadata to a file
> >> ] [
> >> .B \-l
> >> .I logdev
> >> +] [
> >> +.B \-v
> >> +.I version
> >> ]
> >> .I source
> >> .I target
> >> @@ -74,6 +77,12 @@ metadata such as filenames is not considered sensitive. If obfuscation
> >> is required on a metadump with a dirty log, please inform the recipient
> >> of the metadump image about this situation.
> >> .PP
> >> +The contents of an external log device can be dumped only when using the v2
> >> +format.
> >> +Metadump in v2 format can be generated by passing the "-v 2" option.
> >> +Metadump in v2 format is generated by default if the filesystem has an
> >> +external log and the metadump version to use is not explicitly mentioned.
> >> +.PP
> >> .B xfs_metadump
> >> should not be used for any purposes other than for debugging and reporting
> >> filesystem problems. The most common usage scenario for this tool is when
> >> @@ -134,6 +143,11 @@ this value. The default size is 2097151 blocks.
> >> .B \-o
> >> Disables obfuscation of file names and extended attributes.
> >> .TP
> >> +.B \-v
> >> +The format of the metadump file to be produced.
> >> +Valid values are 1 and 2.
> >> +The default metadump format is 1.
> >> +.TP
> >> .B \-w
> >> Prints warnings of inconsistent metadata encountered to stderr. Bad metadata
> >> is still copied.
> >> --
> >> 2.39.1
> >>
>
> --
> chandan
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH V3 14/23] mdrestore: Declare boolean variables with bool type
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (12 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 13/23] metadump: Add support for passing version option Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 15/23] mdrestore: Define and use struct mdrestore Chandan Babu R
` (9 subsequent siblings)
23 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
mdrestore/xfs_mdrestore.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
index 481dd00c..ca28c48e 100644
--- a/mdrestore/xfs_mdrestore.c
+++ b/mdrestore/xfs_mdrestore.c
@@ -7,9 +7,9 @@
#include "libxfs.h"
#include "xfs_metadump.h"
-static int show_progress = 0;
-static int show_info = 0;
-static int progress_since_warning = 0;
+static bool show_progress = false;
+static bool show_info = false;
+static bool progress_since_warning = false;
static void
fatal(const char *msg, ...)
@@ -35,7 +35,7 @@ print_progress(const char *fmt, ...)
printf("\r%-59s", buf);
fflush(stdout);
- progress_since_warning = 1;
+ progress_since_warning = true;
}
/*
@@ -202,10 +202,10 @@ main(
while ((c = getopt(argc, argv, "giV")) != EOF) {
switch (c) {
case 'g':
- show_progress = 1;
+ show_progress = true;
break;
case 'i':
- show_info = 1;
+ show_info = true;
break;
case 'V':
printf("%s version %s\n", progname, VERSION);
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH V3 15/23] mdrestore: Define and use struct mdrestore
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (13 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 14/23] mdrestore: Declare boolean variables with bool type Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 16/23] mdrestore: Detect metadump v1 magic before reading the header Chandan Babu R
` (8 subsequent siblings)
23 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
This commit collects all state tracking variables in a new "struct mdrestore"
structure. This is done to collect all the global variables in one place
rather than having them spread across the file. A new structure member of type
"struct mdrestore_ops *" will be added by a future commit to support the two
versions of metadump.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
mdrestore/xfs_mdrestore.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
index ca28c48e..97cb4e35 100644
--- a/mdrestore/xfs_mdrestore.c
+++ b/mdrestore/xfs_mdrestore.c
@@ -7,9 +7,11 @@
#include "libxfs.h"
#include "xfs_metadump.h"
-static bool show_progress = false;
-static bool show_info = false;
-static bool progress_since_warning = false;
+static struct mdrestore {
+ bool show_progress;
+ bool show_info;
+ bool progress_since_warning;
+} mdrestore;
static void
fatal(const char *msg, ...)
@@ -35,7 +37,7 @@ print_progress(const char *fmt, ...)
printf("\r%-59s", buf);
fflush(stdout);
- progress_since_warning = true;
+ mdrestore.progress_since_warning = true;
}
/*
@@ -127,7 +129,8 @@ perform_restore(
bytes_read = 0;
for (;;) {
- if (show_progress && (bytes_read & ((1 << 20) - 1)) == 0)
+ if (mdrestore.show_progress &&
+ (bytes_read & ((1 << 20) - 1)) == 0)
print_progress("%lld MB read", bytes_read >> 20);
for (cur_index = 0; cur_index < mb_count; cur_index++) {
@@ -158,7 +161,7 @@ perform_restore(
bytes_read += block_size + (mb_count << mbp->mb_blocklog);
}
- if (progress_since_warning)
+ if (mdrestore.progress_since_warning)
putchar('\n');
memset(block_buffer, 0, sb.sb_sectsize);
@@ -197,15 +200,19 @@ main(
int is_target_file;
struct xfs_metablock mb;
+ mdrestore.show_progress = false;
+ mdrestore.show_info = false;
+ mdrestore.progress_since_warning = false;
+
progname = basename(argv[0]);
while ((c = getopt(argc, argv, "giV")) != EOF) {
switch (c) {
case 'g':
- show_progress = true;
+ mdrestore.show_progress = true;
break;
case 'i':
- show_info = true;
+ mdrestore.show_info = true;
break;
case 'V':
printf("%s version %s\n", progname, VERSION);
@@ -219,7 +226,7 @@ main(
usage();
/* show_info without a target is ok */
- if (!show_info && argc - optind != 2)
+ if (!mdrestore.show_info && argc - optind != 2)
usage();
/*
@@ -243,7 +250,7 @@ main(
if (mb.mb_magic != cpu_to_be32(XFS_MD_MAGIC_V1))
fatal("specified file is not a metadata dump\n");
- if (show_info) {
+ if (mdrestore.show_info) {
if (mb.mb_info & XFS_METADUMP_INFO_FLAGS) {
printf("%s: %sobfuscated, %s log, %s metadata blocks\n",
argv[optind],
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH V3 16/23] mdrestore: Detect metadump v1 magic before reading the header
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (14 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 15/23] mdrestore: Define and use struct mdrestore Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 17/23] mdrestore: Add open_device(), read_header() and show_info() functions Chandan Babu R
` (7 subsequent siblings)
23 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
In order to support both v1 and v2 versions of metadump, mdrestore will have
to detect the format in which the metadump file has been stored on the disk
and then read the ondisk structures accordingly. In a step in that direction,
this commit splits the work of reading the metadump header from disk into two
parts,
1. Read the first 4 bytes containing the metadump magic code.
2. Read the remaining part of the header.
A future commit will take appropriate action based on the value of the magic
code.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
mdrestore/xfs_mdrestore.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
index 97cb4e35..ffa8274f 100644
--- a/mdrestore/xfs_mdrestore.c
+++ b/mdrestore/xfs_mdrestore.c
@@ -198,6 +198,7 @@ main(
int open_flags;
struct stat statbuf;
int is_target_file;
+ uint32_t magic;
struct xfs_metablock mb;
mdrestore.show_progress = false;
@@ -245,10 +246,21 @@ main(
fatal("cannot open source dump file\n");
}
- if (fread(&mb, sizeof(mb), 1, src_f) != 1)
- fatal("error reading from metadump file\n");
- if (mb.mb_magic != cpu_to_be32(XFS_MD_MAGIC_V1))
+ if (fread(&magic, sizeof(magic), 1, src_f) != 1)
+ fatal("Unable to read metadump magic from metadump file\n");
+
+ switch (be32_to_cpu(magic)) {
+ case XFS_MD_MAGIC_V1:
+ mb.mb_magic = cpu_to_be32(XFS_MD_MAGIC_V1);
+ if (fread((uint8_t *)&mb + sizeof(mb.mb_magic),
+ sizeof(mb) - sizeof(mb.mb_magic), 1,
+ src_f) != 1)
+ fatal("error reading from metadump file\n");
+ break;
+ default:
fatal("specified file is not a metadata dump\n");
+ break;
+ }
if (mdrestore.show_info) {
if (mb.mb_info & XFS_METADUMP_INFO_FLAGS) {
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH V3 17/23] mdrestore: Add open_device(), read_header() and show_info() functions
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (15 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 16/23] mdrestore: Detect metadump v1 magic before reading the header Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-08-01 23:54 ` Darrick J. Wong
2023-07-24 4:35 ` [PATCH V3 18/23] mdrestore: Introduce struct mdrestore_ops Chandan Babu R
` (6 subsequent siblings)
23 siblings, 1 reply; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
This commit moves functionality associated with opening the target device,
reading metadump header information and printing information about the
metadump into their respective functions. There are no functional changes made
by this commit.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
mdrestore/xfs_mdrestore.c | 141 +++++++++++++++++++++++---------------
1 file changed, 84 insertions(+), 57 deletions(-)
diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
index ffa8274f..d67a0629 100644
--- a/mdrestore/xfs_mdrestore.c
+++ b/mdrestore/xfs_mdrestore.c
@@ -6,6 +6,7 @@
#include "libxfs.h"
#include "xfs_metadump.h"
+#include <libfrog/platform.h>
static struct mdrestore {
bool show_progress;
@@ -40,8 +41,71 @@ print_progress(const char *fmt, ...)
mdrestore.progress_since_warning = true;
}
+static int
+open_device(
+ char *path,
+ bool *is_file)
+{
+ struct stat statbuf;
+ int open_flags;
+ int fd;
+
+ open_flags = O_RDWR;
+ *is_file = false;
+
+ if (stat(path, &statbuf) < 0) {
+ /* ok, assume it's a file and create it */
+ open_flags |= O_CREAT;
+ *is_file = true;
+ } else if (S_ISREG(statbuf.st_mode)) {
+ open_flags |= O_TRUNC;
+ *is_file = true;
+ } else if (platform_check_ismounted(path, NULL, &statbuf, 0)) {
+ /*
+ * check to make sure a filesystem isn't mounted on the device
+ */
+ fatal("a filesystem is mounted on target device \"%s\","
+ " cannot restore to a mounted filesystem.\n",
+ path);
+ }
+
+ fd = open(path, open_flags, 0644);
+ if (fd < 0)
+ fatal("couldn't open \"%s\"\n", path);
+
+ return fd;
+}
+
+static void
+read_header(
+ struct xfs_metablock *mb,
+ FILE *md_fp)
+{
+ mb->mb_magic = cpu_to_be32(XFS_MD_MAGIC_V1);
+
+ if (fread((uint8_t *)mb + sizeof(mb->mb_magic),
+ sizeof(*mb) - sizeof(mb->mb_magic), 1, md_fp) != 1)
+ fatal("error reading from metadump file\n");
+}
+
+static void
+show_info(
+ struct xfs_metablock *mb,
+ const char *md_file)
+{
+ if (mb->mb_info & XFS_METADUMP_INFO_FLAGS) {
+ printf("%s: %sobfuscated, %s log, %s metadata blocks\n",
+ md_file,
+ mb->mb_info & XFS_METADUMP_OBFUSCATED ? "":"not ",
+ mb->mb_info & XFS_METADUMP_DIRTYLOG ? "dirty":"clean",
+ mb->mb_info & XFS_METADUMP_FULLBLOCKS ? "full":"zeroed");
+ } else {
+ printf("%s: no informational flags present\n", md_file);
+ }
+}
+
/*
- * perform_restore() -- do the actual work to restore the metadump
+ * restore() -- do the actual work to restore the metadump
*
* @src_f: A FILE pointer to the source metadump
* @dst_fd: the file descriptor for the target file
@@ -51,9 +115,9 @@ print_progress(const char *fmt, ...)
* src_f should be positioned just past a read the previously validated metablock
*/
static void
-perform_restore(
- FILE *src_f,
- int dst_fd,
+restore(
+ FILE *md_fp,
+ int ddev_fd,
int is_target_file,
const struct xfs_metablock *mbp)
{
@@ -81,14 +145,15 @@ perform_restore(
block_index = (__be64 *)((char *)metablock + sizeof(xfs_metablock_t));
block_buffer = (char *)metablock + block_size;
- if (fread(block_index, block_size - sizeof(struct xfs_metablock), 1, src_f) != 1)
+ if (fread(block_index, block_size - sizeof(struct xfs_metablock), 1,
+ md_fp) != 1)
fatal("error reading from metadump file\n");
if (block_index[0] != 0)
fatal("first block is not the primary superblock\n");
- if (fread(block_buffer, mb_count << mbp->mb_blocklog, 1, src_f) != 1)
+ if (fread(block_buffer, mb_count << mbp->mb_blocklog, 1, md_fp) != 1)
fatal("error reading from metadump file\n");
libxfs_sb_from_disk(&sb, (struct xfs_dsb *)block_buffer);
@@ -111,7 +176,7 @@ perform_restore(
if (is_target_file) {
/* ensure regular files are correctly sized */
- if (ftruncate(dst_fd, sb.sb_dblocks * sb.sb_blocksize))
+ if (ftruncate(ddev_fd, sb.sb_dblocks * sb.sb_blocksize))
fatal("cannot set filesystem image size: %s\n",
strerror(errno));
} else {
@@ -121,7 +186,7 @@ perform_restore(
off64_t off;
off = sb.sb_dblocks * sb.sb_blocksize - sizeof(lb);
- if (pwrite(dst_fd, lb, sizeof(lb), off) < 0)
+ if (pwrite(ddev_fd, lb, sizeof(lb), off) < 0)
fatal("failed to write last block, is target too "
"small? (error: %s)\n", strerror(errno));
}
@@ -134,7 +199,7 @@ perform_restore(
print_progress("%lld MB read", bytes_read >> 20);
for (cur_index = 0; cur_index < mb_count; cur_index++) {
- if (pwrite(dst_fd, &block_buffer[cur_index <<
+ if (pwrite(ddev_fd, &block_buffer[cur_index <<
mbp->mb_blocklog], block_size,
be64_to_cpu(block_index[cur_index]) <<
BBSHIFT) < 0)
@@ -145,7 +210,7 @@ perform_restore(
if (mb_count < max_indices)
break;
- if (fread(metablock, block_size, 1, src_f) != 1)
+ if (fread(metablock, block_size, 1, md_fp) != 1)
fatal("error reading from metadump file\n");
mb_count = be16_to_cpu(metablock->mb_count);
@@ -155,7 +220,7 @@ perform_restore(
fatal("bad block count: %u\n", mb_count);
if (fread(block_buffer, mb_count << mbp->mb_blocklog,
- 1, src_f) != 1)
+ 1, md_fp) != 1)
fatal("error reading from metadump file\n");
bytes_read += block_size + (mb_count << mbp->mb_blocklog);
@@ -172,7 +237,7 @@ perform_restore(
offsetof(struct xfs_sb, sb_crc));
}
- if (pwrite(dst_fd, block_buffer, sb.sb_sectsize, 0) < 0)
+ if (pwrite(ddev_fd, block_buffer, sb.sb_sectsize, 0) < 0)
fatal("error writing primary superblock: %s\n", strerror(errno));
free(metablock);
@@ -185,8 +250,6 @@ usage(void)
exit(1);
}
-extern int platform_check_ismounted(char *, char *, struct stat *, int);
-
int
main(
int argc,
@@ -195,9 +258,7 @@ main(
FILE *src_f;
int dst_fd;
int c;
- int open_flags;
- struct stat statbuf;
- int is_target_file;
+ bool is_target_file;
uint32_t magic;
struct xfs_metablock mb;
@@ -231,8 +292,8 @@ main(
usage();
/*
- * open source and test if this really is a dump. The first metadump block
- * will be passed to perform_restore() which will continue to read the
+ * open source and test if this really is a dump. The first metadump
+ * block will be passed to restore() which will continue to read the
* file from this point. This avoids rewind the stream, which causes
* restore to fail when source was being read from stdin.
*/
@@ -251,11 +312,7 @@ main(
switch (be32_to_cpu(magic)) {
case XFS_MD_MAGIC_V1:
- mb.mb_magic = cpu_to_be32(XFS_MD_MAGIC_V1);
- if (fread((uint8_t *)&mb + sizeof(mb.mb_magic),
- sizeof(mb) - sizeof(mb.mb_magic), 1,
- src_f) != 1)
- fatal("error reading from metadump file\n");
+ read_header(&mb, src_f);
break;
default:
fatal("specified file is not a metadata dump\n");
@@ -263,16 +320,7 @@ main(
}
if (mdrestore.show_info) {
- if (mb.mb_info & XFS_METADUMP_INFO_FLAGS) {
- printf("%s: %sobfuscated, %s log, %s metadata blocks\n",
- argv[optind],
- mb.mb_info & XFS_METADUMP_OBFUSCATED ? "":"not ",
- mb.mb_info & XFS_METADUMP_DIRTYLOG ? "dirty":"clean",
- mb.mb_info & XFS_METADUMP_FULLBLOCKS ? "full":"zeroed");
- } else {
- printf("%s: no informational flags present\n",
- argv[optind]);
- }
+ show_info(&mb, argv[optind]);
if (argc - optind == 1)
exit(0);
@@ -281,30 +329,9 @@ main(
optind++;
/* check and open target */
- open_flags = O_RDWR;
- is_target_file = 0;
- if (stat(argv[optind], &statbuf) < 0) {
- /* ok, assume it's a file and create it */
- open_flags |= O_CREAT;
- is_target_file = 1;
- } else if (S_ISREG(statbuf.st_mode)) {
- open_flags |= O_TRUNC;
- is_target_file = 1;
- } else {
- /*
- * check to make sure a filesystem isn't mounted on the device
- */
- if (platform_check_ismounted(argv[optind], NULL, &statbuf, 0))
- fatal("a filesystem is mounted on target device \"%s\","
- " cannot restore to a mounted filesystem.\n",
- argv[optind]);
- }
-
- dst_fd = open(argv[optind], open_flags, 0644);
- if (dst_fd < 0)
- fatal("couldn't open target \"%s\"\n", argv[optind]);
+ dst_fd = open_device(argv[optind], &is_target_file);
- perform_restore(src_f, dst_fd, is_target_file, &mb);
+ restore(src_f, dst_fd, is_target_file, &mb);
close(dst_fd);
if (src_f != stdin)
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH V3 17/23] mdrestore: Add open_device(), read_header() and show_info() functions
2023-07-24 4:35 ` [PATCH V3 17/23] mdrestore: Add open_device(), read_header() and show_info() functions Chandan Babu R
@ 2023-08-01 23:54 ` Darrick J. Wong
0 siblings, 0 replies; 41+ messages in thread
From: Darrick J. Wong @ 2023-08-01 23:54 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs, cem
On Mon, Jul 24, 2023 at 10:05:21AM +0530, Chandan Babu R wrote:
> This commit moves functionality associated with opening the target device,
> reading metadump header information and printing information about the
> metadump into their respective functions. There are no functional changes made
> by this commit.
>
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
Looks correct,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
--D
> ---
> mdrestore/xfs_mdrestore.c | 141 +++++++++++++++++++++++---------------
> 1 file changed, 84 insertions(+), 57 deletions(-)
>
> diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
> index ffa8274f..d67a0629 100644
> --- a/mdrestore/xfs_mdrestore.c
> +++ b/mdrestore/xfs_mdrestore.c
> @@ -6,6 +6,7 @@
>
> #include "libxfs.h"
> #include "xfs_metadump.h"
> +#include <libfrog/platform.h>
>
> static struct mdrestore {
> bool show_progress;
> @@ -40,8 +41,71 @@ print_progress(const char *fmt, ...)
> mdrestore.progress_since_warning = true;
> }
>
> +static int
> +open_device(
> + char *path,
> + bool *is_file)
> +{
> + struct stat statbuf;
> + int open_flags;
> + int fd;
> +
> + open_flags = O_RDWR;
> + *is_file = false;
> +
> + if (stat(path, &statbuf) < 0) {
> + /* ok, assume it's a file and create it */
> + open_flags |= O_CREAT;
> + *is_file = true;
> + } else if (S_ISREG(statbuf.st_mode)) {
> + open_flags |= O_TRUNC;
> + *is_file = true;
> + } else if (platform_check_ismounted(path, NULL, &statbuf, 0)) {
> + /*
> + * check to make sure a filesystem isn't mounted on the device
> + */
> + fatal("a filesystem is mounted on target device \"%s\","
> + " cannot restore to a mounted filesystem.\n",
> + path);
> + }
> +
> + fd = open(path, open_flags, 0644);
> + if (fd < 0)
> + fatal("couldn't open \"%s\"\n", path);
> +
> + return fd;
> +}
> +
> +static void
> +read_header(
> + struct xfs_metablock *mb,
> + FILE *md_fp)
> +{
> + mb->mb_magic = cpu_to_be32(XFS_MD_MAGIC_V1);
> +
> + if (fread((uint8_t *)mb + sizeof(mb->mb_magic),
> + sizeof(*mb) - sizeof(mb->mb_magic), 1, md_fp) != 1)
> + fatal("error reading from metadump file\n");
> +}
> +
> +static void
> +show_info(
> + struct xfs_metablock *mb,
> + const char *md_file)
> +{
> + if (mb->mb_info & XFS_METADUMP_INFO_FLAGS) {
> + printf("%s: %sobfuscated, %s log, %s metadata blocks\n",
> + md_file,
> + mb->mb_info & XFS_METADUMP_OBFUSCATED ? "":"not ",
> + mb->mb_info & XFS_METADUMP_DIRTYLOG ? "dirty":"clean",
> + mb->mb_info & XFS_METADUMP_FULLBLOCKS ? "full":"zeroed");
> + } else {
> + printf("%s: no informational flags present\n", md_file);
> + }
> +}
> +
> /*
> - * perform_restore() -- do the actual work to restore the metadump
> + * restore() -- do the actual work to restore the metadump
> *
> * @src_f: A FILE pointer to the source metadump
> * @dst_fd: the file descriptor for the target file
> @@ -51,9 +115,9 @@ print_progress(const char *fmt, ...)
> * src_f should be positioned just past a read the previously validated metablock
> */
> static void
> -perform_restore(
> - FILE *src_f,
> - int dst_fd,
> +restore(
> + FILE *md_fp,
> + int ddev_fd,
> int is_target_file,
> const struct xfs_metablock *mbp)
> {
> @@ -81,14 +145,15 @@ perform_restore(
> block_index = (__be64 *)((char *)metablock + sizeof(xfs_metablock_t));
> block_buffer = (char *)metablock + block_size;
>
> - if (fread(block_index, block_size - sizeof(struct xfs_metablock), 1, src_f) != 1)
> + if (fread(block_index, block_size - sizeof(struct xfs_metablock), 1,
> + md_fp) != 1)
> fatal("error reading from metadump file\n");
>
> if (block_index[0] != 0)
> fatal("first block is not the primary superblock\n");
>
>
> - if (fread(block_buffer, mb_count << mbp->mb_blocklog, 1, src_f) != 1)
> + if (fread(block_buffer, mb_count << mbp->mb_blocklog, 1, md_fp) != 1)
> fatal("error reading from metadump file\n");
>
> libxfs_sb_from_disk(&sb, (struct xfs_dsb *)block_buffer);
> @@ -111,7 +176,7 @@ perform_restore(
> if (is_target_file) {
> /* ensure regular files are correctly sized */
>
> - if (ftruncate(dst_fd, sb.sb_dblocks * sb.sb_blocksize))
> + if (ftruncate(ddev_fd, sb.sb_dblocks * sb.sb_blocksize))
> fatal("cannot set filesystem image size: %s\n",
> strerror(errno));
> } else {
> @@ -121,7 +186,7 @@ perform_restore(
> off64_t off;
>
> off = sb.sb_dblocks * sb.sb_blocksize - sizeof(lb);
> - if (pwrite(dst_fd, lb, sizeof(lb), off) < 0)
> + if (pwrite(ddev_fd, lb, sizeof(lb), off) < 0)
> fatal("failed to write last block, is target too "
> "small? (error: %s)\n", strerror(errno));
> }
> @@ -134,7 +199,7 @@ perform_restore(
> print_progress("%lld MB read", bytes_read >> 20);
>
> for (cur_index = 0; cur_index < mb_count; cur_index++) {
> - if (pwrite(dst_fd, &block_buffer[cur_index <<
> + if (pwrite(ddev_fd, &block_buffer[cur_index <<
> mbp->mb_blocklog], block_size,
> be64_to_cpu(block_index[cur_index]) <<
> BBSHIFT) < 0)
> @@ -145,7 +210,7 @@ perform_restore(
> if (mb_count < max_indices)
> break;
>
> - if (fread(metablock, block_size, 1, src_f) != 1)
> + if (fread(metablock, block_size, 1, md_fp) != 1)
> fatal("error reading from metadump file\n");
>
> mb_count = be16_to_cpu(metablock->mb_count);
> @@ -155,7 +220,7 @@ perform_restore(
> fatal("bad block count: %u\n", mb_count);
>
> if (fread(block_buffer, mb_count << mbp->mb_blocklog,
> - 1, src_f) != 1)
> + 1, md_fp) != 1)
> fatal("error reading from metadump file\n");
>
> bytes_read += block_size + (mb_count << mbp->mb_blocklog);
> @@ -172,7 +237,7 @@ perform_restore(
> offsetof(struct xfs_sb, sb_crc));
> }
>
> - if (pwrite(dst_fd, block_buffer, sb.sb_sectsize, 0) < 0)
> + if (pwrite(ddev_fd, block_buffer, sb.sb_sectsize, 0) < 0)
> fatal("error writing primary superblock: %s\n", strerror(errno));
>
> free(metablock);
> @@ -185,8 +250,6 @@ usage(void)
> exit(1);
> }
>
> -extern int platform_check_ismounted(char *, char *, struct stat *, int);
> -
> int
> main(
> int argc,
> @@ -195,9 +258,7 @@ main(
> FILE *src_f;
> int dst_fd;
> int c;
> - int open_flags;
> - struct stat statbuf;
> - int is_target_file;
> + bool is_target_file;
> uint32_t magic;
> struct xfs_metablock mb;
>
> @@ -231,8 +292,8 @@ main(
> usage();
>
> /*
> - * open source and test if this really is a dump. The first metadump block
> - * will be passed to perform_restore() which will continue to read the
> + * open source and test if this really is a dump. The first metadump
> + * block will be passed to restore() which will continue to read the
> * file from this point. This avoids rewind the stream, which causes
> * restore to fail when source was being read from stdin.
> */
> @@ -251,11 +312,7 @@ main(
>
> switch (be32_to_cpu(magic)) {
> case XFS_MD_MAGIC_V1:
> - mb.mb_magic = cpu_to_be32(XFS_MD_MAGIC_V1);
> - if (fread((uint8_t *)&mb + sizeof(mb.mb_magic),
> - sizeof(mb) - sizeof(mb.mb_magic), 1,
> - src_f) != 1)
> - fatal("error reading from metadump file\n");
> + read_header(&mb, src_f);
> break;
> default:
> fatal("specified file is not a metadata dump\n");
> @@ -263,16 +320,7 @@ main(
> }
>
> if (mdrestore.show_info) {
> - if (mb.mb_info & XFS_METADUMP_INFO_FLAGS) {
> - printf("%s: %sobfuscated, %s log, %s metadata blocks\n",
> - argv[optind],
> - mb.mb_info & XFS_METADUMP_OBFUSCATED ? "":"not ",
> - mb.mb_info & XFS_METADUMP_DIRTYLOG ? "dirty":"clean",
> - mb.mb_info & XFS_METADUMP_FULLBLOCKS ? "full":"zeroed");
> - } else {
> - printf("%s: no informational flags present\n",
> - argv[optind]);
> - }
> + show_info(&mb, argv[optind]);
>
> if (argc - optind == 1)
> exit(0);
> @@ -281,30 +329,9 @@ main(
> optind++;
>
> /* check and open target */
> - open_flags = O_RDWR;
> - is_target_file = 0;
> - if (stat(argv[optind], &statbuf) < 0) {
> - /* ok, assume it's a file and create it */
> - open_flags |= O_CREAT;
> - is_target_file = 1;
> - } else if (S_ISREG(statbuf.st_mode)) {
> - open_flags |= O_TRUNC;
> - is_target_file = 1;
> - } else {
> - /*
> - * check to make sure a filesystem isn't mounted on the device
> - */
> - if (platform_check_ismounted(argv[optind], NULL, &statbuf, 0))
> - fatal("a filesystem is mounted on target device \"%s\","
> - " cannot restore to a mounted filesystem.\n",
> - argv[optind]);
> - }
> -
> - dst_fd = open(argv[optind], open_flags, 0644);
> - if (dst_fd < 0)
> - fatal("couldn't open target \"%s\"\n", argv[optind]);
> + dst_fd = open_device(argv[optind], &is_target_file);
>
> - perform_restore(src_f, dst_fd, is_target_file, &mb);
> + restore(src_f, dst_fd, is_target_file, &mb);
>
> close(dst_fd);
> if (src_f != stdin)
> --
> 2.39.1
>
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH V3 18/23] mdrestore: Introduce struct mdrestore_ops
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (16 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 17/23] mdrestore: Add open_device(), read_header() and show_info() functions Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 19/23] mdrestore: Replace metadump header pointer argument with a union pointer Chandan Babu R
` (5 subsequent siblings)
23 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
We will need two sets of functions to work with two versions of metadump
formats. This commit adds the definition for 'struct mdrestore_ops' to hold
pointers to version specific mdrestore functions.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
mdrestore/xfs_mdrestore.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
index d67a0629..53c5f68e 100644
--- a/mdrestore/xfs_mdrestore.c
+++ b/mdrestore/xfs_mdrestore.c
@@ -8,10 +8,23 @@
#include "xfs_metadump.h"
#include <libfrog/platform.h>
+union mdrestore_headers {
+ __be32 magic;
+ struct xfs_metablock v1;
+};
+
+struct mdrestore_ops {
+ void (*read_header)(union mdrestore_headers *header, FILE *md_fp);
+ void (*show_info)(union mdrestore_headers *header, const char *md_file);
+ void (*restore)(union mdrestore_headers *header, FILE *md_fp,
+ int ddev_fd, bool is_target_file);
+};
+
static struct mdrestore {
- bool show_progress;
- bool show_info;
- bool progress_since_warning;
+ struct mdrestore_ops *mdrops;
+ bool show_progress;
+ bool show_info;
+ bool progress_since_warning;
} mdrestore;
static void
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH V3 19/23] mdrestore: Replace metadump header pointer argument with a union pointer
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (17 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 18/23] mdrestore: Introduce struct mdrestore_ops Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-08-02 0:01 ` Darrick J. Wong
2023-07-24 4:35 ` [PATCH V3 20/23] mdrestore: Introduce mdrestore v1 operations Chandan Babu R
` (4 subsequent siblings)
23 siblings, 1 reply; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
We will need two variants of read_header(), show_info() and restore() helper
functions to support two versions of metadump formats. To this end, A future
commit will introduce a vector of function pointers to work with the two
metadump formats. To have a common function signature for the function
pointers, this commit replaces the first argument of the previously listed
function pointers from "struct xfs_metablock *" with "union
mdrestore_headers *".
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
mdrestore/xfs_mdrestore.c | 61 +++++++++++++++++++--------------------
1 file changed, 29 insertions(+), 32 deletions(-)
diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
index 53c5f68e..4d1bbf28 100644
--- a/mdrestore/xfs_mdrestore.c
+++ b/mdrestore/xfs_mdrestore.c
@@ -91,27 +91,25 @@ open_device(
static void
read_header(
- struct xfs_metablock *mb,
+ union mdrestore_headers *h,
FILE *md_fp)
{
- mb->mb_magic = cpu_to_be32(XFS_MD_MAGIC_V1);
-
- if (fread((uint8_t *)mb + sizeof(mb->mb_magic),
- sizeof(*mb) - sizeof(mb->mb_magic), 1, md_fp) != 1)
+ if (fread((uint8_t *)&(h->v1.mb_count),
+ sizeof(h->v1) - sizeof(h->magic), 1, md_fp) != 1)
fatal("error reading from metadump file\n");
}
static void
show_info(
- struct xfs_metablock *mb,
+ union mdrestore_headers *h,
const char *md_file)
{
- if (mb->mb_info & XFS_METADUMP_INFO_FLAGS) {
+ if (h->v1.mb_info & XFS_METADUMP_INFO_FLAGS) {
printf("%s: %sobfuscated, %s log, %s metadata blocks\n",
md_file,
- mb->mb_info & XFS_METADUMP_OBFUSCATED ? "":"not ",
- mb->mb_info & XFS_METADUMP_DIRTYLOG ? "dirty":"clean",
- mb->mb_info & XFS_METADUMP_FULLBLOCKS ? "full":"zeroed");
+ h->v1.mb_info & XFS_METADUMP_OBFUSCATED ? "":"not ",
+ h->v1.mb_info & XFS_METADUMP_DIRTYLOG ? "dirty":"clean",
+ h->v1.mb_info & XFS_METADUMP_FULLBLOCKS ? "full":"zeroed");
} else {
printf("%s: no informational flags present\n", md_file);
}
@@ -129,10 +127,10 @@ show_info(
*/
static void
restore(
+ union mdrestore_headers *h,
FILE *md_fp,
int ddev_fd,
- int is_target_file,
- const struct xfs_metablock *mbp)
+ int is_target_file)
{
struct xfs_metablock *metablock; /* header + index + blocks */
__be64 *block_index;
@@ -144,14 +142,14 @@ restore(
xfs_sb_t sb;
int64_t bytes_read;
- block_size = 1 << mbp->mb_blocklog;
+ block_size = 1 << h->v1.mb_blocklog;
max_indices = (block_size - sizeof(xfs_metablock_t)) / sizeof(__be64);
metablock = (xfs_metablock_t *)calloc(max_indices + 1, block_size);
if (metablock == NULL)
fatal("memory allocation failure\n");
- mb_count = be16_to_cpu(mbp->mb_count);
+ mb_count = be16_to_cpu(h->v1.mb_count);
if (mb_count == 0 || mb_count > max_indices)
fatal("bad block count: %u\n", mb_count);
@@ -165,8 +163,7 @@ restore(
if (block_index[0] != 0)
fatal("first block is not the primary superblock\n");
-
- if (fread(block_buffer, mb_count << mbp->mb_blocklog, 1, md_fp) != 1)
+ if (fread(block_buffer, mb_count << h->v1.mb_blocklog, 1, md_fp) != 1)
fatal("error reading from metadump file\n");
libxfs_sb_from_disk(&sb, (struct xfs_dsb *)block_buffer);
@@ -213,7 +210,7 @@ restore(
for (cur_index = 0; cur_index < mb_count; cur_index++) {
if (pwrite(ddev_fd, &block_buffer[cur_index <<
- mbp->mb_blocklog], block_size,
+ h->v1.mb_blocklog], block_size,
be64_to_cpu(block_index[cur_index]) <<
BBSHIFT) < 0)
fatal("error writing block %llu: %s\n",
@@ -232,11 +229,11 @@ restore(
if (mb_count > max_indices)
fatal("bad block count: %u\n", mb_count);
- if (fread(block_buffer, mb_count << mbp->mb_blocklog,
+ if (fread(block_buffer, mb_count << h->v1.mb_blocklog,
1, md_fp) != 1)
fatal("error reading from metadump file\n");
- bytes_read += block_size + (mb_count << mbp->mb_blocklog);
+ bytes_read += block_size + (mb_count << h->v1.mb_blocklog);
}
if (mdrestore.progress_since_warning)
@@ -265,15 +262,14 @@ usage(void)
int
main(
- int argc,
- char **argv)
+ int argc,
+ char **argv)
{
- FILE *src_f;
- int dst_fd;
- int c;
- bool is_target_file;
- uint32_t magic;
- struct xfs_metablock mb;
+ union mdrestore_headers headers;
+ FILE *src_f;
+ int dst_fd;
+ int c;
+ bool is_target_file;
mdrestore.show_progress = false;
mdrestore.show_info = false;
@@ -320,20 +316,21 @@ main(
fatal("cannot open source dump file\n");
}
- if (fread(&magic, sizeof(magic), 1, src_f) != 1)
+ if (fread(&headers.magic, sizeof(headers.magic), 1, src_f) != 1)
fatal("Unable to read metadump magic from metadump file\n");
- switch (be32_to_cpu(magic)) {
+ switch (be32_to_cpu(headers.magic)) {
case XFS_MD_MAGIC_V1:
- read_header(&mb, src_f);
break;
default:
fatal("specified file is not a metadata dump\n");
break;
}
+ read_header(&headers, src_f);
+
if (mdrestore.show_info) {
- show_info(&mb, argv[optind]);
+ show_info(&headers, argv[optind]);
if (argc - optind == 1)
exit(0);
@@ -344,7 +341,7 @@ main(
/* check and open target */
dst_fd = open_device(argv[optind], &is_target_file);
- restore(src_f, dst_fd, is_target_file, &mb);
+ restore(&headers, src_f, dst_fd, is_target_file);
close(dst_fd);
if (src_f != stdin)
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH V3 19/23] mdrestore: Replace metadump header pointer argument with a union pointer
2023-07-24 4:35 ` [PATCH V3 19/23] mdrestore: Replace metadump header pointer argument with a union pointer Chandan Babu R
@ 2023-08-02 0:01 ` Darrick J. Wong
2023-08-02 13:17 ` Chandan Babu R
0 siblings, 1 reply; 41+ messages in thread
From: Darrick J. Wong @ 2023-08-02 0:01 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs, cem
On Mon, Jul 24, 2023 at 10:05:23AM +0530, Chandan Babu R wrote:
> We will need two variants of read_header(), show_info() and restore() helper
> functions to support two versions of metadump formats. To this end, A future
> commit will introduce a vector of function pointers to work with the two
> metadump formats. To have a common function signature for the function
> pointers, this commit replaces the first argument of the previously listed
> function pointers from "struct xfs_metablock *" with "union
> mdrestore_headers *".
>
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
The overall code changes look fine to me, but I'm a little mystified why
the *previous* patch introduces union mdrestore_headers and the
mdrestore ops without using either of them.
IOWs, I think you could delete patch 18, move the union definition into
this patch, and move the mdrestore ops definitions that used to be in
patch 18 into patch 20.
--D
> ---
> mdrestore/xfs_mdrestore.c | 61 +++++++++++++++++++--------------------
> 1 file changed, 29 insertions(+), 32 deletions(-)
>
> diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
> index 53c5f68e..4d1bbf28 100644
> --- a/mdrestore/xfs_mdrestore.c
> +++ b/mdrestore/xfs_mdrestore.c
> @@ -91,27 +91,25 @@ open_device(
>
> static void
> read_header(
> - struct xfs_metablock *mb,
> + union mdrestore_headers *h,
> FILE *md_fp)
> {
> - mb->mb_magic = cpu_to_be32(XFS_MD_MAGIC_V1);
> -
> - if (fread((uint8_t *)mb + sizeof(mb->mb_magic),
> - sizeof(*mb) - sizeof(mb->mb_magic), 1, md_fp) != 1)
> + if (fread((uint8_t *)&(h->v1.mb_count),
> + sizeof(h->v1) - sizeof(h->magic), 1, md_fp) != 1)
> fatal("error reading from metadump file\n");
> }
>
> static void
> show_info(
> - struct xfs_metablock *mb,
> + union mdrestore_headers *h,
> const char *md_file)
> {
> - if (mb->mb_info & XFS_METADUMP_INFO_FLAGS) {
> + if (h->v1.mb_info & XFS_METADUMP_INFO_FLAGS) {
> printf("%s: %sobfuscated, %s log, %s metadata blocks\n",
> md_file,
> - mb->mb_info & XFS_METADUMP_OBFUSCATED ? "":"not ",
> - mb->mb_info & XFS_METADUMP_DIRTYLOG ? "dirty":"clean",
> - mb->mb_info & XFS_METADUMP_FULLBLOCKS ? "full":"zeroed");
> + h->v1.mb_info & XFS_METADUMP_OBFUSCATED ? "":"not ",
> + h->v1.mb_info & XFS_METADUMP_DIRTYLOG ? "dirty":"clean",
> + h->v1.mb_info & XFS_METADUMP_FULLBLOCKS ? "full":"zeroed");
> } else {
> printf("%s: no informational flags present\n", md_file);
> }
> @@ -129,10 +127,10 @@ show_info(
> */
> static void
> restore(
> + union mdrestore_headers *h,
> FILE *md_fp,
> int ddev_fd,
> - int is_target_file,
> - const struct xfs_metablock *mbp)
> + int is_target_file)
> {
> struct xfs_metablock *metablock; /* header + index + blocks */
> __be64 *block_index;
> @@ -144,14 +142,14 @@ restore(
> xfs_sb_t sb;
> int64_t bytes_read;
>
> - block_size = 1 << mbp->mb_blocklog;
> + block_size = 1 << h->v1.mb_blocklog;
> max_indices = (block_size - sizeof(xfs_metablock_t)) / sizeof(__be64);
>
> metablock = (xfs_metablock_t *)calloc(max_indices + 1, block_size);
> if (metablock == NULL)
> fatal("memory allocation failure\n");
>
> - mb_count = be16_to_cpu(mbp->mb_count);
> + mb_count = be16_to_cpu(h->v1.mb_count);
> if (mb_count == 0 || mb_count > max_indices)
> fatal("bad block count: %u\n", mb_count);
>
> @@ -165,8 +163,7 @@ restore(
> if (block_index[0] != 0)
> fatal("first block is not the primary superblock\n");
>
> -
> - if (fread(block_buffer, mb_count << mbp->mb_blocklog, 1, md_fp) != 1)
> + if (fread(block_buffer, mb_count << h->v1.mb_blocklog, 1, md_fp) != 1)
> fatal("error reading from metadump file\n");
>
> libxfs_sb_from_disk(&sb, (struct xfs_dsb *)block_buffer);
> @@ -213,7 +210,7 @@ restore(
>
> for (cur_index = 0; cur_index < mb_count; cur_index++) {
> if (pwrite(ddev_fd, &block_buffer[cur_index <<
> - mbp->mb_blocklog], block_size,
> + h->v1.mb_blocklog], block_size,
> be64_to_cpu(block_index[cur_index]) <<
> BBSHIFT) < 0)
> fatal("error writing block %llu: %s\n",
> @@ -232,11 +229,11 @@ restore(
> if (mb_count > max_indices)
> fatal("bad block count: %u\n", mb_count);
>
> - if (fread(block_buffer, mb_count << mbp->mb_blocklog,
> + if (fread(block_buffer, mb_count << h->v1.mb_blocklog,
> 1, md_fp) != 1)
> fatal("error reading from metadump file\n");
>
> - bytes_read += block_size + (mb_count << mbp->mb_blocklog);
> + bytes_read += block_size + (mb_count << h->v1.mb_blocklog);
> }
>
> if (mdrestore.progress_since_warning)
> @@ -265,15 +262,14 @@ usage(void)
>
> int
> main(
> - int argc,
> - char **argv)
> + int argc,
> + char **argv)
> {
> - FILE *src_f;
> - int dst_fd;
> - int c;
> - bool is_target_file;
> - uint32_t magic;
> - struct xfs_metablock mb;
> + union mdrestore_headers headers;
> + FILE *src_f;
> + int dst_fd;
> + int c;
> + bool is_target_file;
>
> mdrestore.show_progress = false;
> mdrestore.show_info = false;
> @@ -320,20 +316,21 @@ main(
> fatal("cannot open source dump file\n");
> }
>
> - if (fread(&magic, sizeof(magic), 1, src_f) != 1)
> + if (fread(&headers.magic, sizeof(headers.magic), 1, src_f) != 1)
> fatal("Unable to read metadump magic from metadump file\n");
>
> - switch (be32_to_cpu(magic)) {
> + switch (be32_to_cpu(headers.magic)) {
> case XFS_MD_MAGIC_V1:
> - read_header(&mb, src_f);
> break;
> default:
> fatal("specified file is not a metadata dump\n");
> break;
> }
>
> + read_header(&headers, src_f);
> +
> if (mdrestore.show_info) {
> - show_info(&mb, argv[optind]);
> + show_info(&headers, argv[optind]);
>
> if (argc - optind == 1)
> exit(0);
> @@ -344,7 +341,7 @@ main(
> /* check and open target */
> dst_fd = open_device(argv[optind], &is_target_file);
>
> - restore(src_f, dst_fd, is_target_file, &mb);
> + restore(&headers, src_f, dst_fd, is_target_file);
>
> close(dst_fd);
> if (src_f != stdin)
> --
> 2.39.1
>
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH V3 19/23] mdrestore: Replace metadump header pointer argument with a union pointer
2023-08-02 0:01 ` Darrick J. Wong
@ 2023-08-02 13:17 ` Chandan Babu R
0 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-08-02 13:17 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: linux-xfs, cem
On Tue, Aug 01, 2023 at 05:01:46 PM -0700, Darrick J. Wong wrote:
> On Mon, Jul 24, 2023 at 10:05:23AM +0530, Chandan Babu R wrote:
>> We will need two variants of read_header(), show_info() and restore() helper
>> functions to support two versions of metadump formats. To this end, A future
>> commit will introduce a vector of function pointers to work with the two
>> metadump formats. To have a common function signature for the function
>> pointers, this commit replaces the first argument of the previously listed
>> function pointers from "struct xfs_metablock *" with "union
>> mdrestore_headers *".
>>
>> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
>
> The overall code changes look fine to me, but I'm a little mystified why
> the *previous* patch introduces union mdrestore_headers and the
> mdrestore ops without using either of them.
>
> IOWs, I think you could delete patch 18, move the union definition into
> this patch, and move the mdrestore ops definitions that used to be in
> patch 18 into patch 20.
>
You are right. I will make the changes suggested above.
--
chandan
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH V3 20/23] mdrestore: Introduce mdrestore v1 operations
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (18 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 19/23] mdrestore: Replace metadump header pointer argument with a union pointer Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 21/23] mdrestore: Extract target device size verification into a function Chandan Babu R
` (3 subsequent siblings)
23 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
In order to indicate the version of metadump files that they can work with,
this commit renames read_header(), show_info() and restore() functions to
read_header_v1(), show_info_v1() and restore_v1() respectively.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
mdrestore/xfs_mdrestore.c | 37 +++++++++++++++++--------------------
1 file changed, 17 insertions(+), 20 deletions(-)
diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
index 4d1bbf28..b247a4bf 100644
--- a/mdrestore/xfs_mdrestore.c
+++ b/mdrestore/xfs_mdrestore.c
@@ -90,7 +90,7 @@ open_device(
}
static void
-read_header(
+read_header_v1(
union mdrestore_headers *h,
FILE *md_fp)
{
@@ -100,7 +100,7 @@ read_header(
}
static void
-show_info(
+show_info_v1(
union mdrestore_headers *h,
const char *md_file)
{
@@ -115,22 +115,12 @@ show_info(
}
}
-/*
- * restore() -- do the actual work to restore the metadump
- *
- * @src_f: A FILE pointer to the source metadump
- * @dst_fd: the file descriptor for the target file
- * @is_target_file: designates whether the target is a regular file
- * @mbp: pointer to metadump's first xfs_metablock, read and verified by the caller
- *
- * src_f should be positioned just past a read the previously validated metablock
- */
static void
-restore(
+restore_v1(
union mdrestore_headers *h,
FILE *md_fp,
int ddev_fd,
- int is_target_file)
+ bool is_target_file)
{
struct xfs_metablock *metablock; /* header + index + blocks */
__be64 *block_index;
@@ -253,6 +243,12 @@ restore(
free(metablock);
}
+static struct mdrestore_ops mdrestore_ops_v1 = {
+ .read_header = read_header_v1,
+ .show_info = show_info_v1,
+ .restore = restore_v1,
+};
+
static void
usage(void)
{
@@ -302,9 +298,9 @@ main(
/*
* open source and test if this really is a dump. The first metadump
- * block will be passed to restore() which will continue to read the
- * file from this point. This avoids rewind the stream, which causes
- * restore to fail when source was being read from stdin.
+ * block will be passed to mdrestore_ops->restore() which will continue
+ * to read the file from this point. This avoids rewind the stream,
+ * which causes restore to fail when source was being read from stdin.
*/
if (strcmp(argv[optind], "-") == 0) {
src_f = stdin;
@@ -321,16 +317,17 @@ main(
switch (be32_to_cpu(headers.magic)) {
case XFS_MD_MAGIC_V1:
+ mdrestore.mdrops = &mdrestore_ops_v1;
break;
default:
fatal("specified file is not a metadata dump\n");
break;
}
- read_header(&headers, src_f);
+ mdrestore.mdrops->read_header(&headers, src_f);
if (mdrestore.show_info) {
- show_info(&headers, argv[optind]);
+ mdrestore.mdrops->show_info(&headers, argv[optind]);
if (argc - optind == 1)
exit(0);
@@ -341,7 +338,7 @@ main(
/* check and open target */
dst_fd = open_device(argv[optind], &is_target_file);
- restore(&headers, src_f, dst_fd, is_target_file);
+ mdrestore.mdrops->restore(&headers, src_f, dst_fd, is_target_file);
close(dst_fd);
if (src_f != stdin)
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH V3 21/23] mdrestore: Extract target device size verification into a function
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (19 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 20/23] mdrestore: Introduce mdrestore v1 operations Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-07-24 4:35 ` [PATCH V3 22/23] mdrestore: Define mdrestore ops for v2 format Chandan Babu R
` (2 subsequent siblings)
23 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
A future commit will need to perform the device size verification on an
external log device. In preparation for this, this commit extracts the
relevant portions into a new function. No functional changes have been
introduced.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
mdrestore/xfs_mdrestore.c | 43 +++++++++++++++++++++++----------------
1 file changed, 26 insertions(+), 17 deletions(-)
diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
index b247a4bf..0fdbfce7 100644
--- a/mdrestore/xfs_mdrestore.c
+++ b/mdrestore/xfs_mdrestore.c
@@ -89,6 +89,30 @@ open_device(
return fd;
}
+static void
+verify_device_size(
+ int dev_fd,
+ bool is_file,
+ xfs_rfsblock_t nr_blocks,
+ uint32_t blocksize)
+{
+ if (is_file) {
+ /* ensure regular files are correctly sized */
+ if (ftruncate(dev_fd, nr_blocks * blocksize))
+ fatal("cannot set filesystem image size: %s\n",
+ strerror(errno));
+ } else {
+ /* ensure device is sufficiently large enough */
+ char lb[XFS_MAX_SECTORSIZE] = { 0 };
+ off64_t off;
+
+ off = nr_blocks * blocksize - sizeof(lb);
+ if (pwrite(dev_fd, lb, sizeof(lb), off) < 0)
+ fatal("failed to write last block, is target too "
+ "small? (error: %s)\n", strerror(errno));
+ }
+}
+
static void
read_header_v1(
union mdrestore_headers *h,
@@ -173,23 +197,8 @@ restore_v1(
((struct xfs_dsb*)block_buffer)->sb_inprogress = 1;
- if (is_target_file) {
- /* ensure regular files are correctly sized */
-
- if (ftruncate(ddev_fd, sb.sb_dblocks * sb.sb_blocksize))
- fatal("cannot set filesystem image size: %s\n",
- strerror(errno));
- } else {
- /* ensure device is sufficiently large enough */
-
- char lb[XFS_MAX_SECTORSIZE] = { 0 };
- off64_t off;
-
- off = sb.sb_dblocks * sb.sb_blocksize - sizeof(lb);
- if (pwrite(ddev_fd, lb, sizeof(lb), off) < 0)
- fatal("failed to write last block, is target too "
- "small? (error: %s)\n", strerror(errno));
- }
+ verify_device_size(ddev_fd, is_target_file, sb.sb_dblocks,
+ sb.sb_blocksize);
bytes_read = 0;
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH V3 22/23] mdrestore: Define mdrestore ops for v2 format
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (20 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 21/23] mdrestore: Extract target device size verification into a function Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-08-02 17:16 ` Darrick J. Wong
2023-07-24 4:35 ` [PATCH V3 23/23] mdrestore: Add support for passing log device as an argument Chandan Babu R
2023-10-31 16:46 ` [PATCH V3 00/23] Metadump v2 Darrick J. Wong
23 siblings, 1 reply; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
This commit adds functionality to restore metadump stored in v2 format.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
mdrestore/xfs_mdrestore.c | 234 ++++++++++++++++++++++++++++++++++++--
1 file changed, 222 insertions(+), 12 deletions(-)
diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
index 0fdbfce7..85a61c8b 100644
--- a/mdrestore/xfs_mdrestore.c
+++ b/mdrestore/xfs_mdrestore.c
@@ -9,15 +9,17 @@
#include <libfrog/platform.h>
union mdrestore_headers {
- __be32 magic;
- struct xfs_metablock v1;
+ __be32 magic;
+ struct xfs_metablock v1;
+ struct xfs_metadump_header v2;
};
struct mdrestore_ops {
void (*read_header)(union mdrestore_headers *header, FILE *md_fp);
void (*show_info)(union mdrestore_headers *header, const char *md_file);
void (*restore)(union mdrestore_headers *header, FILE *md_fp,
- int ddev_fd, bool is_target_file);
+ int ddev_fd, bool is_data_target_file, int logdev_fd,
+ bool is_log_target_file);
};
static struct mdrestore {
@@ -25,6 +27,7 @@ static struct mdrestore {
bool show_progress;
bool show_info;
bool progress_since_warning;
+ bool external_log;
} mdrestore;
static void
@@ -144,7 +147,9 @@ restore_v1(
union mdrestore_headers *h,
FILE *md_fp,
int ddev_fd,
- bool is_target_file)
+ bool is_data_target_file,
+ int logdev_fd,
+ bool is_log_target_file)
{
struct xfs_metablock *metablock; /* header + index + blocks */
__be64 *block_index;
@@ -197,7 +202,7 @@ restore_v1(
((struct xfs_dsb*)block_buffer)->sb_inprogress = 1;
- verify_device_size(ddev_fd, is_target_file, sb.sb_dblocks,
+ verify_device_size(ddev_fd, is_data_target_file, sb.sb_dblocks,
sb.sb_blocksize);
bytes_read = 0;
@@ -258,6 +263,193 @@ static struct mdrestore_ops mdrestore_ops_v1 = {
.restore = restore_v1,
};
+static void
+read_header_v2(
+ union mdrestore_headers *h,
+ FILE *md_fp)
+{
+ bool want_external_log;
+
+ if (fread((uint8_t *)&(h->v2) + sizeof(h->v2.xmh_magic),
+ sizeof(h->v2) - sizeof(h->v2.xmh_magic), 1, md_fp) != 1)
+ fatal("error reading from metadump file\n");
+
+ want_external_log = !!(be32_to_cpu(h->v2.xmh_incompat_flags) &
+ XFS_MD2_INCOMPAT_EXTERNALLOG);
+
+ if (want_external_log && !mdrestore.external_log)
+ fatal("External Log device is required\n");
+}
+
+static void
+show_info_v2(
+ union mdrestore_headers *h,
+ const char *md_file)
+{
+ uint32_t incompat_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",
+ md_file,
+ incompat_flags & XFS_MD2_INCOMPAT_OBFUSCATED ? "":"not ",
+ incompat_flags & XFS_MD2_INCOMPAT_DIRTYLOG ? "dirty":"clean",
+ incompat_flags & XFS_MD2_INCOMPAT_EXTERNALLOG ? "":"not ",
+ incompat_flags & XFS_MD2_INCOMPAT_FULLBLOCKS ? "full":"zeroed");
+}
+
+#define MDR_IO_BUF_SIZE (8 * 1024 * 1024)
+
+static void
+restore_meta_extent(
+ FILE *md_fp,
+ int dev_fd,
+ char *device,
+ void *buf,
+ uint64_t offset,
+ int len)
+{
+ int io_size;
+
+ io_size = min(len, MDR_IO_BUF_SIZE);
+
+ do {
+ if (fread(buf, io_size, 1, md_fp) != 1)
+ fatal("error reading from metadump file\n");
+ if (pwrite(dev_fd, buf, io_size, offset) < 0)
+ fatal("error writing to %s device at offset %llu: %s\n",
+ device, offset, strerror(errno));
+ len -= io_size;
+ offset += io_size;
+
+ io_size = min(len, io_size);
+ } while (len);
+}
+
+static void
+restore_v2(
+ union mdrestore_headers *h,
+ FILE *md_fp,
+ int ddev_fd,
+ bool is_data_target_file,
+ int logdev_fd,
+ bool is_log_target_file)
+{
+ struct xfs_sb sb;
+ struct xfs_meta_extent xme;
+ char *block_buffer;
+ int64_t bytes_read;
+ uint64_t offset;
+ int len;
+
+ block_buffer = malloc(MDR_IO_BUF_SIZE);
+ if (block_buffer == NULL)
+ fatal("Unable to allocate input buffer memory\n");
+
+ if (fread(&xme, sizeof(xme), 1, md_fp) != 1)
+ fatal("error reading from metadump file\n");
+
+ if (xme.xme_addr != 0 || xme.xme_len == 1 ||
+ (be64_to_cpu(xme.xme_addr) & XME_ADDR_DEVICE_MASK) !=
+ XME_ADDR_DATA_DEVICE)
+ fatal("Invalid superblock disk address/length\n");
+
+ len = BBTOB(be32_to_cpu(xme.xme_len));
+
+ if (fread(block_buffer, len, 1, md_fp) != 1)
+ fatal("error reading from metadump file\n");
+
+ libxfs_sb_from_disk(&sb, (struct xfs_dsb *)block_buffer);
+
+ if (sb.sb_magicnum != XFS_SB_MAGIC)
+ fatal("bad magic number for primary superblock\n");
+
+ ((struct xfs_dsb *)block_buffer)->sb_inprogress = 1;
+
+ verify_device_size(ddev_fd, is_data_target_file, sb.sb_dblocks,
+ sb.sb_blocksize);
+
+ if (sb.sb_logstart == 0) {
+ ASSERT(mdrestore.external_log == true);
+ verify_device_size(logdev_fd, is_log_target_file, sb.sb_logblocks,
+ sb.sb_blocksize);
+ }
+
+ if (pwrite(ddev_fd, block_buffer, len, 0) < 0)
+ fatal("error writing primary superblock: %s\n",
+ strerror(errno));
+
+ bytes_read = len;
+
+ do {
+ char *device;
+ int fd;
+
+ if (fread(&xme, sizeof(xme), 1, md_fp) != 1) {
+ if (feof(md_fp))
+ break;
+ fatal("error reading from metadump file\n");
+ }
+
+ offset = BBTOB(be64_to_cpu(xme.xme_addr) & XME_ADDR_DADDR_MASK);
+ switch (be64_to_cpu(xme.xme_addr) & XME_ADDR_DEVICE_MASK) {
+ case XME_ADDR_DATA_DEVICE:
+ device = "data";
+ fd = ddev_fd;
+ break;
+ case XME_ADDR_LOG_DEVICE:
+ device = "log";
+ fd = logdev_fd;
+ break;
+ default:
+ fatal("Invalid device found in metadump\n");
+ break;
+ }
+
+ len = BBTOB(be32_to_cpu(xme.xme_len));
+
+ restore_meta_extent(md_fp, fd, device, block_buffer, offset,
+ len);
+
+ bytes_read += len;
+
+ if (mdrestore.show_progress) {
+ static int64_t mb_read;
+ int64_t mb_now = bytes_read >> 20;
+
+ if (mb_now != mb_read) {
+ print_progress("%lld MB read", mb_now);
+ mb_read = mb_now;
+ }
+ }
+ } while (1);
+
+ if (mdrestore.progress_since_warning)
+ putchar('\n');
+
+ memset(block_buffer, 0, sb.sb_sectsize);
+ sb.sb_inprogress = 0;
+ libxfs_sb_to_disk((struct xfs_dsb *)block_buffer, &sb);
+ if (xfs_sb_version_hascrc(&sb)) {
+ xfs_update_cksum(block_buffer, sb.sb_sectsize,
+ offsetof(struct xfs_sb, sb_crc));
+ }
+
+ if (pwrite(ddev_fd, block_buffer, sb.sb_sectsize, 0) < 0)
+ fatal("error writing primary superblock: %s\n",
+ strerror(errno));
+
+ free(block_buffer);
+
+ return;
+}
+
+static struct mdrestore_ops mdrestore_ops_v2 = {
+ .read_header = read_header_v2,
+ .show_info = show_info_v2,
+ .restore = restore_v2,
+};
+
static void
usage(void)
{
@@ -270,15 +462,19 @@ main(
int argc,
char **argv)
{
- union mdrestore_headers headers;
+ union mdrestore_headers headers;
FILE *src_f;
- int dst_fd;
+ char *logdev = NULL;
+ int data_dev_fd;
+ int log_dev_fd;
int c;
- bool is_target_file;
+ bool is_data_dev_file;
+ bool is_log_dev_file;
mdrestore.show_progress = false;
mdrestore.show_info = false;
mdrestore.progress_since_warning = false;
+ mdrestore.external_log = false;
progname = basename(argv[0]);
@@ -328,6 +524,11 @@ main(
case XFS_MD_MAGIC_V1:
mdrestore.mdrops = &mdrestore_ops_v1;
break;
+
+ case XFS_MD_MAGIC_V2:
+ mdrestore.mdrops = &mdrestore_ops_v2;
+ break;
+
default:
fatal("specified file is not a metadata dump\n");
break;
@@ -344,12 +545,21 @@ main(
optind++;
- /* check and open target */
- dst_fd = open_device(argv[optind], &is_target_file);
+ /* check and open data device */
+ data_dev_fd = open_device(argv[optind], &is_data_dev_file);
+
+ log_dev_fd = -1;
+ if (mdrestore.external_log)
+ /* check and open log device */
+ log_dev_fd = open_device(logdev, &is_log_dev_file);
+
+ mdrestore.mdrops->restore(&headers, src_f, data_dev_fd,
+ is_data_dev_file, log_dev_fd, is_log_dev_file);
- mdrestore.mdrops->restore(&headers, src_f, dst_fd, is_target_file);
+ close(data_dev_fd);
+ if (mdrestore.external_log)
+ close(log_dev_fd);
- close(dst_fd);
if (src_f != stdin)
fclose(src_f);
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH V3 22/23] mdrestore: Define mdrestore ops for v2 format
2023-07-24 4:35 ` [PATCH V3 22/23] mdrestore: Define mdrestore ops for v2 format Chandan Babu R
@ 2023-08-02 17:16 ` Darrick J. Wong
0 siblings, 0 replies; 41+ messages in thread
From: Darrick J. Wong @ 2023-08-02 17:16 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs, cem
On Mon, Jul 24, 2023 at 10:05:26AM +0530, Chandan Babu R wrote:
> This commit adds functionality to restore metadump stored in v2 format.
>
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
Looks good now, thanks for taking care of this!
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
--D
> ---
> mdrestore/xfs_mdrestore.c | 234 ++++++++++++++++++++++++++++++++++++--
> 1 file changed, 222 insertions(+), 12 deletions(-)
>
> diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
> index 0fdbfce7..85a61c8b 100644
> --- a/mdrestore/xfs_mdrestore.c
> +++ b/mdrestore/xfs_mdrestore.c
> @@ -9,15 +9,17 @@
> #include <libfrog/platform.h>
>
> union mdrestore_headers {
> - __be32 magic;
> - struct xfs_metablock v1;
> + __be32 magic;
> + struct xfs_metablock v1;
> + struct xfs_metadump_header v2;
> };
>
> struct mdrestore_ops {
> void (*read_header)(union mdrestore_headers *header, FILE *md_fp);
> void (*show_info)(union mdrestore_headers *header, const char *md_file);
> void (*restore)(union mdrestore_headers *header, FILE *md_fp,
> - int ddev_fd, bool is_target_file);
> + int ddev_fd, bool is_data_target_file, int logdev_fd,
> + bool is_log_target_file);
> };
>
> static struct mdrestore {
> @@ -25,6 +27,7 @@ static struct mdrestore {
> bool show_progress;
> bool show_info;
> bool progress_since_warning;
> + bool external_log;
> } mdrestore;
>
> static void
> @@ -144,7 +147,9 @@ restore_v1(
> union mdrestore_headers *h,
> FILE *md_fp,
> int ddev_fd,
> - bool is_target_file)
> + bool is_data_target_file,
> + int logdev_fd,
> + bool is_log_target_file)
> {
> struct xfs_metablock *metablock; /* header + index + blocks */
> __be64 *block_index;
> @@ -197,7 +202,7 @@ restore_v1(
>
> ((struct xfs_dsb*)block_buffer)->sb_inprogress = 1;
>
> - verify_device_size(ddev_fd, is_target_file, sb.sb_dblocks,
> + verify_device_size(ddev_fd, is_data_target_file, sb.sb_dblocks,
> sb.sb_blocksize);
>
> bytes_read = 0;
> @@ -258,6 +263,193 @@ static struct mdrestore_ops mdrestore_ops_v1 = {
> .restore = restore_v1,
> };
>
> +static void
> +read_header_v2(
> + union mdrestore_headers *h,
> + FILE *md_fp)
> +{
> + bool want_external_log;
> +
> + if (fread((uint8_t *)&(h->v2) + sizeof(h->v2.xmh_magic),
> + sizeof(h->v2) - sizeof(h->v2.xmh_magic), 1, md_fp) != 1)
> + fatal("error reading from metadump file\n");
> +
> + want_external_log = !!(be32_to_cpu(h->v2.xmh_incompat_flags) &
> + XFS_MD2_INCOMPAT_EXTERNALLOG);
> +
> + if (want_external_log && !mdrestore.external_log)
> + fatal("External Log device is required\n");
> +}
> +
> +static void
> +show_info_v2(
> + union mdrestore_headers *h,
> + const char *md_file)
> +{
> + uint32_t incompat_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",
> + md_file,
> + incompat_flags & XFS_MD2_INCOMPAT_OBFUSCATED ? "":"not ",
> + incompat_flags & XFS_MD2_INCOMPAT_DIRTYLOG ? "dirty":"clean",
> + incompat_flags & XFS_MD2_INCOMPAT_EXTERNALLOG ? "":"not ",
> + incompat_flags & XFS_MD2_INCOMPAT_FULLBLOCKS ? "full":"zeroed");
> +}
> +
> +#define MDR_IO_BUF_SIZE (8 * 1024 * 1024)
> +
> +static void
> +restore_meta_extent(
> + FILE *md_fp,
> + int dev_fd,
> + char *device,
> + void *buf,
> + uint64_t offset,
> + int len)
> +{
> + int io_size;
> +
> + io_size = min(len, MDR_IO_BUF_SIZE);
> +
> + do {
> + if (fread(buf, io_size, 1, md_fp) != 1)
> + fatal("error reading from metadump file\n");
> + if (pwrite(dev_fd, buf, io_size, offset) < 0)
> + fatal("error writing to %s device at offset %llu: %s\n",
> + device, offset, strerror(errno));
> + len -= io_size;
> + offset += io_size;
> +
> + io_size = min(len, io_size);
> + } while (len);
> +}
> +
> +static void
> +restore_v2(
> + union mdrestore_headers *h,
> + FILE *md_fp,
> + int ddev_fd,
> + bool is_data_target_file,
> + int logdev_fd,
> + bool is_log_target_file)
> +{
> + struct xfs_sb sb;
> + struct xfs_meta_extent xme;
> + char *block_buffer;
> + int64_t bytes_read;
> + uint64_t offset;
> + int len;
> +
> + block_buffer = malloc(MDR_IO_BUF_SIZE);
> + if (block_buffer == NULL)
> + fatal("Unable to allocate input buffer memory\n");
> +
> + if (fread(&xme, sizeof(xme), 1, md_fp) != 1)
> + fatal("error reading from metadump file\n");
> +
> + if (xme.xme_addr != 0 || xme.xme_len == 1 ||
> + (be64_to_cpu(xme.xme_addr) & XME_ADDR_DEVICE_MASK) !=
> + XME_ADDR_DATA_DEVICE)
> + fatal("Invalid superblock disk address/length\n");
> +
> + len = BBTOB(be32_to_cpu(xme.xme_len));
> +
> + if (fread(block_buffer, len, 1, md_fp) != 1)
> + fatal("error reading from metadump file\n");
> +
> + libxfs_sb_from_disk(&sb, (struct xfs_dsb *)block_buffer);
> +
> + if (sb.sb_magicnum != XFS_SB_MAGIC)
> + fatal("bad magic number for primary superblock\n");
> +
> + ((struct xfs_dsb *)block_buffer)->sb_inprogress = 1;
> +
> + verify_device_size(ddev_fd, is_data_target_file, sb.sb_dblocks,
> + sb.sb_blocksize);
> +
> + if (sb.sb_logstart == 0) {
> + ASSERT(mdrestore.external_log == true);
> + verify_device_size(logdev_fd, is_log_target_file, sb.sb_logblocks,
> + sb.sb_blocksize);
> + }
> +
> + if (pwrite(ddev_fd, block_buffer, len, 0) < 0)
> + fatal("error writing primary superblock: %s\n",
> + strerror(errno));
> +
> + bytes_read = len;
> +
> + do {
> + char *device;
> + int fd;
> +
> + if (fread(&xme, sizeof(xme), 1, md_fp) != 1) {
> + if (feof(md_fp))
> + break;
> + fatal("error reading from metadump file\n");
> + }
> +
> + offset = BBTOB(be64_to_cpu(xme.xme_addr) & XME_ADDR_DADDR_MASK);
> + switch (be64_to_cpu(xme.xme_addr) & XME_ADDR_DEVICE_MASK) {
> + case XME_ADDR_DATA_DEVICE:
> + device = "data";
> + fd = ddev_fd;
> + break;
> + case XME_ADDR_LOG_DEVICE:
> + device = "log";
> + fd = logdev_fd;
> + break;
> + default:
> + fatal("Invalid device found in metadump\n");
> + break;
> + }
> +
> + len = BBTOB(be32_to_cpu(xme.xme_len));
> +
> + restore_meta_extent(md_fp, fd, device, block_buffer, offset,
> + len);
> +
> + bytes_read += len;
> +
> + if (mdrestore.show_progress) {
> + static int64_t mb_read;
> + int64_t mb_now = bytes_read >> 20;
> +
> + if (mb_now != mb_read) {
> + print_progress("%lld MB read", mb_now);
> + mb_read = mb_now;
> + }
> + }
> + } while (1);
> +
> + if (mdrestore.progress_since_warning)
> + putchar('\n');
> +
> + memset(block_buffer, 0, sb.sb_sectsize);
> + sb.sb_inprogress = 0;
> + libxfs_sb_to_disk((struct xfs_dsb *)block_buffer, &sb);
> + if (xfs_sb_version_hascrc(&sb)) {
> + xfs_update_cksum(block_buffer, sb.sb_sectsize,
> + offsetof(struct xfs_sb, sb_crc));
> + }
> +
> + if (pwrite(ddev_fd, block_buffer, sb.sb_sectsize, 0) < 0)
> + fatal("error writing primary superblock: %s\n",
> + strerror(errno));
> +
> + free(block_buffer);
> +
> + return;
> +}
> +
> +static struct mdrestore_ops mdrestore_ops_v2 = {
> + .read_header = read_header_v2,
> + .show_info = show_info_v2,
> + .restore = restore_v2,
> +};
> +
> static void
> usage(void)
> {
> @@ -270,15 +462,19 @@ main(
> int argc,
> char **argv)
> {
> - union mdrestore_headers headers;
> + union mdrestore_headers headers;
> FILE *src_f;
> - int dst_fd;
> + char *logdev = NULL;
> + int data_dev_fd;
> + int log_dev_fd;
> int c;
> - bool is_target_file;
> + bool is_data_dev_file;
> + bool is_log_dev_file;
>
> mdrestore.show_progress = false;
> mdrestore.show_info = false;
> mdrestore.progress_since_warning = false;
> + mdrestore.external_log = false;
>
> progname = basename(argv[0]);
>
> @@ -328,6 +524,11 @@ main(
> case XFS_MD_MAGIC_V1:
> mdrestore.mdrops = &mdrestore_ops_v1;
> break;
> +
> + case XFS_MD_MAGIC_V2:
> + mdrestore.mdrops = &mdrestore_ops_v2;
> + break;
> +
> default:
> fatal("specified file is not a metadata dump\n");
> break;
> @@ -344,12 +545,21 @@ main(
>
> optind++;
>
> - /* check and open target */
> - dst_fd = open_device(argv[optind], &is_target_file);
> + /* check and open data device */
> + data_dev_fd = open_device(argv[optind], &is_data_dev_file);
> +
> + log_dev_fd = -1;
> + if (mdrestore.external_log)
> + /* check and open log device */
> + log_dev_fd = open_device(logdev, &is_log_dev_file);
> +
> + mdrestore.mdrops->restore(&headers, src_f, data_dev_fd,
> + is_data_dev_file, log_dev_fd, is_log_dev_file);
>
> - mdrestore.mdrops->restore(&headers, src_f, dst_fd, is_target_file);
> + close(data_dev_fd);
> + if (mdrestore.external_log)
> + close(log_dev_fd);
>
> - close(dst_fd);
> if (src_f != stdin)
> fclose(src_f);
>
> --
> 2.39.1
>
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH V3 23/23] mdrestore: Add support for passing log device as an argument
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (21 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 22/23] mdrestore: Define mdrestore ops for v2 format Chandan Babu R
@ 2023-07-24 4:35 ` Chandan Babu R
2023-10-31 16:46 ` [PATCH V3 00/23] Metadump v2 Darrick J. Wong
23 siblings, 0 replies; 41+ messages in thread
From: Chandan Babu R @ 2023-07-24 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong, cem
metadump v2 format allows dumping metadata from external log devices. This
commit allows passing the device file to which log data must be restored from
the corresponding metadump file.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
man/man8/xfs_mdrestore.8 | 8 ++++++++
mdrestore/xfs_mdrestore.c | 11 +++++++++--
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/man/man8/xfs_mdrestore.8 b/man/man8/xfs_mdrestore.8
index 72f3b297..6e7457c0 100644
--- a/man/man8/xfs_mdrestore.8
+++ b/man/man8/xfs_mdrestore.8
@@ -5,6 +5,9 @@ xfs_mdrestore \- restores an XFS metadump image to a filesystem image
.B xfs_mdrestore
[
.B \-gi
+] [
+.B \-l
+.I logdev
]
.I source
.I target
@@ -49,6 +52,11 @@ Shows metadump information on stdout. If no
is specified, exits after displaying information. Older metadumps man not
include any descriptive information.
.TP
+.B \-l " logdev"
+Metadump in v2 format can contain metadata dumped from an external log.
+In such a scenario, the user has to provide a device to which the log device
+contents from the metadump file are copied.
+.TP
.B \-V
Prints the version number and exits.
.SH DIAGNOSTICS
diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
index 85a61c8b..beb23489 100644
--- a/mdrestore/xfs_mdrestore.c
+++ b/mdrestore/xfs_mdrestore.c
@@ -453,7 +453,8 @@ static struct mdrestore_ops mdrestore_ops_v2 = {
static void
usage(void)
{
- fprintf(stderr, "Usage: %s [-V] [-g] [-i] source target\n", progname);
+ fprintf(stderr, "Usage: %s [-V] [-g] [-i] [-l logdev] source target\n",
+ progname);
exit(1);
}
@@ -478,7 +479,7 @@ main(
progname = basename(argv[0]);
- while ((c = getopt(argc, argv, "giV")) != EOF) {
+ while ((c = getopt(argc, argv, "gil:V")) != EOF) {
switch (c) {
case 'g':
mdrestore.show_progress = true;
@@ -486,6 +487,10 @@ main(
case 'i':
mdrestore.show_info = true;
break;
+ case 'l':
+ logdev = optarg;
+ mdrestore.external_log = true;
+ break;
case 'V':
printf("%s version %s\n", progname, VERSION);
exit(0);
@@ -522,6 +527,8 @@ main(
switch (be32_to_cpu(headers.magic)) {
case XFS_MD_MAGIC_V1:
+ if (logdev != NULL)
+ usage();
mdrestore.mdrops = &mdrestore_ops_v1;
break;
--
2.39.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH V3 00/23] Metadump v2
2023-07-24 4:35 [PATCH V3 00/23] Metadump v2 Chandan Babu R
` (22 preceding siblings ...)
2023-07-24 4:35 ` [PATCH V3 23/23] mdrestore: Add support for passing log device as an argument Chandan Babu R
@ 2023-10-31 16:46 ` Darrick J. Wong
2023-11-01 14:58 ` Carlos Maiolino
23 siblings, 1 reply; 41+ messages in thread
From: Darrick J. Wong @ 2023-10-31 16:46 UTC (permalink / raw)
To: Chandan Babu R, Carlos Maiolino; +Cc: linux-xfs, cem
On Mon, Jul 24, 2023 at 10:05:04AM +0530, Chandan Babu R wrote:
> Hi all,
>
> This patch series extends metadump/mdrestore tools to be able to dump
> and restore contents of an external log device. It also adds the
> ability to copy larger blocks (e.g. 4096 bytes instead of 512 bytes)
> into the metadump file. These objectives are accomplished by
> introducing a new metadump file format.
Gentle maintainer ping: Carlos, do you have any thoughts about this
series? The only unaddressed review comment was <cough> me asking for
code golf around patch 18 or so. Do you (or anyone else) see any
problems that I've not spotted?
--D
>
> I have tested the patchset by extending metadump/mdrestore tests in
> fstests to cover the newly introduced metadump v2 format. The tests
> can be found at
> https://github.com/chandanr/xfstests/commits/metadump-v2.
>
> The patch series can also be obtained from
> https://github.com/chandanr/xfsprogs-dev/commits/metadump-v2.
>
> Darrick, Please note that I have removed your RVB from "metadump: Add
> support for passing version option" patch. copy_log() and metadump_f()
> were invoking set_log_cur() for both "internal log" and "external
> log". In the V3 patchset, I have modified the copy_log() function to,
> 1. Invoke set_log_cur() when the filesystem has an external log.
> 2. Invoke set_cur() when the filesystem has an internal log.
>
> Changelog:
> V2 -> V3:
> 1. Document the meanings of metadump v2's ondisk flags.
> 2. Rename metadump_ops->end_write() to metadump_ops->finish_dump().
> 3. Pass a pointer to the newly introduced "union mdrestore_headers"
> to callbacks in "struct mdrestore_ops" instead of a pointer to
> "void".
> 4. Use set_log_cur() only when metadump has to be read from an
> external log device.
> 5. Verify that primary superblock read from metadump file was indeed
> read from the data device.
> 6. Fix indentation issues.
>
> V1 -> V2:
> 1. Introduce the new incompat flag XFS_MD2_INCOMPAT_EXTERNALLOG to
> indicate that the metadump file contains data obtained from an
> external log.
> 2. Interpret bits 54 and 55 of xfs_meta_extent.xme_addr as a counter
> such that 00 maps to the data device and 01 maps to the log
> device.
> 3. Define the new function set_log_cur() to read from
> internal/external log device. This allows us to continue using
> TYP_LOG to read from both internal and external log.
> 4. In order to support reading metadump from a pipe, mdrestore now
> reads the first four bytes of the header to determine the
> metadump version rather than reading the entire header in a
> single call to fread().
> 5. Add an ASCII diagram to describe metadump v2's ondisk layout in
> xfs_metadump.h.
> 6. Update metadump's man page to indicate that metadump in v2 format
> is generated by default if the filesystem has an external log and
> the metadump version to use is not explicitly mentioned on the
> command line.
> 7. Remove '_metadump' suffix from function pointer names in "struct
> metadump_ops".
> 8. Use xfs_daddr_t type for declaring variables containing disk
> offset value.
> 9. Use bool type rather than int for variables holding a boolean
> value.
> 11. Remove unnecessary whitespace.
>
>
> Chandan Babu R (23):
> metadump: Use boolean values true/false instead of 1/0
> mdrestore: Fix logic used to check if target device is large enough
> metadump: Declare boolean variables with bool type
> metadump: Define and use struct metadump
> metadump: Add initialization and release functions
> metadump: Postpone invocation of init_metadump()
> metadump: Introduce struct metadump_ops
> metadump: Introduce metadump v1 operations
> metadump: Rename XFS_MD_MAGIC to XFS_MD_MAGIC_V1
> metadump: Define metadump v2 ondisk format structures and macros
> metadump: Define metadump ops for v2 format
> xfs_db: Add support to read from external log device
> metadump: Add support for passing version option
> mdrestore: Declare boolean variables with bool type
> mdrestore: Define and use struct mdrestore
> mdrestore: Detect metadump v1 magic before reading the header
> mdrestore: Add open_device(), read_header() and show_info() functions
> mdrestore: Introduce struct mdrestore_ops
> mdrestore: Replace metadump header pointer argument with a union
> pointer
> mdrestore: Introduce mdrestore v1 operations
> mdrestore: Extract target device size verification into a function
> mdrestore: Define mdrestore ops for v2 format
> mdrestore: Add support for passing log device as an argument
>
> db/io.c | 56 ++-
> db/io.h | 2 +
> db/metadump.c | 777 ++++++++++++++++++++++++--------------
> db/xfs_metadump.sh | 3 +-
> include/xfs_metadump.h | 70 +++-
> man/man8/xfs_mdrestore.8 | 8 +
> man/man8/xfs_metadump.8 | 14 +
> mdrestore/xfs_mdrestore.c | 497 ++++++++++++++++++------
> 8 files changed, 1014 insertions(+), 413 deletions(-)
>
> --
> 2.39.1
>
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH V3 00/23] Metadump v2
2023-10-31 16:46 ` [PATCH V3 00/23] Metadump v2 Darrick J. Wong
@ 2023-11-01 14:58 ` Carlos Maiolino
2023-11-01 18:02 ` Darrick J. Wong
0 siblings, 1 reply; 41+ messages in thread
From: Carlos Maiolino @ 2023-11-01 14:58 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: Chandan Babu R, linux-xfs
On Tue, Oct 31, 2023 at 09:46:40AM -0700, Darrick J. Wong wrote:
> On Mon, Jul 24, 2023 at 10:05:04AM +0530, Chandan Babu R wrote:
> > Hi all,
> >
> > This patch series extends metadump/mdrestore tools to be able to dump
> > and restore contents of an external log device. It also adds the
> > ability to copy larger blocks (e.g. 4096 bytes instead of 512 bytes)
> > into the metadump file. These objectives are accomplished by
> > introducing a new metadump file format.
>
> Gentle maintainer ping: Carlos, do you have any thoughts about this
> series? The only unaddressed review comment was <cough> me asking for
> code golf around patch 18 or so. Do you (or anyone else) see any
> problems that I've not spotted?
Hi, it's been a while, but I looked into this series before, and I was mostly ok
with it, I was actually waiting for a follow-up patch addressing your comments
on patch 19, regarding mdrestore ops definition. My emails have been a bit funky
recently, did I miss a new version of this series?
Carlos
>
> --D
>
> >
> > I have tested the patchset by extending metadump/mdrestore tests in
> > fstests to cover the newly introduced metadump v2 format. The tests
> > can be found at
> > https://github.com/chandanr/xfstests/commits/metadump-v2.
> >
> > The patch series can also be obtained from
> > https://github.com/chandanr/xfsprogs-dev/commits/metadump-v2.
> >
> > Darrick, Please note that I have removed your RVB from "metadump: Add
> > support for passing version option" patch. copy_log() and metadump_f()
> > were invoking set_log_cur() for both "internal log" and "external
> > log". In the V3 patchset, I have modified the copy_log() function to,
> > 1. Invoke set_log_cur() when the filesystem has an external log.
> > 2. Invoke set_cur() when the filesystem has an internal log.
> >
> > Changelog:
> > V2 -> V3:
> > 1. Document the meanings of metadump v2's ondisk flags.
> > 2. Rename metadump_ops->end_write() to metadump_ops->finish_dump().
> > 3. Pass a pointer to the newly introduced "union mdrestore_headers"
> > to callbacks in "struct mdrestore_ops" instead of a pointer to
> > "void".
> > 4. Use set_log_cur() only when metadump has to be read from an
> > external log device.
> > 5. Verify that primary superblock read from metadump file was indeed
> > read from the data device.
> > 6. Fix indentation issues.
> >
> > V1 -> V2:
> > 1. Introduce the new incompat flag XFS_MD2_INCOMPAT_EXTERNALLOG to
> > indicate that the metadump file contains data obtained from an
> > external log.
> > 2. Interpret bits 54 and 55 of xfs_meta_extent.xme_addr as a counter
> > such that 00 maps to the data device and 01 maps to the log
> > device.
> > 3. Define the new function set_log_cur() to read from
> > internal/external log device. This allows us to continue using
> > TYP_LOG to read from both internal and external log.
> > 4. In order to support reading metadump from a pipe, mdrestore now
> > reads the first four bytes of the header to determine the
> > metadump version rather than reading the entire header in a
> > single call to fread().
> > 5. Add an ASCII diagram to describe metadump v2's ondisk layout in
> > xfs_metadump.h.
> > 6. Update metadump's man page to indicate that metadump in v2 format
> > is generated by default if the filesystem has an external log and
> > the metadump version to use is not explicitly mentioned on the
> > command line.
> > 7. Remove '_metadump' suffix from function pointer names in "struct
> > metadump_ops".
> > 8. Use xfs_daddr_t type for declaring variables containing disk
> > offset value.
> > 9. Use bool type rather than int for variables holding a boolean
> > value.
> > 11. Remove unnecessary whitespace.
> >
> >
> > Chandan Babu R (23):
> > metadump: Use boolean values true/false instead of 1/0
> > mdrestore: Fix logic used to check if target device is large enough
> > metadump: Declare boolean variables with bool type
> > metadump: Define and use struct metadump
> > metadump: Add initialization and release functions
> > metadump: Postpone invocation of init_metadump()
> > metadump: Introduce struct metadump_ops
> > metadump: Introduce metadump v1 operations
> > metadump: Rename XFS_MD_MAGIC to XFS_MD_MAGIC_V1
> > metadump: Define metadump v2 ondisk format structures and macros
> > metadump: Define metadump ops for v2 format
> > xfs_db: Add support to read from external log device
> > metadump: Add support for passing version option
> > mdrestore: Declare boolean variables with bool type
> > mdrestore: Define and use struct mdrestore
> > mdrestore: Detect metadump v1 magic before reading the header
> > mdrestore: Add open_device(), read_header() and show_info() functions
> > mdrestore: Introduce struct mdrestore_ops
> > mdrestore: Replace metadump header pointer argument with a union
> > pointer
> > mdrestore: Introduce mdrestore v1 operations
> > mdrestore: Extract target device size verification into a function
> > mdrestore: Define mdrestore ops for v2 format
> > mdrestore: Add support for passing log device as an argument
> >
> > db/io.c | 56 ++-
> > db/io.h | 2 +
> > db/metadump.c | 777 ++++++++++++++++++++++++--------------
> > db/xfs_metadump.sh | 3 +-
> > include/xfs_metadump.h | 70 +++-
> > man/man8/xfs_mdrestore.8 | 8 +
> > man/man8/xfs_metadump.8 | 14 +
> > mdrestore/xfs_mdrestore.c | 497 ++++++++++++++++++------
> > 8 files changed, 1014 insertions(+), 413 deletions(-)
> >
> > --
> > 2.39.1
> >
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH V3 00/23] Metadump v2
2023-11-01 14:58 ` Carlos Maiolino
@ 2023-11-01 18:02 ` Darrick J. Wong
0 siblings, 0 replies; 41+ messages in thread
From: Darrick J. Wong @ 2023-11-01 18:02 UTC (permalink / raw)
To: Carlos Maiolino; +Cc: Chandan Babu R, linux-xfs
On Wed, Nov 01, 2023 at 03:58:57PM +0100, Carlos Maiolino wrote:
> On Tue, Oct 31, 2023 at 09:46:40AM -0700, Darrick J. Wong wrote:
> > On Mon, Jul 24, 2023 at 10:05:04AM +0530, Chandan Babu R wrote:
> > > Hi all,
> > >
> > > This patch series extends metadump/mdrestore tools to be able to dump
> > > and restore contents of an external log device. It also adds the
> > > ability to copy larger blocks (e.g. 4096 bytes instead of 512 bytes)
> > > into the metadump file. These objectives are accomplished by
> > > introducing a new metadump file format.
> >
> > Gentle maintainer ping: Carlos, do you have any thoughts about this
> > series? The only unaddressed review comment was <cough> me asking for
> > code golf around patch 18 or so. Do you (or anyone else) see any
> > problems that I've not spotted?
>
> Hi, it's been a while, but I looked into this series before, and I was mostly ok
> with it, I was actually waiting for a follow-up patch addressing your comments
> on patch 19, regarding mdrestore ops definition. My emails have been a bit funky
> recently, did I miss a new version of this series?
AFAIK there hasn't been a new revision; this was a "hey it's been a few
months, are we all on the same page still?" inquiry. :)
--D
> Carlos
>
> >
> > --D
> >
> > >
> > > I have tested the patchset by extending metadump/mdrestore tests in
> > > fstests to cover the newly introduced metadump v2 format. The tests
> > > can be found at
> > > https://github.com/chandanr/xfstests/commits/metadump-v2.
> > >
> > > The patch series can also be obtained from
> > > https://github.com/chandanr/xfsprogs-dev/commits/metadump-v2.
> > >
> > > Darrick, Please note that I have removed your RVB from "metadump: Add
> > > support for passing version option" patch. copy_log() and metadump_f()
> > > were invoking set_log_cur() for both "internal log" and "external
> > > log". In the V3 patchset, I have modified the copy_log() function to,
> > > 1. Invoke set_log_cur() when the filesystem has an external log.
> > > 2. Invoke set_cur() when the filesystem has an internal log.
> > >
> > > Changelog:
> > > V2 -> V3:
> > > 1. Document the meanings of metadump v2's ondisk flags.
> > > 2. Rename metadump_ops->end_write() to metadump_ops->finish_dump().
> > > 3. Pass a pointer to the newly introduced "union mdrestore_headers"
> > > to callbacks in "struct mdrestore_ops" instead of a pointer to
> > > "void".
> > > 4. Use set_log_cur() only when metadump has to be read from an
> > > external log device.
> > > 5. Verify that primary superblock read from metadump file was indeed
> > > read from the data device.
> > > 6. Fix indentation issues.
> > >
> > > V1 -> V2:
> > > 1. Introduce the new incompat flag XFS_MD2_INCOMPAT_EXTERNALLOG to
> > > indicate that the metadump file contains data obtained from an
> > > external log.
> > > 2. Interpret bits 54 and 55 of xfs_meta_extent.xme_addr as a counter
> > > such that 00 maps to the data device and 01 maps to the log
> > > device.
> > > 3. Define the new function set_log_cur() to read from
> > > internal/external log device. This allows us to continue using
> > > TYP_LOG to read from both internal and external log.
> > > 4. In order to support reading metadump from a pipe, mdrestore now
> > > reads the first four bytes of the header to determine the
> > > metadump version rather than reading the entire header in a
> > > single call to fread().
> > > 5. Add an ASCII diagram to describe metadump v2's ondisk layout in
> > > xfs_metadump.h.
> > > 6. Update metadump's man page to indicate that metadump in v2 format
> > > is generated by default if the filesystem has an external log and
> > > the metadump version to use is not explicitly mentioned on the
> > > command line.
> > > 7. Remove '_metadump' suffix from function pointer names in "struct
> > > metadump_ops".
> > > 8. Use xfs_daddr_t type for declaring variables containing disk
> > > offset value.
> > > 9. Use bool type rather than int for variables holding a boolean
> > > value.
> > > 11. Remove unnecessary whitespace.
> > >
> > >
> > > Chandan Babu R (23):
> > > metadump: Use boolean values true/false instead of 1/0
> > > mdrestore: Fix logic used to check if target device is large enough
> > > metadump: Declare boolean variables with bool type
> > > metadump: Define and use struct metadump
> > > metadump: Add initialization and release functions
> > > metadump: Postpone invocation of init_metadump()
> > > metadump: Introduce struct metadump_ops
> > > metadump: Introduce metadump v1 operations
> > > metadump: Rename XFS_MD_MAGIC to XFS_MD_MAGIC_V1
> > > metadump: Define metadump v2 ondisk format structures and macros
> > > metadump: Define metadump ops for v2 format
> > > xfs_db: Add support to read from external log device
> > > metadump: Add support for passing version option
> > > mdrestore: Declare boolean variables with bool type
> > > mdrestore: Define and use struct mdrestore
> > > mdrestore: Detect metadump v1 magic before reading the header
> > > mdrestore: Add open_device(), read_header() and show_info() functions
> > > mdrestore: Introduce struct mdrestore_ops
> > > mdrestore: Replace metadump header pointer argument with a union
> > > pointer
> > > mdrestore: Introduce mdrestore v1 operations
> > > mdrestore: Extract target device size verification into a function
> > > mdrestore: Define mdrestore ops for v2 format
> > > mdrestore: Add support for passing log device as an argument
> > >
> > > db/io.c | 56 ++-
> > > db/io.h | 2 +
> > > db/metadump.c | 777 ++++++++++++++++++++++++--------------
> > > db/xfs_metadump.sh | 3 +-
> > > include/xfs_metadump.h | 70 +++-
> > > man/man8/xfs_mdrestore.8 | 8 +
> > > man/man8/xfs_metadump.8 | 14 +
> > > mdrestore/xfs_mdrestore.c | 497 ++++++++++++++++++------
> > > 8 files changed, 1014 insertions(+), 413 deletions(-)
> > >
> > > --
> > > 2.39.1
> > >
^ permalink raw reply [flat|nested] 41+ messages in thread