* [PATCH 1/2] xfs_mdrestore: Add -i option to built-in help @ 2018-02-02 19:11 Marco A Benatto 2018-02-02 19:11 ` [PATCH 2/2] xfs_mdrestore: Don't rewind source file stream Marco A Benatto 2018-02-02 20:22 ` [PATCH 1/2] xfs_mdrestore: Add -i option to built-in help Darrick J. Wong 0 siblings, 2 replies; 9+ messages in thread From: Marco A Benatto @ 2018-02-02 19:11 UTC (permalink / raw) To: linux-xfs; +Cc: mbenatto Currently we are missing -i option from usage(). This patch adds it to this biult-in help. Signed-off-by: Marco A Benatto <marco.antonio.780@gmail.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 c49c13a..0bb4ac8 100644 --- a/mdrestore/xfs_mdrestore.c +++ b/mdrestore/xfs_mdrestore.c @@ -194,7 +194,7 @@ perform_restore( static void usage(void) { - fprintf(stderr, "Usage: %s [-V] [-g] source target\n", progname); + fprintf(stderr, "Usage: %s [-V] [-g] [-i] source target\n", progname); exit(1); } -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/2] xfs_mdrestore: Don't rewind source file stream 2018-02-02 19:11 [PATCH 1/2] xfs_mdrestore: Add -i option to built-in help Marco A Benatto @ 2018-02-02 19:11 ` Marco A Benatto 2018-02-02 20:27 ` Darrick J. Wong 2018-02-02 20:22 ` [PATCH 1/2] xfs_mdrestore: Add -i option to built-in help Darrick J. Wong 1 sibling, 1 reply; 9+ messages in thread From: Marco A Benatto @ 2018-02-02 19:11 UTC (permalink / raw) To: linux-xfs; +Cc: mbenatto Today, xfs_mdrestore from stdin will fail if the -i flag is specified, because it attempts to rewind the stream after the initial read of the metablock. This fails, and results in an abort with "specified file is not a metadata dump." Read the metablock exactly once in main(), validate the magic, print informational flags if requested, and then pass it to perform_restore() which will then continue the restore process. Reported-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Marco A Benatto <marco.antonio.780@gmail.com> --- mdrestore/xfs_mdrestore.c | 52 +++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c index 0bb4ac8..15231a1 100644 --- a/mdrestore/xfs_mdrestore.c +++ b/mdrestore/xfs_mdrestore.c @@ -51,11 +51,22 @@ print_progress(const char *fmt, ...) progress_since_warning = 1; } +/* + * perform_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 + * @mb: the metadump's first xfs_metablock_t, read and verified by the caller + * + * src_f should be positioned just past a read the previously validated metablock + */ static void perform_restore( FILE *src_f, int dst_fd, - int is_target_file) + int is_target_file, + const xfs_metablock_t tmb) { xfs_metablock_t *metablock; /* header + index + blocks */ __be64 *block_index; @@ -64,22 +75,9 @@ perform_restore( int max_indices; int cur_index; int mb_count; - xfs_metablock_t tmb; xfs_sb_t sb; int64_t bytes_read; - /* - * read in first blocks (superblock 0), set "inprogress" flag for it, - * read in the rest of the file, and if complete, clear SB 0's - * "inprogress flag" - */ - - if (fread(&tmb, sizeof(tmb), 1, src_f) != 1) - fatal("error reading from file: %s\n", strerror(errno)); - - if (be32_to_cpu(tmb.mb_magic) != XFS_MD_MAGIC) - fatal("specified file is not a metadata dump\n"); - block_size = 1 << tmb.mb_blocklog; max_indices = (block_size - sizeof(xfs_metablock_t)) / sizeof(__be64); @@ -211,6 +209,7 @@ main( int open_flags; struct stat statbuf; int is_target_file; + xfs_metablock_t mb; progname = basename(argv[0]); @@ -237,7 +236,12 @@ main( if (!show_info && argc - optind != 2) usage(); - /* open source */ + /* + * open source and test if this really is a dump. The first metadatablock + * will be passed to perform_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; if (isatty(fileno(stdin))) @@ -248,15 +252,12 @@ main( fatal("cannot open source dump file\n"); } - if (show_info) { - xfs_metablock_t mb; - - if (fread(&mb, sizeof(mb), 1, src_f) != 1) - fatal("error reading from file: %s\n", strerror(errno)); - - if (be32_to_cpu(mb.mb_magic) != XFS_MD_MAGIC) - fatal("specified file is not a metadata dump\n"); + if (fread(&mb, sizeof(mb), 1, src_f) != 1) + fatal("error reading from file: %s\n", strerror(errno)); + if (be32_to_cpu(mb.mb_magic) != XFS_MD_MAGIC) + fatal("specified file is not a metadata dump\n"); + if (show_info) { if (mb.mb_info & XFS_METADUMP_INFO_FLAGS) { printf("%s: %sobfuscated, %s log, %s metadata blocks\n", argv[optind], @@ -270,9 +271,6 @@ main( if (argc - optind == 1) exit(0); - - /* Go back to the beginning for the restore function */ - fseek(src_f, 0L, SEEK_SET); } optind++; @@ -301,7 +299,7 @@ main( if (dst_fd < 0) fatal("couldn't open target \"%s\"\n", argv[optind]); - perform_restore(src_f, dst_fd, is_target_file); + perform_restore(src_f, dst_fd, is_target_file, mb); close(dst_fd); if (src_f != stdin) -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] xfs_mdrestore: Don't rewind source file stream 2018-02-02 19:11 ` [PATCH 2/2] xfs_mdrestore: Don't rewind source file stream Marco A Benatto @ 2018-02-02 20:27 ` Darrick J. Wong 2018-02-03 13:16 ` [PATCH] " Marco A Benatto 0 siblings, 1 reply; 9+ messages in thread From: Darrick J. Wong @ 2018-02-02 20:27 UTC (permalink / raw) To: Marco A Benatto; +Cc: linux-xfs, mbenatto On Fri, Feb 02, 2018 at 05:11:14PM -0200, Marco A Benatto wrote: > Today, xfs_mdrestore from stdin will fail if the -i flag is > specified, because it attempts to rewind the stream after > the initial read of the metablock. This fails, and > results in an abort with "specified file is not a metadata > dump." > > Read the metablock exactly once in main(), validate the magic, > print informational flags if requested, and then pass it to > perform_restore() which will then continue the restore process. > > Reported-by: Darrick J. Wong <darrick.wong@oracle.com> > Signed-off-by: Marco A Benatto <marco.antonio.780@gmail.com> > --- > mdrestore/xfs_mdrestore.c | 52 +++++++++++++++++++++++------------------------ > 1 file changed, 25 insertions(+), 27 deletions(-) > > diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c > index 0bb4ac8..15231a1 100644 > --- a/mdrestore/xfs_mdrestore.c > +++ b/mdrestore/xfs_mdrestore.c > @@ -51,11 +51,22 @@ print_progress(const char *fmt, ...) > progress_since_warning = 1; > } > > +/* > + * perform_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 > + * @mb: the metadump's first xfs_metablock_t, read and verified by the caller > + * > + * src_f should be positioned just past a read the previously validated metablock > + */ > static void > perform_restore( > FILE *src_f, > int dst_fd, > - int is_target_file) > + int is_target_file, > + const xfs_metablock_t tmb) "const struct xfs_metablock *tmp" Please don't pass the whole structure on the stack, and since this is new code, don't use the structure typedef aliases (which we are slowly trying to eliminate). > { > xfs_metablock_t *metablock; /* header + index + blocks */ > __be64 *block_index; > @@ -64,22 +75,9 @@ perform_restore( > int max_indices; > int cur_index; > int mb_count; > - xfs_metablock_t tmb; > xfs_sb_t sb; > int64_t bytes_read; > > - /* > - * read in first blocks (superblock 0), set "inprogress" flag for it, > - * read in the rest of the file, and if complete, clear SB 0's > - * "inprogress flag" > - */ > - > - if (fread(&tmb, sizeof(tmb), 1, src_f) != 1) > - fatal("error reading from file: %s\n", strerror(errno)); > - > - if (be32_to_cpu(tmb.mb_magic) != XFS_MD_MAGIC) > - fatal("specified file is not a metadata dump\n"); > - > block_size = 1 << tmb.mb_blocklog; > max_indices = (block_size - sizeof(xfs_metablock_t)) / sizeof(__be64); > > @@ -211,6 +209,7 @@ main( > int open_flags; > struct stat statbuf; > int is_target_file; > + xfs_metablock_t mb; struct xfs_metablock mb; > > progname = basename(argv[0]); > > @@ -237,7 +236,12 @@ main( > if (!show_info && argc - optind != 2) > usage(); > > - /* open source */ > + /* > + * open source and test if this really is a dump. The first metadatablock "The first metadump block..." > + * will be passed to perform_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; > if (isatty(fileno(stdin))) > @@ -248,15 +252,12 @@ main( > fatal("cannot open source dump file\n"); > } > > - if (show_info) { > - xfs_metablock_t mb; > - > - if (fread(&mb, sizeof(mb), 1, src_f) != 1) > - fatal("error reading from file: %s\n", strerror(errno)); > - > - if (be32_to_cpu(mb.mb_magic) != XFS_MD_MAGIC) > - fatal("specified file is not a metadata dump\n"); > + if (fread(&mb, sizeof(mb), 1, src_f) != 1) > + fatal("error reading from file: %s\n", strerror(errno)); > + if (be32_to_cpu(mb.mb_magic) != XFS_MD_MAGIC) if (mb.mb_magic != cpu_to_be32(XFS_MD_MAGIC)) ...so that we can let the horrible macro definitions turn that into a byteswapped constant instead of a function call. It's not critical here, but it's a convention we try to maintain everywhere else. The rest looks fine. --D > + fatal("specified file is not a metadata dump\n"); > > + if (show_info) { > if (mb.mb_info & XFS_METADUMP_INFO_FLAGS) { > printf("%s: %sobfuscated, %s log, %s metadata blocks\n", > argv[optind], > @@ -270,9 +271,6 @@ main( > > if (argc - optind == 1) > exit(0); > - > - /* Go back to the beginning for the restore function */ > - fseek(src_f, 0L, SEEK_SET); > } > > optind++; > @@ -301,7 +299,7 @@ main( > if (dst_fd < 0) > fatal("couldn't open target \"%s\"\n", argv[optind]); > > - perform_restore(src_f, dst_fd, is_target_file); > + perform_restore(src_f, dst_fd, is_target_file, mb); > > close(dst_fd); > if (src_f != stdin) > -- > 1.8.3.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-xfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH] xfs_mdrestore: Don't rewind source file stream 2018-02-02 20:27 ` Darrick J. Wong @ 2018-02-03 13:16 ` Marco A Benatto 2018-02-03 13:18 ` Marco Benatto 2018-02-03 17:32 ` Darrick J. Wong 0 siblings, 2 replies; 9+ messages in thread From: Marco A Benatto @ 2018-02-03 13:16 UTC (permalink / raw) To: linux-xfs, darrick.wong Today, xfs_mdrestore from stdin will fail if the -i flag is specified, because it attempts to rewind the stream after the initial read of the metablock. This fails, and results in an abort with "specified file is not a metadata dump." Read the metablock exactly once in main(), validate the magic, print informational flags if requested, and then pass it to perform_restore() which will then continue the restore process. Reported-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Marco A Benatto <marco.antonio.780@gmail.com> --- mdrestore/xfs_mdrestore.c | 55 +++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c index 0bb4ac8..3db740d 100644 --- a/mdrestore/xfs_mdrestore.c +++ b/mdrestore/xfs_mdrestore.c @@ -51,35 +51,34 @@ print_progress(const char *fmt, ...) progress_since_warning = 1; } +/* + * perform_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 perform_restore( FILE *src_f, int dst_fd, - int is_target_file) + int is_target_file, + const struct xfs_metablock *mbp) { - xfs_metablock_t *metablock; /* header + index + blocks */ + struct xfs_metablock *metablock, tmb; /* header + index + blocks */ __be64 *block_index; char *block_buffer; int block_size; int max_indices; int cur_index; int mb_count; - xfs_metablock_t tmb; xfs_sb_t sb; int64_t bytes_read; - /* - * read in first blocks (superblock 0), set "inprogress" flag for it, - * read in the rest of the file, and if complete, clear SB 0's - * "inprogress flag" - */ - - if (fread(&tmb, sizeof(tmb), 1, src_f) != 1) - fatal("error reading from file: %s\n", strerror(errno)); - - if (be32_to_cpu(tmb.mb_magic) != XFS_MD_MAGIC) - fatal("specified file is not a metadata dump\n"); - + tmb = *mbp; block_size = 1 << tmb.mb_blocklog; max_indices = (block_size - sizeof(xfs_metablock_t)) / sizeof(__be64); @@ -211,6 +210,7 @@ main( int open_flags; struct stat statbuf; int is_target_file; + xfs_metablock_t mb; progname = basename(argv[0]); @@ -237,7 +237,12 @@ main( if (!show_info && argc - optind != 2) usage(); - /* open source */ + /* + * 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 + * 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; if (isatty(fileno(stdin))) @@ -248,15 +253,12 @@ main( fatal("cannot open source dump file\n"); } - if (show_info) { - xfs_metablock_t mb; - - if (fread(&mb, sizeof(mb), 1, src_f) != 1) - fatal("error reading from file: %s\n", strerror(errno)); - - if (be32_to_cpu(mb.mb_magic) != XFS_MD_MAGIC) - fatal("specified file is not a metadata dump\n"); + if (fread(&mb, sizeof(mb), 1, src_f) != 1) + fatal("error reading from file: %s\n", strerror(errno)); + if (mb.mb_magic != cpu_to_be32(XFS_MD_MAGIC)) + fatal("specified file is not a metadata dump\n"); + if (show_info) { if (mb.mb_info & XFS_METADUMP_INFO_FLAGS) { printf("%s: %sobfuscated, %s log, %s metadata blocks\n", argv[optind], @@ -270,9 +272,6 @@ main( if (argc - optind == 1) exit(0); - - /* Go back to the beginning for the restore function */ - fseek(src_f, 0L, SEEK_SET); } optind++; @@ -301,7 +300,7 @@ main( if (dst_fd < 0) fatal("couldn't open target \"%s\"\n", argv[optind]); - perform_restore(src_f, dst_fd, is_target_file); + perform_restore(src_f, dst_fd, is_target_file, &mb); close(dst_fd); if (src_f != stdin) -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] xfs_mdrestore: Don't rewind source file stream 2018-02-03 13:16 ` [PATCH] " Marco A Benatto @ 2018-02-03 13:18 ` Marco Benatto 2018-02-03 17:32 ` Darrick J. Wong 1 sibling, 0 replies; 9+ messages in thread From: Marco Benatto @ 2018-02-03 13:18 UTC (permalink / raw) To: linux-xfs, Darrick J. Wong Hi Darrick, just resent with the changes for the reviews you mentioned. Please, let me know if this seems ok now. Thanks, On Sat, Feb 3, 2018 at 11:16 AM, Marco A Benatto <marco.antonio.780@gmail.com> wrote: > Today, xfs_mdrestore from stdin will fail if the -i flag is > specified, because it attempts to rewind the stream after > the initial read of the metablock. This fails, and > results in an abort with "specified file is not a metadata > dump." > > Read the metablock exactly once in main(), validate the magic, > print informational flags if requested, and then pass it to > perform_restore() which will then continue the restore process. > > Reported-by: Darrick J. Wong <darrick.wong@oracle.com> > Signed-off-by: Marco A Benatto <marco.antonio.780@gmail.com> > --- > mdrestore/xfs_mdrestore.c | 55 +++++++++++++++++++++++------------------------ > 1 file changed, 27 insertions(+), 28 deletions(-) > > diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c > index 0bb4ac8..3db740d 100644 > --- a/mdrestore/xfs_mdrestore.c > +++ b/mdrestore/xfs_mdrestore.c > @@ -51,35 +51,34 @@ print_progress(const char *fmt, ...) > progress_since_warning = 1; > } > > +/* > + * perform_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 > perform_restore( > FILE *src_f, > int dst_fd, > - int is_target_file) > + int is_target_file, > + const struct xfs_metablock *mbp) > { > - xfs_metablock_t *metablock; /* header + index + blocks */ > + struct xfs_metablock *metablock, tmb; /* header + index + blocks */ > __be64 *block_index; > char *block_buffer; > int block_size; > int max_indices; > int cur_index; > int mb_count; > - xfs_metablock_t tmb; > xfs_sb_t sb; > int64_t bytes_read; > > - /* > - * read in first blocks (superblock 0), set "inprogress" flag for it, > - * read in the rest of the file, and if complete, clear SB 0's > - * "inprogress flag" > - */ > - > - if (fread(&tmb, sizeof(tmb), 1, src_f) != 1) > - fatal("error reading from file: %s\n", strerror(errno)); > - > - if (be32_to_cpu(tmb.mb_magic) != XFS_MD_MAGIC) > - fatal("specified file is not a metadata dump\n"); > - > + tmb = *mbp; > block_size = 1 << tmb.mb_blocklog; > max_indices = (block_size - sizeof(xfs_metablock_t)) / sizeof(__be64); > > @@ -211,6 +210,7 @@ main( > int open_flags; > struct stat statbuf; > int is_target_file; > + xfs_metablock_t mb; > > progname = basename(argv[0]); > > @@ -237,7 +237,12 @@ main( > if (!show_info && argc - optind != 2) > usage(); > > - /* open source */ > + /* > + * 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 > + * 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; > if (isatty(fileno(stdin))) > @@ -248,15 +253,12 @@ main( > fatal("cannot open source dump file\n"); > } > > - if (show_info) { > - xfs_metablock_t mb; > - > - if (fread(&mb, sizeof(mb), 1, src_f) != 1) > - fatal("error reading from file: %s\n", strerror(errno)); > - > - if (be32_to_cpu(mb.mb_magic) != XFS_MD_MAGIC) > - fatal("specified file is not a metadata dump\n"); > + if (fread(&mb, sizeof(mb), 1, src_f) != 1) > + fatal("error reading from file: %s\n", strerror(errno)); > + if (mb.mb_magic != cpu_to_be32(XFS_MD_MAGIC)) > + fatal("specified file is not a metadata dump\n"); > > + if (show_info) { > if (mb.mb_info & XFS_METADUMP_INFO_FLAGS) { > printf("%s: %sobfuscated, %s log, %s metadata blocks\n", > argv[optind], > @@ -270,9 +272,6 @@ main( > > if (argc - optind == 1) > exit(0); > - > - /* Go back to the beginning for the restore function */ > - fseek(src_f, 0L, SEEK_SET); > } > > optind++; > @@ -301,7 +300,7 @@ main( > if (dst_fd < 0) > fatal("couldn't open target \"%s\"\n", argv[optind]); > > - perform_restore(src_f, dst_fd, is_target_file); > + perform_restore(src_f, dst_fd, is_target_file, &mb); > > close(dst_fd); > if (src_f != stdin) > -- > 1.8.3.1 > -- Marco Antonio Benatto Linux user ID: #506236 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] xfs_mdrestore: Don't rewind source file stream 2018-02-03 13:16 ` [PATCH] " Marco A Benatto 2018-02-03 13:18 ` Marco Benatto @ 2018-02-03 17:32 ` Darrick J. Wong 2018-02-05 11:50 ` Marco A Benatto 1 sibling, 1 reply; 9+ messages in thread From: Darrick J. Wong @ 2018-02-03 17:32 UTC (permalink / raw) To: Marco A Benatto; +Cc: linux-xfs On Sat, Feb 03, 2018 at 11:16:36AM -0200, Marco A Benatto wrote: > Today, xfs_mdrestore from stdin will fail if the -i flag is > specified, because it attempts to rewind the stream after > the initial read of the metablock. This fails, and > results in an abort with "specified file is not a metadata > dump." > > Read the metablock exactly once in main(), validate the magic, > print informational flags if requested, and then pass it to > perform_restore() which will then continue the restore process. > > Reported-by: Darrick J. Wong <darrick.wong@oracle.com> > Signed-off-by: Marco A Benatto <marco.antonio.780@gmail.com> > --- > mdrestore/xfs_mdrestore.c | 55 +++++++++++++++++++++++------------------------ > 1 file changed, 27 insertions(+), 28 deletions(-) > > diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c > index 0bb4ac8..3db740d 100644 > --- a/mdrestore/xfs_mdrestore.c > +++ b/mdrestore/xfs_mdrestore.c > @@ -51,35 +51,34 @@ print_progress(const char *fmt, ...) > progress_since_warning = 1; > } > > +/* > + * perform_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 > perform_restore( > FILE *src_f, > int dst_fd, > - int is_target_file) > + int is_target_file, > + const struct xfs_metablock *mbp) > { > - xfs_metablock_t *metablock; /* header + index + blocks */ > + struct xfs_metablock *metablock, tmb; /* header + index + blocks */ > __be64 *block_index; > char *block_buffer; > int block_size; > int max_indices; > int cur_index; > int mb_count; > - xfs_metablock_t tmb; > xfs_sb_t sb; > int64_t bytes_read; > > - /* > - * read in first blocks (superblock 0), set "inprogress" flag for it, > - * read in the rest of the file, and if complete, clear SB 0's > - * "inprogress flag" > - */ > - > - if (fread(&tmb, sizeof(tmb), 1, src_f) != 1) > - fatal("error reading from file: %s\n", strerror(errno)); > - > - if (be32_to_cpu(tmb.mb_magic) != XFS_MD_MAGIC) > - fatal("specified file is not a metadata dump\n"); > - > + tmb = *mbp; > block_size = 1 << tmb.mb_blocklog; Why not avoid the structure copy and dereference the pointer directly? block_size = 1 << mbp->mb_blocklog; etc. > max_indices = (block_size - sizeof(xfs_metablock_t)) / sizeof(__be64); > > @@ -211,6 +210,7 @@ main( > int open_flags; > struct stat statbuf; > int is_target_file; > + xfs_metablock_t mb; struct xfs_metablock mb; --D > > progname = basename(argv[0]); > > @@ -237,7 +237,12 @@ main( > if (!show_info && argc - optind != 2) > usage(); > > - /* open source */ > + /* > + * 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 > + * 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; > if (isatty(fileno(stdin))) > @@ -248,15 +253,12 @@ main( > fatal("cannot open source dump file\n"); > } > > - if (show_info) { > - xfs_metablock_t mb; > - > - if (fread(&mb, sizeof(mb), 1, src_f) != 1) > - fatal("error reading from file: %s\n", strerror(errno)); > - > - if (be32_to_cpu(mb.mb_magic) != XFS_MD_MAGIC) > - fatal("specified file is not a metadata dump\n"); > + if (fread(&mb, sizeof(mb), 1, src_f) != 1) > + fatal("error reading from file: %s\n", strerror(errno)); > + if (mb.mb_magic != cpu_to_be32(XFS_MD_MAGIC)) > + fatal("specified file is not a metadata dump\n"); > > + if (show_info) { > if (mb.mb_info & XFS_METADUMP_INFO_FLAGS) { > printf("%s: %sobfuscated, %s log, %s metadata blocks\n", > argv[optind], > @@ -270,9 +272,6 @@ main( > > if (argc - optind == 1) > exit(0); > - > - /* Go back to the beginning for the restore function */ > - fseek(src_f, 0L, SEEK_SET); > } > > optind++; > @@ -301,7 +300,7 @@ main( > if (dst_fd < 0) > fatal("couldn't open target \"%s\"\n", argv[optind]); > > - perform_restore(src_f, dst_fd, is_target_file); > + perform_restore(src_f, dst_fd, is_target_file, &mb); > > close(dst_fd); > if (src_f != stdin) > -- > 1.8.3.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-xfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH] xfs_mdrestore: Don't rewind source file stream 2018-02-03 17:32 ` Darrick J. Wong @ 2018-02-05 11:50 ` Marco A Benatto 2018-02-05 16:47 ` Darrick J. Wong 0 siblings, 1 reply; 9+ messages in thread From: Marco A Benatto @ 2018-02-05 11:50 UTC (permalink / raw) To: linux-xfs, darrick.wong Today, xfs_mdrestore from stdin will fail if the -i flag is specified, because it attempts to rewind the stream after the initial read of the metablock. This fails, and results in an abort with "specified file is not a metadata dump." Read the metablock exactly once in main(), validate the magic, print informational flags if requested, and then pass it to perform_restore() which will then continue the restore process. Reported-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Marco A Benatto <marco.antonio.780@gmail.com> --- mdrestore/xfs_mdrestore.c | 68 +++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c index 0bb4ac8..cbabd56 100644 --- a/mdrestore/xfs_mdrestore.c +++ b/mdrestore/xfs_mdrestore.c @@ -51,57 +51,55 @@ print_progress(const char *fmt, ...) progress_since_warning = 1; } +/* + * perform_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 perform_restore( FILE *src_f, int dst_fd, - int is_target_file) + int is_target_file, + const struct xfs_metablock *mbp) { - xfs_metablock_t *metablock; /* header + index + blocks */ + struct xfs_metablock *metablock; /* header + index + blocks */ __be64 *block_index; char *block_buffer; int block_size; int max_indices; int cur_index; int mb_count; - xfs_metablock_t tmb; xfs_sb_t sb; int64_t bytes_read; - /* - * read in first blocks (superblock 0), set "inprogress" flag for it, - * read in the rest of the file, and if complete, clear SB 0's - * "inprogress flag" - */ - - if (fread(&tmb, sizeof(tmb), 1, src_f) != 1) - fatal("error reading from file: %s\n", strerror(errno)); - - if (be32_to_cpu(tmb.mb_magic) != XFS_MD_MAGIC) - fatal("specified file is not a metadata dump\n"); - - block_size = 1 << tmb.mb_blocklog; + block_size = 1 << mbp->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(tmb.mb_count); + mb_count = be16_to_cpu(mbp->mb_count); if (mb_count == 0 || mb_count > max_indices) fatal("bad block count: %u\n", mb_count); block_index = (__be64 *)((char *)metablock + sizeof(xfs_metablock_t)); block_buffer = (char *)metablock + block_size; - if (fread(block_index, block_size - sizeof(tmb), 1, src_f) != 1) + if (fread(block_index, block_size - sizeof(struct xfs_metablock), 1, src_f) != 1) fatal("error reading from file: %s\n", strerror(errno)); if (block_index[0] != 0) fatal("first block is not the primary superblock\n"); - if (fread(block_buffer, mb_count << tmb.mb_blocklog, + if (fread(block_buffer, mb_count << mbp->mb_blocklog, 1, src_f) != 1) fatal("error reading from file: %s\n", strerror(errno)); @@ -148,7 +146,7 @@ perform_restore( for (cur_index = 0; cur_index < mb_count; cur_index++) { if (pwrite(dst_fd, &block_buffer[cur_index << - tmb.mb_blocklog], block_size, + mbp->mb_blocklog], block_size, be64_to_cpu(block_index[cur_index]) << BBSHIFT) < 0) fatal("error writing block %llu: %s\n", @@ -167,11 +165,11 @@ perform_restore( if (mb_count > max_indices) fatal("bad block count: %u\n", mb_count); - if (fread(block_buffer, mb_count << tmb.mb_blocklog, + if (fread(block_buffer, mb_count << mbp->mb_blocklog, 1, src_f) != 1) fatal("error reading from file: %s\n", strerror(errno)); - bytes_read += block_size + (mb_count << tmb.mb_blocklog); + bytes_read += block_size + (mb_count << mbp->mb_blocklog); } if (progress_since_warning) @@ -211,6 +209,7 @@ main( int open_flags; struct stat statbuf; int is_target_file; + struct xfs_metablock mb; progname = basename(argv[0]); @@ -237,7 +236,12 @@ main( if (!show_info && argc - optind != 2) usage(); - /* open source */ + /* + * 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 + * 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; if (isatty(fileno(stdin))) @@ -248,15 +252,12 @@ main( fatal("cannot open source dump file\n"); } - if (show_info) { - xfs_metablock_t mb; - - if (fread(&mb, sizeof(mb), 1, src_f) != 1) - fatal("error reading from file: %s\n", strerror(errno)); - - if (be32_to_cpu(mb.mb_magic) != XFS_MD_MAGIC) - fatal("specified file is not a metadata dump\n"); + if (fread(&mb, sizeof(mb), 1, src_f) != 1) + fatal("error reading from file: %s\n", strerror(errno)); + if (mb.mb_magic != cpu_to_be32(XFS_MD_MAGIC)) + fatal("specified file is not a metadata dump\n"); + if (show_info) { if (mb.mb_info & XFS_METADUMP_INFO_FLAGS) { printf("%s: %sobfuscated, %s log, %s metadata blocks\n", argv[optind], @@ -270,9 +271,6 @@ main( if (argc - optind == 1) exit(0); - - /* Go back to the beginning for the restore function */ - fseek(src_f, 0L, SEEK_SET); } optind++; @@ -301,7 +299,7 @@ main( if (dst_fd < 0) fatal("couldn't open target \"%s\"\n", argv[optind]); - perform_restore(src_f, dst_fd, is_target_file); + perform_restore(src_f, dst_fd, is_target_file, &mb); close(dst_fd); if (src_f != stdin) -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] xfs_mdrestore: Don't rewind source file stream 2018-02-05 11:50 ` Marco A Benatto @ 2018-02-05 16:47 ` Darrick J. Wong 0 siblings, 0 replies; 9+ messages in thread From: Darrick J. Wong @ 2018-02-05 16:47 UTC (permalink / raw) To: Marco A Benatto; +Cc: linux-xfs On Mon, Feb 05, 2018 at 09:50:34AM -0200, Marco A Benatto wrote: > Today, xfs_mdrestore from stdin will fail if the -i flag is > specified, because it attempts to rewind the stream after > the initial read of the metablock. This fails, and > results in an abort with "specified file is not a metadata > dump." > > Read the metablock exactly once in main(), validate the magic, > print informational flags if requested, and then pass it to > perform_restore() which will then continue the restore process. > > Reported-by: Darrick J. Wong <darrick.wong@oracle.com> > Signed-off-by: Marco A Benatto <marco.antonio.780@gmail.com> Looks ok, Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > mdrestore/xfs_mdrestore.c | 68 +++++++++++++++++++++++------------------------ > 1 file changed, 33 insertions(+), 35 deletions(-) > > diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c > index 0bb4ac8..cbabd56 100644 > --- a/mdrestore/xfs_mdrestore.c > +++ b/mdrestore/xfs_mdrestore.c > @@ -51,57 +51,55 @@ print_progress(const char *fmt, ...) > progress_since_warning = 1; > } > > +/* > + * perform_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 > perform_restore( > FILE *src_f, > int dst_fd, > - int is_target_file) > + int is_target_file, > + const struct xfs_metablock *mbp) > { > - xfs_metablock_t *metablock; /* header + index + blocks */ > + struct xfs_metablock *metablock; /* header + index + blocks */ > __be64 *block_index; > char *block_buffer; > int block_size; > int max_indices; > int cur_index; > int mb_count; > - xfs_metablock_t tmb; > xfs_sb_t sb; > int64_t bytes_read; > > - /* > - * read in first blocks (superblock 0), set "inprogress" flag for it, > - * read in the rest of the file, and if complete, clear SB 0's > - * "inprogress flag" > - */ > - > - if (fread(&tmb, sizeof(tmb), 1, src_f) != 1) > - fatal("error reading from file: %s\n", strerror(errno)); > - > - if (be32_to_cpu(tmb.mb_magic) != XFS_MD_MAGIC) > - fatal("specified file is not a metadata dump\n"); > - > - block_size = 1 << tmb.mb_blocklog; > + block_size = 1 << mbp->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(tmb.mb_count); > + mb_count = be16_to_cpu(mbp->mb_count); > if (mb_count == 0 || mb_count > max_indices) > fatal("bad block count: %u\n", mb_count); > > block_index = (__be64 *)((char *)metablock + sizeof(xfs_metablock_t)); > block_buffer = (char *)metablock + block_size; > > - if (fread(block_index, block_size - sizeof(tmb), 1, src_f) != 1) > + if (fread(block_index, block_size - sizeof(struct xfs_metablock), 1, src_f) != 1) > fatal("error reading from file: %s\n", strerror(errno)); > > if (block_index[0] != 0) > fatal("first block is not the primary superblock\n"); > > > - if (fread(block_buffer, mb_count << tmb.mb_blocklog, > + if (fread(block_buffer, mb_count << mbp->mb_blocklog, > 1, src_f) != 1) > fatal("error reading from file: %s\n", strerror(errno)); > > @@ -148,7 +146,7 @@ perform_restore( > > for (cur_index = 0; cur_index < mb_count; cur_index++) { > if (pwrite(dst_fd, &block_buffer[cur_index << > - tmb.mb_blocklog], block_size, > + mbp->mb_blocklog], block_size, > be64_to_cpu(block_index[cur_index]) << > BBSHIFT) < 0) > fatal("error writing block %llu: %s\n", > @@ -167,11 +165,11 @@ perform_restore( > if (mb_count > max_indices) > fatal("bad block count: %u\n", mb_count); > > - if (fread(block_buffer, mb_count << tmb.mb_blocklog, > + if (fread(block_buffer, mb_count << mbp->mb_blocklog, > 1, src_f) != 1) > fatal("error reading from file: %s\n", strerror(errno)); > > - bytes_read += block_size + (mb_count << tmb.mb_blocklog); > + bytes_read += block_size + (mb_count << mbp->mb_blocklog); > } > > if (progress_since_warning) > @@ -211,6 +209,7 @@ main( > int open_flags; > struct stat statbuf; > int is_target_file; > + struct xfs_metablock mb; > > progname = basename(argv[0]); > > @@ -237,7 +236,12 @@ main( > if (!show_info && argc - optind != 2) > usage(); > > - /* open source */ > + /* > + * 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 > + * 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; > if (isatty(fileno(stdin))) > @@ -248,15 +252,12 @@ main( > fatal("cannot open source dump file\n"); > } > > - if (show_info) { > - xfs_metablock_t mb; > - > - if (fread(&mb, sizeof(mb), 1, src_f) != 1) > - fatal("error reading from file: %s\n", strerror(errno)); > - > - if (be32_to_cpu(mb.mb_magic) != XFS_MD_MAGIC) > - fatal("specified file is not a metadata dump\n"); > + if (fread(&mb, sizeof(mb), 1, src_f) != 1) > + fatal("error reading from file: %s\n", strerror(errno)); > + if (mb.mb_magic != cpu_to_be32(XFS_MD_MAGIC)) > + fatal("specified file is not a metadata dump\n"); > > + if (show_info) { > if (mb.mb_info & XFS_METADUMP_INFO_FLAGS) { > printf("%s: %sobfuscated, %s log, %s metadata blocks\n", > argv[optind], > @@ -270,9 +271,6 @@ main( > > if (argc - optind == 1) > exit(0); > - > - /* Go back to the beginning for the restore function */ > - fseek(src_f, 0L, SEEK_SET); > } > > optind++; > @@ -301,7 +299,7 @@ main( > if (dst_fd < 0) > fatal("couldn't open target \"%s\"\n", argv[optind]); > > - perform_restore(src_f, dst_fd, is_target_file); > + perform_restore(src_f, dst_fd, is_target_file, &mb); > > close(dst_fd); > if (src_f != stdin) > -- > 1.8.3.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-xfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] xfs_mdrestore: Add -i option to built-in help 2018-02-02 19:11 [PATCH 1/2] xfs_mdrestore: Add -i option to built-in help Marco A Benatto 2018-02-02 19:11 ` [PATCH 2/2] xfs_mdrestore: Don't rewind source file stream Marco A Benatto @ 2018-02-02 20:22 ` Darrick J. Wong 1 sibling, 0 replies; 9+ messages in thread From: Darrick J. Wong @ 2018-02-02 20:22 UTC (permalink / raw) To: Marco A Benatto; +Cc: linux-xfs, mbenatto On Fri, Feb 02, 2018 at 05:11:13PM -0200, Marco A Benatto wrote: > Currently we are missing -i option from usage(). > This patch adds it to this biult-in help. "built-in" > Signed-off-by: Marco A Benatto <marco.antonio.780@gmail.com> Otherwise looks ok, Reviewed-by: Darrick J. Wong <darrick.wong@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 c49c13a..0bb4ac8 100644 > --- a/mdrestore/xfs_mdrestore.c > +++ b/mdrestore/xfs_mdrestore.c > @@ -194,7 +194,7 @@ perform_restore( > static void > usage(void) > { > - fprintf(stderr, "Usage: %s [-V] [-g] source target\n", progname); > + fprintf(stderr, "Usage: %s [-V] [-g] [-i] source target\n", progname); > exit(1); > } > > -- > 1.8.3.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-xfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2018-02-05 16:47 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-02-02 19:11 [PATCH 1/2] xfs_mdrestore: Add -i option to built-in help Marco A Benatto 2018-02-02 19:11 ` [PATCH 2/2] xfs_mdrestore: Don't rewind source file stream Marco A Benatto 2018-02-02 20:27 ` Darrick J. Wong 2018-02-03 13:16 ` [PATCH] " Marco A Benatto 2018-02-03 13:18 ` Marco Benatto 2018-02-03 17:32 ` Darrick J. Wong 2018-02-05 11:50 ` Marco A Benatto 2018-02-05 16:47 ` Darrick J. Wong 2018-02-02 20:22 ` [PATCH 1/2] xfs_mdrestore: Add -i option to built-in help Darrick J. Wong
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).