From: Nathan Scott Date: Wed, 9 May 2001 06:56:06 +0000 (+0000) Subject: insert (experimental) rtcp binary - for eric/others working on realtime X-Git-Tag: Release-1_0_0 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f91dde66407c83f701aa0cff03c03fb30c20cfee;p=thirdparty%2Fxfsprogs-dev.git insert (experimental) rtcp binary - for eric/others working on realtime support, this is a useful little tool. --- diff --git a/Makefile b/Makefile index bc1ddb87d..885c91574 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ LSRCFILES = configure configure.in Makepkgs install-sh README VERSION LDIRT = config.* conftest* Logs/* built install.* install-dev.* *.gz SUBDIRS = include libxfs libhandle \ - bmap db fsck growfs logprint mkfile mkfs repair \ + bmap db fsck growfs logprint mkfile mkfs repair rtcp \ man doc debian build default: $(CONFIGURE) diff --git a/bmap/xfs_bmap.c b/bmap/xfs_bmap.c index ce413e343..a15e5d424 100644 --- a/bmap/xfs_bmap.c +++ b/bmap/xfs_bmap.c @@ -34,13 +34,9 @@ * Bmap display utility for xfs. */ -#include -#include -#include -#include -#include -#include #include +#include +#include int aflag = 0; /* Attribute fork. */ int lflag = 0; /* list number of blocks with each extent */ diff --git a/configure.in b/configure.in index 66e6b657a..dc1a0b4f3 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ AC_SUBST(pkg_name) # DEBUG=${DEBUG:-'-DDEBUG'} # -DNDEBUG -OPTIMIZER=${OPTIMIZER:-'-g'} # -O2 +OPTIMIZER=${OPTIMIZER:-'-g'} # (-O1 enforced default) MALLOCLIB=${MALLOCLIB:-''} # /usr/lib/libefence.a dnl Debug build? diff --git a/db/io.c b/db/io.c index 6ea949dc3..b0413a76e 100644 --- a/db/io.c +++ b/db/io.c @@ -31,7 +31,6 @@ */ #include -#include #include "command.h" #include "data.h" #include "type.h" diff --git a/debian/changelog b/debian/changelog index c69c2e902..011595884 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +xfsprogs (1.2.5) unstable; urgency=low + + * Fix missing Makefile include entries for LVM headers + * Add experimental xfs_rtcp (realtime copy) command + * PowerPC build failure fixups - thanks to Robert Ramiega + * Cleanup arch-specific code, esp. the byteswab routines + * Suggests xfsdump and attr packages + + -- Nathan Scott Tue, 8 May 2001 15:50:27 +1000 + xfsprogs (1.2.4) unstable; urgency=low * Add -L option to mkfs.xfs (filesystem label) diff --git a/debian/control b/debian/control index 3495cb0d9..39d8d7db2 100644 --- a/debian/control +++ b/debian/control @@ -7,6 +7,7 @@ Standards-Version: 3.1.1 Package: xfsprogs Depends: ${shlibs:Depends} +Suggests: xfsdump, attr Architecture: any Description: Utilities for managing the XFS filesystem A set of commands to use the XFS filesystem, including mkfs.xfs. diff --git a/debian/rules b/debian/rules index 0c1cfe7c8..b1904a803 100755 --- a/debian/rules +++ b/debian/rules @@ -11,8 +11,7 @@ pkgtmp = DIST_ROOT=`pwd`/$(dirtmp); export DIST_ROOT; pkgdev = DIST_ROOT=`pwd`/$(dirdev); export DIST_ROOT; stdenv = GZIP=-q; export GZIP; -options = DEBUG="-DNDEBUG"; OPTIMIZER="-O1 -g"; DISTRIBUTION="debian"; \ - export DEBUG OPTIMIZER DISTRIBUTION; +options = DEBUG=-DNDEBUG; DISTRIBUTION=debian; export DEBUG DISTRIBUTION; checkdir = test -f debian/rules build: built diff --git a/doc/CHANGES b/doc/CHANGES index 31f44a8ac..ab72efe87 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -2,6 +2,10 @@ xfsprogs-1.2.5 (07 May 2001) - fix missing Makefile include entries for LVM headers - configure script default man path now /usr/share/man + - add experimental xfs_rtcp (realtime copy) command + - powerpc build failure fixups - thanks to Robert Ramiega + - cleanup arch-specific code, esp. the byteswab routines + - as a result, move to -O1 as default for extern inlines xfsprogs-1.2.4 (01 May 2001) - added -L option to mkfs.xfs (filesystem label) diff --git a/growfs/xfs_growfs.c b/growfs/xfs_growfs.c index 1220689bf..db2307f64 100644 --- a/growfs/xfs_growfs.c +++ b/growfs/xfs_growfs.c @@ -30,8 +30,6 @@ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ -#include -#include #include #include #include diff --git a/include/arch.h b/include/arch.h index 12ce1c5b1..d12b16b33 100644 --- a/include/arch.h +++ b/include/arch.h @@ -43,10 +43,6 @@ # define __BYTE_ORDER __BIG_ENDIAN #endif -#else - -#include - #endif /* __KERNEL__ */ /* do we need conversion? */ diff --git a/include/builddefs.in b/include/builddefs.in index 71f15cf8c..274c3a543 100644 --- a/include/builddefs.in +++ b/include/builddefs.in @@ -67,7 +67,7 @@ PKG_DOC_DIR = @pkg_doc_dir@ # $(CXXFILES), or $(HFILES) and is used to construct the manifest list # during the "dist" phase (packaging). -CFLAGS += $(OPTIMIZER) $(DEBUG) -funsigned-char -Wall $(LCFLAGS) \ +CFLAGS += -O1 $(OPTIMIZER) $(DEBUG) -funsigned-char -Wall $(LCFLAGS) \ -I$(TOPDIR)/include '-DVERSION="$(PKG_VERSION)"' -D_GNU_SOURCE \ -D_FILE_OFFSET_BITS=64 -DXFS_BIG_FILES=1 -DXFS_BIG_FILESYSTEMS=1 diff --git a/include/libxfs.h b/include/libxfs.h index ba78c7746..a01b3b19f 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -34,7 +34,6 @@ #include "platform_defs.h" -#include #include #include #include @@ -468,8 +467,4 @@ extern void libxfs_dir2_free_log_bests (xfs_trans_t *, xfs_dabuf_t *, /* Shared utility routines */ extern unsigned int libxfs_log2_roundup(unsigned int i); - -/* ick */ -extern __inline__ __const__ __u64 __fswab64 (__u64 x); - #endif /* __LIBXFS_H__ */ diff --git a/include/platform_defs.h.in b/include/platform_defs.h.in index 75e9c854a..3715fdd13 100644 --- a/include/platform_defs.h.in +++ b/include/platform_defs.h.in @@ -44,19 +44,30 @@ #include #include #include +#include -#if (__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ <= 1)) -# define constpp const char * const * -#else -# define constpp char * const * +#if defined (__powerpc__) /* ppc fix from: Robert Ramiega (jedi@plukwa.net) */ +# define __BYTEORDER_HAS_U64__ #endif +#include + +#include +#include -#ifdef __sparc__ -# ifndef O_DIRECT +#ifndef O_DIRECT +# if defined (__powerpc__) +# define O_DIRECT 0400000 +# elif defined (__sparc__) # define O_DIRECT 0x100000 # endif #endif +#if (__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ <= 1)) +# define constpp const char * const * +#else +# define constpp char * const * +#endif + typedef loff_t xfs_off_t; typedef __uint64_t xfs_ino_t; typedef __uint32_t xfs_dev_t; diff --git a/libhandle/handle.c b/libhandle/handle.c index 103e7c3ef..2dfb31b4c 100644 --- a/libhandle/handle.c +++ b/libhandle/handle.c @@ -30,18 +30,10 @@ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ -#include +#include #include -#include #include - -#include -#include -#include -#include - #include "handle.h" -#include /* just pick a value we know is more than big enough */ #define MAXHANSIZ 64 diff --git a/libxfs/Makefile b/libxfs/Makefile index 644137a60..e6a0eb4fe 100644 --- a/libxfs/Makefile +++ b/libxfs/Makefile @@ -37,7 +37,7 @@ LIB = libxfs STATICLIBTARGET = $(LIB).a HFILES = xfs.h -CFILES = arch.c init.c logitem.c rdwr.c trans.c util.c \ +CFILES = init.c logitem.c rdwr.c trans.c util.c \ xfs_bit.c xfs_rtbit.c xfs_alloc.c xfs_ialloc.c xfs_rtalloc.c \ xfs_inode.c xfs_btree.c xfs_alloc_btree.c xfs_ialloc_btree.c \ xfs_bmap_btree.c xfs_da_btree.c xfs_dir.c xfs_dir_leaf.c \ diff --git a/libxfs/init.c b/libxfs/init.c index b58b05be3..19c670335 100644 --- a/libxfs/init.c +++ b/libxfs/init.c @@ -32,8 +32,6 @@ #define ustat __kernel_ustat #include -#include -#include #include #include #undef ustat diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index 3c9aa38dc..9cdcbc2c1 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -32,9 +32,6 @@ #include #include -#include -#include - #include #include diff --git a/logprint/logprint.c b/logprint/logprint.c index cea2f0ce2..50025813a 100644 --- a/logprint/logprint.c +++ b/logprint/logprint.c @@ -31,8 +31,6 @@ */ #include "logprint.h" -#include -#include int print_data; int print_only_data; diff --git a/logprint/logprint.h b/logprint/logprint.h index 565de940b..6027dfb01 100644 --- a/logprint/logprint.h +++ b/logprint/logprint.h @@ -33,8 +33,6 @@ #define XFS_LOGPRINT_H #include -#include -#include /* * define the userlevel xlog_t to be the subset of the kernel's diff --git a/man/man5/xfs.5 b/man/man5/xfs.5 index a358f4aaf..a7291d358 100644 --- a/man/man5/xfs.5 +++ b/man/man5/xfs.5 @@ -6,32 +6,33 @@ An XFS filesystem can reside on a regular disk partition or on a logical volume (see .IR lvm (8)). An XFS filesystem has up to three parts: -a data section, a log section, and a real-time section. -For disk partition filesystems, -the real-time section is absent, and +a data section, a log section, and a realtime section. +Using the default +.IR mkfs.xfs (8) +options, the realtime section is absent, and the log area is contained within the data section. For logical volume filesystems, -the real-time section is optional, +the realtime section is optional, and the log section can be separate from the data section or contained within it. The filesystem sections are divided into a certain number of .IR blocks , whose size is specified at -.IR mkfs (8) +.IR mkfs.xfs time with the .B \-b option. .PP The data section contains all the filesystem metadata (inodes, directories, indirect blocks) -as well as the user file data for ordinary (non-real-time) files +as well as the user file data for ordinary (non-realtime) files and the log area if the log is .I internal to the data section. The data section is divided into a number of \f2allocation groups\f1. The number and size of the allocation groups are chosen by -.I mkfs +.I mkfs.xfs so that there is normally a small number of equal-sized groups. The number of allocation groups controls the amount of parallelism available in file and block allocation. @@ -55,23 +56,23 @@ When mounting a filesystem after a crash, the log is read to complete operations that were in progress at the time of the crash. .PP -The real-time section is used to store the data of real-time files. +The realtime section is used to store the data of realtime files. These files had an attribute bit set through -.IR fcntl (2) +.IR ioctl (2) after file creation, before any data was written to the file. -The real-time section is divided into a number of +The realtime section is divided into a number of .I extents of fixed size (specified at -.I mkfs +.I mkfs.xfs time). -Each file in the real-time section has an extent size that -is a multiple of the real-time section extent size. +Each file in the realtime section has an extent size that +is a multiple of the realtime section extent size. .PP Each allocation group contains several data structures. The first sector contains the superblock. For allocation groups after the first, the superblock is just a copy and is not updated after -.IR mkfs . +.IR mkfs.xfs . The next three sectors contain information for block and inode allocation within the allocation group. Also contained within each allocation group are data structures @@ -85,30 +86,26 @@ is used to help distinguish one XFS filesystem from another, therefore you should avoid using .I dd or other block-by-block copying programs to copy XFS filesystems. -If two XFS filesystems on the same machine have the UUID, +If two XFS filesystems on the same machine have the same UUID, .I xfsdump -may become confused when doing incremental and resumed dumps. -(See +may become confused when doing incremental and resumed dumps +(refer to .IR xfsdump (8) -for more details.) -.I xfs_copy -or -.IR xfsdump / xfsrestore +for more details). +.I xfsdump +and +.I xfsrestore are recommended for making copies of XFS filesystems. -.PP -All these data structures are subject to change, and the -headers that specify their layout on disk are not provided. .SH SEE ALSO fs(5), mkfs.xfs(8), xfs_bmap(8), xfs_check(8), -xfs_copy(8), xfs_estimate(8), xfs_growfs(8), xfs_logprint(8), xfs_repair(8), xfsdump(8), xfsrestore(8), -fcntl(2), +ioctl(2), lvm(8). diff --git a/man/man8/xfs_rtcp.8 b/man/man8/xfs_rtcp.8 new file mode 100644 index 000000000..f2368fae5 --- /dev/null +++ b/man/man8/xfs_rtcp.8 @@ -0,0 +1,44 @@ +.TH xfs_rtcp 8 +.SH NAME +xfs_rtcp \- XFS realtime copy command +.SH SYNOPSIS +.nf +\f3xfs_rtcp\f1 [\f3\-e\f1 extsize] [\f3\-p\f1] \f2source\f1... \f2target\f1 +.fi +.SH DESCRIPTION +.I xfs_rtcp +copies a file to the realtime partition on an XFS filesystem. +If there is more than one +.I source +and +.IR target , +the final argument (the +.IR target ) +must be a directory which already exists. +.SH OPTIONS +.TP +\f3\-e\f1 extsize +Sets the extent size of the destination realtime file. +.TP +\f3\-p\f1 +Use if the size of the source file is not an even multiple of +the block size of the destination filesystem. +When +\f3\-p\f1 is specified +.I xfs_rtcp +will pad the destination file to a size which is an even multiple +of the filesystem block size. +This is necessary since the realtime file is created using +direct I/O and the minimum I/O is the filesystem block size. +.SH "SEE ALSO" +xfs(5), +mkfs.xfs(8), +mount(8). +.SH CAVEATS +Currently, realtime partitions are not supported under the Linux +version of XFS, and use of a realtime partition +.BR "WILL CAUSE CORRUPTION" +on the data partition. +As such, this command is made available for curious +.B "DEVELOPERS ONLY" +at this point in time. diff --git a/mkfile/xfs_mkfile.c b/mkfile/xfs_mkfile.c index e5b026cd9..6903a8350 100644 --- a/mkfile/xfs_mkfile.c +++ b/mkfile/xfs_mkfile.c @@ -34,15 +34,11 @@ * Make file utility for xfs. */ -#include -#include -#include +#include +#include #include -#include +#include #include -#include -#include -#include #define MAXBUFFERSIZE (256 * 1024) diff --git a/mkfs/proto.c b/mkfs/proto.c index abe566763..409557f31 100644 --- a/mkfs/proto.c +++ b/mkfs/proto.c @@ -31,8 +31,6 @@ */ #include -#include -#include #include "proto.h" /* diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 92dfecebf..7272293ad 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -31,8 +31,7 @@ */ #include -#include -#include + #include "xfs_mkfs.h" #include "proto.h" #include "volume.h" diff --git a/repair/attr_repair.c b/repair/attr_repair.c index 727c2ce16..1cad070d2 100644 --- a/repair/attr_repair.c +++ b/repair/attr_repair.c @@ -31,8 +31,6 @@ */ #include -#include - #include "globals.h" #include "err_protos.h" #include "attr_repair.h" diff --git a/repair/io.c b/repair/io.c index 0b400ceef..35de4d870 100644 --- a/repair/io.c +++ b/repair/io.c @@ -30,7 +30,6 @@ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ -#include #include #include "globals.h" #include "agheader.h" diff --git a/repair/phase6.c b/repair/phase6.c index 8a78cb174..0132c2b55 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -30,7 +30,6 @@ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ -#include #include #include "avl.h" #include "globals.h" diff --git a/repair/sb.c b/repair/sb.c index 2b2d6524d..bdbf2c72d 100644 --- a/repair/sb.c +++ b/repair/sb.c @@ -30,7 +30,6 @@ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ -#include #include #include #include "agheader.h" diff --git a/rtcp/Makefile b/rtcp/Makefile new file mode 100644 index 000000000..b7d08bfb4 --- /dev/null +++ b/rtcp/Makefile @@ -0,0 +1,46 @@ +# +# Copyright (c) 2000 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 +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write the Free Software Foundation, Inc., 59 +# Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, +# Mountain View, CA 94043, or: +# +# http://www.sgi.com +# +# For further information regarding this notice, see: +# +# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ +# + +TOPDIR = .. +include $(TOPDIR)/include/builddefs + +CMDTARGET = xfs_rtcp +CFILES = xfs_rtcp.c + +default: $(CMDTARGET) + +include $(BUILDRULES) + +install: default + $(INSTALL) -m 755 -d $(PKG_BIN_DIR) + $(INSTALL) -m 755 $(CMDTARGET) $(PKG_BIN_DIR) +install-dev: diff --git a/rtcp/xfs_rtcp.c b/rtcp/xfs_rtcp.c new file mode 100644 index 000000000..2f76ed2aa --- /dev/null +++ b/rtcp/xfs_rtcp.c @@ -0,0 +1,406 @@ +/* + * Copyright (c) 2000 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include +#include +#include + +int rtcp(char *, char *, int); +int xfsrtextsize(char *path); + +int pflag; +char *progname; + +void +usage() +{ + fprintf(stderr, "%s [-e extsize] [-p] source target\n", progname); + exit(2); +} + +int +main(int argc, char **argv) +{ + register int c, i, r, errflg = 0; + struct stat s2; + int eflag; + int extsize = - 1; + + progname = basename(argv[0]); + + while ((c = getopt(argc, argv, "pe:V")) != EOF) { + switch (c) { + case 'e': + eflag = 1; + extsize = atoi(optarg); + break; + case 'p': + pflag = 1; + break; + case 'V': + printf("%s version %s\n", progname, VERSION); + break; + default: + errflg++; + } + } + + /* + * Check for sufficient arguments or a usage error. + */ + argc -= optind; + argv = &argv[optind]; + + if (argc < 2) { + fprintf(stderr, "%s: must specify files to copy\n", progname); + errflg++; + } + + if (errflg) + usage(); + + /* + * If there is more than a source and target, + * the last argument (the target) must be a directory + * which really exists. + */ + if (argc > 2) { + if (stat(argv[argc-1], &s2) < 0) { + fprintf(stderr, "%s: stat of %s failed\n", + progname, argv[argc-1]); + exit(2); + } + + if (!S_ISDIR(s2.st_mode)) { + fprintf(stderr, "%s: final argument is not directory\n", + progname); + usage(); + } + } + + /* + * Perform a multiple argument rtcp by + * multiple invocations of rtcp(). + */ + r = 0; + for (i = 0; i < argc-1; i++) + r += rtcp(argv[i], argv[argc-1], extsize); + + /* + * Show errors by nonzero exit code. + */ + exit(r?2:0); +} + +int +rtcp( char *source, char *target, int fextsize) +{ + int fromfd, tofd, readct, writect, iosz, reopen; + int remove = 0, rtextsize; + char *sp, *fbuf, *ptr; + char tbuf[ PATH_MAX ]; + struct stat s1, s2; + struct fsxattr fsxattr; + struct dioattr dioattr; + + /* + * While source or target have trailing /, remove them + * unless only "/". + */ + sp = source + strlen(source); + if (sp) { + while (*--sp == '/' && sp > source) + *sp = '\0'; + } + sp = target + strlen(target); + if (sp) { + while (*--sp == '/' && sp > target) + *sp = '\0'; + } + + if ( stat(source, &s1) ) { + fprintf(stderr, "%s: failed stat on\n", progname); + perror(source); + return( -1); + } + + /* + * check for a realtime partition + */ + sprintf(tbuf,"%s",target); + if ( stat(target, &s2) ) { + if (!S_ISDIR(s2.st_mode)) { + /* take out target file name */ + if ((ptr = strrchr(tbuf, '/')) != NULL) + *ptr = '\0'; + else + sprintf(tbuf, "."); + } + } + + if ( (rtextsize = xfsrtextsize( tbuf )) <= 0 ) { + fprintf(stderr, "%s: %s filesystem has no realtime partition\n", + progname, tbuf); + return( -1 ); + } + + /* + * check if target is a directory + */ + sprintf(tbuf,"%s",target); + if ( !stat(target, &s2) ) { + if (S_ISDIR(s2.st_mode)) { + sprintf(tbuf,"%s/%s",target, basename(source)); + } + } + + if ( stat(tbuf, &s2) ) { + /* + * create the file if it does not exist + */ + if ( (tofd = open(tbuf, O_RDWR|O_CREAT|O_DIRECT, 0666)) < 0 ) { + fprintf(stderr, "%s: Open of %s failed.\n", + progname, tbuf); + return( -1 ); + } + remove = 1; + + /* + * mark the file as a realtime file + */ + fsxattr.fsx_xflags = XFS_XFLAG_REALTIME; + if (fextsize != -1 ) + fsxattr.fsx_extsize = fextsize; + else + fsxattr.fsx_extsize = 0; + + if ( ioctl( tofd, XFS_IOC_FSSETXATTR, &fsxattr) ) { + fprintf(stderr, "%s: Set attributes on %s failed.\n", + progname, tbuf); + close( tofd ); + unlink( tbuf ); + return( -1 ); + } + } else { + /* + * open existing file + */ + if ( (tofd = open(tbuf, O_RDWR|O_DIRECT)) < 0 ) { + fprintf(stderr, "%s: Open of %s failed.\n", + progname, tbuf); + return( -1 ); + } + + if ( ioctl( tofd, XFS_IOC_FSGETXATTR, &fsxattr) ) { + fprintf(stderr, "%s: Get attributes of %s failed.\n", + progname, tbuf); + close( tofd ); + return( -1 ); + } + + /* + * check if the existing file is already a realtime file + */ + if ( !(fsxattr.fsx_xflags & XFS_XFLAG_REALTIME) ) { + fprintf(stderr, "%s: %s is not a realtime file.\n", + progname, tbuf); + return( -1 ); + } + + /* + * check for matching extent size + */ + if ( (fextsize != -1) && (fsxattr.fsx_extsize != fextsize) ) { + fprintf(stderr, "%s: %s file extent size is %d, " + "instead of %d.\n", + progname, tbuf, fsxattr.fsx_extsize, fextsize); + return( -1 ); + } + } + + /* + * open the source file + */ + reopen = 0; + if ( (fromfd = open(source, O_RDONLY|O_DIRECT)) < 0 ) { + fprintf(stderr, "%s: Open of %s source failed.\n", + progname, source); + close( tofd ); + if (remove) + unlink( tbuf ); + return( -1 ); + } + + fsxattr.fsx_xflags = 0; + fsxattr.fsx_extsize = 0; + if ( ioctl( fromfd, XFS_IOC_FSGETXATTR, &fsxattr) ) { + reopen = 1; + } else { + if (! (fsxattr.fsx_xflags & XFS_XFLAG_REALTIME) ){ + fprintf(stderr, "%s: %s is not a realtime file.\n", + progname, source); + reopen = 1; + } + } + + if (reopen) { + close( fromfd ); + if ( (fromfd = open(source, O_RDONLY )) < 0 ) { + fprintf(stderr, "%s: Open of %s source failed.\n", + progname, source); + close( tofd ); + if (remove) + unlink( tbuf ); + return( -1 ); + } + } + + /* + * get direct I/O parameters + */ + if ( ioctl( tofd, XFS_IOC_DIOINFO, &dioattr) ) { + fprintf(stderr, "%s: Could not get direct I/O information.\n", + progname); + close( fromfd ); + close( tofd ); + if ( remove ) + unlink( tbuf ); + return( -1 ); + } + + if ( rtextsize % dioattr.d_miniosz ) { + fprintf(stderr, "%s: extent size %d not a multiple of %d.\n", + progname, rtextsize, dioattr.d_miniosz); + close( fromfd ); + close( tofd ); + if ( remove ) + unlink( tbuf ); + return( -1 ); + } + + /* + * Check that the source file size is a multiple of the + * file system block size. + */ + if ( s1.st_size % dioattr.d_miniosz ) { + printf("The size of %s is not a multiple of %d.\n", + source, dioattr.d_miniosz); + if ( pflag ) { + printf("%s will be padded to %lld bytes.\n", + tbuf, + (((s1.st_size / dioattr.d_miniosz) + 1) * + dioattr.d_miniosz) ); + + } else { + printf("Use the -p option to pad %s " + "to a size which is a multiple of %d bytes.\n", + tbuf, dioattr.d_miniosz); + close( fromfd ); + close( tofd ); + if ( remove ) + unlink( tbuf ); + return( -1 ); + } + } + + iosz = dioattr.d_miniosz; + fbuf = memalign( dioattr.d_mem, iosz); + bzero (fbuf, iosz); + + /* + * read the entire source file + */ + while ( ( readct = read( fromfd, fbuf, iosz) ) != 0 ) { + /* + * if there is a read error - break + */ + if (readct < 0 ) { + break; + } + + /* + * if there is a short read, pad to a block boundary + */ + if ( readct != iosz ) { + if ( (readct % dioattr.d_miniosz) != 0 ) { + readct = ( (readct/dioattr.d_miniosz) + 1 ) * + dioattr.d_miniosz; + } + } + + /* + * write to target file + */ + writect = write( tofd, fbuf, readct); + + if ( writect != readct ) { + fprintf(stderr, "%s: Write error.\n", progname); + close(fromfd); + close(tofd); + free( fbuf ); + return( -1 ); + } + + bzero( fbuf, iosz); + } + + close(fromfd); + close(tofd); + free( fbuf ); + return( 0 ); +} + +/* + * Determine the realtime extent size of the XFS file system + */ +int +xfsrtextsize( char *path) +{ + int fd, rval, rtextsize; + xfs_fsop_geom_t geo; + + fd = open( path, O_RDONLY ); + if ( fd < 0 ) { + fprintf(stderr, "%s: Could not open ", progname); + perror(path); + return -1; + } + rval = ioctl(fd, XFS_IOC_FSGEOMETRY, &geo ); + close(fd); + + rtextsize = geo.rtextsize * geo.blocksize; + + if ( rval < 0 ) + return -1; + return rtextsize; +}