From f72d20adb82134b9fc1bf2e39d3d4f6e1ed8fc7d Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Fri, 5 Mar 2004 04:08:55 +0000 Subject: [PATCH] xfs_io tweaks to allow some operations to work on non-XFS files (blkdev, etc). --- io/command.c | 8 +++++++- io/command.h | 3 ++- io/fsync.c | 4 +++- io/help.c | 3 ++- io/init.c | 14 ++++++++++---- io/init.h | 3 ++- io/open.c | 21 +++++++++++++++++---- io/pread.c | 20 ++++++++++++++------ io/pwrite.c | 25 +++++++++++++++++-------- io/quit.c | 3 ++- io/truncate.c | 13 +++++++++++-- man/man8/xfs_io.8 | 14 ++++++++++++-- 12 files changed, 99 insertions(+), 32 deletions(-) diff --git a/io/command.c b/io/command.c index f5e60839d..5c1b27e98 100644 --- a/io/command.c +++ b/io/command.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2003-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -32,6 +32,7 @@ #include #include "command.h" +#include "init.h" cmdinfo_t *cmdtab; int ncmds; @@ -66,6 +67,11 @@ command( fprintf(stderr, _("command \"%s\" not found\n"), cmd); return 0; } + if (foreign && !ct->foreign) { + fprintf(stderr, + _("foreign file is open, %s command is for XFS filesystems only\n"), + cmd); + } if (argc-1 < ct->argmin || (ct->argmax != -1 && argc-1 > ct->argmax)) { if (ct->argmax == -1) fprintf(stderr, diff --git a/io/command.h b/io/command.h index 9d291f1db..5c5e60468 100644 --- a/io/command.h +++ b/io/command.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -42,6 +42,7 @@ typedef struct cmdinfo { int argmin; int argmax; int canpush; + int foreign; const char *args; const char *oneline; helpfunc_t help; diff --git a/io/fsync.c b/io/fsync.c index c4d35acc0..9947882ed 100644 --- a/io/fsync.c +++ b/io/fsync.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2003-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -67,12 +67,14 @@ fsync_init(void) fsync_cmd.name = _("fsync"); fsync_cmd.altname = _("s"); fsync_cmd.cfunc = fsync_f; + fsync_cmd.foreign = 1; fsync_cmd.oneline = _("calls fsync(2) to flush all in-core file state to disk"); fdatasync_cmd.name = _("fdatasync"); fdatasync_cmd.altname = _("ds"); fdatasync_cmd.cfunc = fdatasync_f; + fdatasync_cmd.foreign = 1; fdatasync_cmd.oneline = _("calls fdatasync(2) to flush the files in-core data to disk"); diff --git a/io/help.c b/io/help.c index 692c70536..b62118d2f 100644 --- a/io/help.c +++ b/io/help.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2003-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -102,6 +102,7 @@ help_init(void) help_cmd.cfunc = help_f; help_cmd.argmin = 0; help_cmd.argmax = 1; + help_cmd.foreign = 1; help_cmd.args = _("[command]"); help_cmd.oneline = _("help for one or all commands"); diff --git a/io/init.c b/io/init.c index 5ecd7ca61..6eb18877b 100644 --- a/io/init.c +++ b/io/init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2003-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -44,6 +44,7 @@ xfs_fsop_geom_t fgeom; int readonly; int directio; int realtime; +int foreign; int append; int osync; int trunc; @@ -55,7 +56,8 @@ void usage(void) { fprintf(stderr, - _("Usage: %s [-r] [-p prog] [-c cmd]... file\n"), progname); + _("Usage: %s [-adFfrstx] [-p prog] [-c cmd]... file\n"), + progname); exit(1); } @@ -72,7 +74,7 @@ init( bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - while ((c = getopt(argc, argv, "ac:dfp:rstVx")) != EOF) { + while ((c = getopt(argc, argv, "ac:dFfp:rstVx")) != EOF) { switch (c) { case 'a': /* append */ append = 1; @@ -89,6 +91,9 @@ init( case 'd': /* directIO */ directio = 1; break; + case 'F': /* foreign */ + foreign = 1; + break; case 'f': /* create */ fflag = 1; break; @@ -119,7 +124,8 @@ init( usage(); fname = strdup(argv[optind]); - if ((fdesc = openfile(fname, &fgeom, append, fflag, directio, + if ((fdesc = openfile(fname, foreign ? NULL : &fgeom, + append, fflag, directio, readonly, osync, trunc, realtime)) < 0) exit(1); diff --git a/io/init.h b/io/init.h index 2f1a38878..3fe53ffb7 100644 --- a/io/init.h +++ b/io/init.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2003-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -40,6 +40,7 @@ extern struct xfs_fsop_geom fgeom; extern int readonly; extern int directio; extern int realtime; +extern int foreign; extern int append; extern int osync; extern int trunc; diff --git a/io/open.c b/io/open.c index 76d147a0b..fe71b6bba 100644 --- a/io/open.c +++ b/io/open.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2003-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -132,6 +132,7 @@ open_help(void) "\n" " Opens a file for subsequent use by all of the other xfs_io commands.\n" " With no arguments, open uses the stat command to show the current file.\n" +" -F -- foreign filesystem file, disallow XFS-specific commands\n" " -a -- open with the O_APPEND flag (append-only mode)\n" " -c -- open with O_CREAT (create the file if it doesn't exist)\n" " -d -- open with O_DIRECT (non-buffered IO, note alignment constraints)\n" @@ -151,6 +152,7 @@ open_f( int argc, char **argv) { + int Fflag = 0; int aflag = 0; int cflag = 0; int dflag = 0; @@ -159,15 +161,18 @@ open_f( int tflag = 0; int xflag = 0; char *filename; - xfs_fsop_geom_t geometry; + xfs_fsop_geom_t geometry = { 0 }; int fd; int c; if (argc == 1) return stat_f(argc, argv); - while ((c = getopt(argc, argv, "acdrstx")) != EOF) { + while ((c = getopt(argc, argv, "Facdrstx")) != EOF) { switch (c) { + case 'F': + Fflag = 1; + break; case 'a': aflag = 1; break; @@ -197,7 +202,7 @@ open_f( if (optind != argc - 1) return usage(); - fd = openfile(argv[optind], &geometry, + fd = openfile(argv[optind], Fflag ? NULL : &geometry, aflag, cflag, dflag, rflag, sflag, tflag, xflag); if (fd < 0) return 0; @@ -215,6 +220,7 @@ open_f( osync = sflag; trunc = tflag; append = aflag; + foreign = Fflag; directio = dflag; readonly = rflag; realtime = xflag; @@ -485,6 +491,8 @@ stat_f( printf(_("stat.ctime = %s"), ctime(&st.st_ctime)); } } + if (foreign) + return 0; if ((xfsctl(fname, fdesc, XFS_IOC_FSGETXATTR, &fsx)) < 0) { perror("xfsctl(XFS_IOC_FSGETXATTR)"); } else { @@ -585,6 +593,8 @@ else printf(_("statfs.f_files = %lld\n"), (long long) st.f_files); printf(_("statfs.f_ffree = %lld\n"), (long long) st.f_ffree); } + if (foreign) + return 0; if ((xfsctl(fname, fdesc, XFS_IOC_FSGEOMETRY_V1, &fsgeo)) < 0) { perror("xfsctl(XFS_IOC_FSGEOMETRY_V1)"); } else { @@ -612,6 +622,7 @@ open_init(void) open_cmd.cfunc = open_f; open_cmd.argmin = 0; open_cmd.argmax = -1; + open_cmd.foreign = 1; open_cmd.args = _("[-acdrstx] [path]"); open_cmd.oneline = _("close the current file, open file specified by path"); @@ -621,6 +632,7 @@ open_init(void) stat_cmd.cfunc = stat_f; stat_cmd.argmin = 0; stat_cmd.argmax = 1; + stat_cmd.foreign = 1; stat_cmd.args = _("[-v]"); stat_cmd.oneline = _("statistics on the currently open file"); @@ -633,6 +645,7 @@ open_init(void) statfs_cmd.name = _("statfs"); statfs_cmd.cfunc = statfs_f; + statfs_cmd.foreign = 1; statfs_cmd.oneline = _("statistics on the filesystem of the currently open file"); diff --git a/io/pread.c b/io/pread.c index 0811aff4c..4fabb16a3 100644 --- a/io/pread.c +++ b/io/pread.c @@ -143,17 +143,24 @@ pread_f( { off64_t offset; long long count, total; - unsigned int bsize = 4096; + unsigned int blocksize, sectsize; struct timeval t1, t2; char s1[64], s2[64], ts[64]; int vflag = 0; int c; + if (foreign) { + blocksize = 4096; + sectsize = 512; + } else { + blocksize = fgeom.blocksize; + sectsize = fgeom.sectsize; + } while ((c = getopt(argc, argv, "b:v")) != EOF) { switch (c) { case 'b': - bsize = cvtnum(fgeom.blocksize, fgeom.sectsize, optarg); - if (bsize < 0) { + blocksize = cvtnum(blocksize, sectsize, optarg); + if (blocksize < 0) { printf(_("non-numeric bsize -- %s\n"), optarg); return 0; } @@ -170,19 +177,19 @@ pread_f( printf("%s %s\n", pread_cmd.name, pread_cmd.oneline); return 0; } - offset = cvtnum(fgeom.blocksize, fgeom.sectsize, argv[optind]); + offset = cvtnum(blocksize, sectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); return 0; } optind++; - count = cvtnum(fgeom.blocksize, fgeom.sectsize, argv[optind]); + count = cvtnum(blocksize, sectsize, argv[optind]); if (count < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } - if (!alloc_buffer(bsize, 0xabababab)) + if (!alloc_buffer(blocksize, 0xabababab)) return 0; gettimeofday(&t1, NULL); @@ -209,6 +216,7 @@ pread_init(void) pread_cmd.cfunc = pread_f; pread_cmd.argmin = 2; pread_cmd.argmax = -1; + pread_cmd.foreign = 1; pread_cmd.args = _("[-b bs] [-v] off len"); pread_cmd.oneline = _("reads a number of bytes at a specified offset"); pread_cmd.help = pread_help; diff --git a/io/pwrite.c b/io/pwrite.c index 8a52cfd19..657b3ed15 100644 --- a/io/pwrite.c +++ b/io/pwrite.c @@ -103,17 +103,24 @@ pwrite_f( off64_t offset, skip = 0; long long count, total; unsigned int seed = 0xcdcdcdcd; - unsigned int bsize = 4096; + unsigned int blocksize, sectsize; struct timeval t1, t2; char s1[64], s2[64], ts[64]; char *sp, *infile = NULL; int c, fd = -1, dflag = 0; + if (foreign) { + blocksize = 4096; + sectsize = 512; + } else { + blocksize = fgeom.blocksize; + sectsize = fgeom.sectsize; + } while ((c = getopt(argc, argv, "b:df:i:s:S:")) != EOF) { switch (c) { case 'b': - bsize = cvtnum(fgeom.blocksize, fgeom.sectsize, optarg); - if (bsize < 0) { + blocksize = cvtnum(blocksize, sectsize, optarg); + if (blocksize < 0) { printf(_("non-numeric bsize -- %s\n"), optarg); return 0; } @@ -126,7 +133,7 @@ pwrite_f( infile = optarg; break; case 's': - skip = cvtnum(fgeom.blocksize, fgeom.sectsize, optarg); + skip = cvtnum(blocksize, sectsize, optarg); if (skip < 0) { printf(_("non-numeric skip -- %s\n"), optarg); return 0; @@ -148,19 +155,19 @@ pwrite_f( printf("%s %s\n", pwrite_cmd.name, pwrite_cmd.oneline); return 0; } - offset = cvtnum(fgeom.blocksize, fgeom.sectsize, argv[optind]); + offset = cvtnum(blocksize, sectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); return 0; } optind++; - count = cvtnum(fgeom.blocksize, fgeom.sectsize, argv[optind]); + count = cvtnum(blocksize, sectsize, argv[optind]); if (count < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } - if (!alloc_buffer(bsize, seed)) + if (!alloc_buffer(blocksize, seed)) return 0; if (infile && @@ -168,7 +175,8 @@ pwrite_f( return 0; gettimeofday(&t1, NULL); - if ((c = write_buffer(offset, count, bsize, fd, skip, &total)) < 0) { + c = write_buffer(offset, count, blocksize, fd, skip, &total); + if (c < 0) { close(fd); return 0; } @@ -194,6 +202,7 @@ pwrite_init(void) pwrite_cmd.cfunc = pwrite_f; pwrite_cmd.argmin = 2; pwrite_cmd.argmax = -1; + pwrite_cmd.foreign = 1; pwrite_cmd.args = _("[-i infile [-d] [-s skip]] [-b bs] [-S seed] off len"); pwrite_cmd.oneline = diff --git a/io/quit.c b/io/quit.c index 67942b542..09d6d89ad 100644 --- a/io/quit.c +++ b/io/quit.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2003-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -49,6 +49,7 @@ quit_init(void) quit_cmd.name = _("quit"); quit_cmd.altname = _("q"); quit_cmd.cfunc = quit_f; + quit_cmd.foreign = 1; quit_cmd.oneline = _("exit xfs_io"); add_command(&quit_cmd); diff --git a/io/truncate.c b/io/truncate.c index 04f5ad9d3..916df94f6 100644 --- a/io/truncate.c +++ b/io/truncate.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2003-2004 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -43,8 +43,16 @@ truncate_f( char **argv) { off64_t offset; + unsigned int blocksize, sectsize; - offset = cvtnum(fgeom.blocksize, fgeom.sectsize, argv[1]); + if (foreign) { + blocksize = 4096; + sectsize = 512; + } else { + blocksize = fgeom.blocksize; + sectsize = fgeom.sectsize; + } + offset = cvtnum(blocksize, sectsize, argv[1]); if (offset < 0) { printf(_("non-numeric truncate argument -- %s\n"), argv[1]); return 0; @@ -64,6 +72,7 @@ truncate_init(void) truncate_cmd.cfunc = truncate_f; truncate_cmd.argmin = 1; truncate_cmd.argmax = 1; + truncate_cmd.foreign = 1; truncate_cmd.args = _("off"); truncate_cmd.oneline = _("truncates the current file at the given offset"); diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index d0f9cd647..2d6a003c7 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -3,7 +3,7 @@ xfs_io \- debug the IO path of an XFS filesystem .SH SYNOPSIS .nf -\f3xfs_io\f1 [ \f3\-c\f1 cmd ] ... [ \f3\-p\f1 prog ] [ \f3\-r\f1 ] file +\f3xfs_io\f1 [ \f3\-c\f1 cmd ] ... [ \f3\-p\f1 prog ] [ \f3\-Ffr\f1 ] file .fi .SH DESCRIPTION \f2xfs_io\f1 is a debugging tool like \f2xfs_db\f1(8), but is aimed @@ -23,6 +23,13 @@ This is the mechanism used to implement \f2xfs_bmap\f1(8). Set the program name for prompts and some error messages, the default value is \f2xfs_io\f1. .TP +\f3\-F\f1 +Allow \f2file\f1 to be ``foreign'', i.e. not in an XFS filesystem. +This mode has a restricted set of commands. +.TP +\f3\-f\f1 +Create \f2file\f1 if it does not already exist. +.TP \f3\-r\f1 Open \f2file\f1 read-only, initially. .SH CONCEPTS @@ -61,11 +68,14 @@ Calls \f2fsync\f1(2) to flush all in-core file state to disk. \f3o\f1 See the \f3open\f1 command. .TP -\f3open\f1 [ \f2-acdrstx\f1 ] [ \f2path\f1 ] +\f3open\f1 [ \f2-Facdrstx\f1 ] [ \f2path\f1 ] Closes the current file, and opens the file specified by \f2path\f1 instead. Without any arguments, displays statistics about the currently open file \- see the \f3stat\f1 command. .br +The \f3\-F\f1 option allows non-XFS (foreign) files to be opened and +operated on with a restricted command set. +.br The \f3\-a\f1 option opens append-only (O_APPEND). .br The \f3\-c\f1 option creates the file if it doesn't already exist (O_CREAT). -- 2.39.5