]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
insert (experimental) rtcp binary - for eric/others working on realtime Release-1_0_0
authorNathan Scott <nathans@sgi.com>
Wed, 9 May 2001 06:56:06 +0000 (06:56 +0000)
committerNathan Scott <nathans@sgi.com>
Wed, 9 May 2001 06:56:06 +0000 (06:56 +0000)
support, this is a useful little tool.

30 files changed:
Makefile
bmap/xfs_bmap.c
configure.in
db/io.c
debian/changelog
debian/control
debian/rules
doc/CHANGES
growfs/xfs_growfs.c
include/arch.h
include/builddefs.in
include/libxfs.h
include/platform_defs.h.in
libhandle/handle.c
libxfs/Makefile
libxfs/init.c
libxfs/rdwr.c
logprint/logprint.c
logprint/logprint.h
man/man5/xfs.5
man/man8/xfs_rtcp.8 [new file with mode: 0644]
mkfile/xfs_mkfile.c
mkfs/proto.c
mkfs/xfs_mkfs.c
repair/attr_repair.c
repair/io.c
repair/phase6.c
repair/sb.c
rtcp/Makefile [new file with mode: 0644]
rtcp/xfs_rtcp.c [new file with mode: 0644]

index bc1ddb87dbde76da29e70b87e2349f3e9260c9ae..885c9157451f43abaf8ed650479401c3b11858ba 100644 (file)
--- 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)
index ce413e3436a8043d5fc7d1b2d23789d3a79d6bc6..a15e5d42467aedfead42d2f0e0cb0336e4442c5b 100644 (file)
  * Bmap display utility for xfs.
  */
 
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
 #include <libxfs.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
 
 int aflag = 0; /* Attribute fork. */
 int lflag = 0; /* list number of blocks with each extent */
index 66e6b657aadb73b3c829f8ae4cbd609ea63fe96e..dc1a0b4f386fb13c53ca907fe46c4395bbd8edd6 100644 (file)
@@ -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 6ea949dc399058f5cdc6f328409d0f019ef6b834..b0413a76eca1a1b63fddbbc558e4420ad1b7840b 100644 (file)
--- a/db/io.c
+++ b/db/io.c
@@ -31,7 +31,6 @@
  */
 
 #include <libxfs.h>
-#include <errno.h>
 #include "command.h"
 #include "data.h"
 #include "type.h"
index c69c2e9020f572bd8c702b6b2d41557c3a9ab9f2..0115958840522dff654b930ee93927aff418a1a4 100644 (file)
@@ -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 <nathans@debian.org>  Tue,  8 May 2001 15:50:27 +1000
+
 xfsprogs (1.2.4) unstable; urgency=low
 
   * Add -L option to mkfs.xfs (filesystem label)
index 3495cb0d9ef848f16dcf0852e040e4f05bcf7359..39d8d7db2c02c4e2d9815ba824441e2c273c3b5e 100644 (file)
@@ -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.
index 0c1cfe7c89ad0eba4582d78f57907bd2eb20a5f7..b1904a803a9fcc3fc4b53d7c620fcd53356ba323 100755 (executable)
@@ -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
index 31f44a8ace67142edb1cce8ee5d54c5cf43177a6..ab72efe87d3e050c8fb206be6e6c564e6cff8fc9 100644 (file)
@@ -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)
index 1220689bfea6e3479a54344cc8f52916619c9cd3..db2307f640076d8ef56b9f06f10f8938ed5f52fa 100644 (file)
@@ -30,8 +30,6 @@
  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
  */
 
-#include <errno.h>
-#include <fcntl.h>
 #include <libxfs.h>
 #include <mntent.h>
 #include <sys/ioctl.h>
index 12ce1c5b1c265acb45b787180dc42e58e4c74d1a..d12b16b33ea67838aa07c165460aec65b0d1a5e6 100644 (file)
 # define __BYTE_ORDER  __BIG_ENDIAN
 #endif
 
-#else
-
-#include <linux/byteorder/swab.h>
-
 #endif /* __KERNEL__ */
 
 /* do we need conversion? */
index 71f15cf8cbff4db4a5c5455d4ae17cfc920a6aad..274c3a5431a3cd790dcf5b9ff3b4f31d8e9a498e 100644 (file)
@@ -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
 
index ba78c774660e9992c65fa740442c5fcce3f98886..a01b3b19f95b979d55643580d6caf3758b641216 100644 (file)
@@ -34,7 +34,6 @@
 
 #include "platform_defs.h"
 
-#include <uuid/uuid.h>
 #include <xfs_fs.h>
 #include <xfs_types.h>
 #include <arch.h>
@@ -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__ */
index 75e9c854aeb74266f7a1039cbd52eeeb97796d2b..3715fdd1339dc56552e56b5a58364119ed51f050 100644 (file)
 #include <unistd.h>
 #include <sys/param.h>
 #include <sys/types.h>
+#include <uuid/uuid.h>
 
-#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 <asm/byteorder.h>
+
+#include <errno.h>
+#include <fcntl.h>
 
-#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;
index 103e7c3ef4553b5e81870ba59745c68e07e3647c..2dfb31b4c4118041b71e96aed17cf054d985a8e6 100644 (file)
  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
  */
 
-#include <sys/types.h>
+#include <libxfs.h>
 #include <sys/stat.h>
-#include <sys/errno.h>
 #include <sys/ioctl.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-
 #include "handle.h"
-#include <libxfs.h>
 
 /* just pick a value we know is more than big enough */
 #define        MAXHANSIZ       64
index 644137a60091d921b196812fe7b358a4be45c932..e6a0eb4fe4c24954bc5a3c795f5a63a59e85e022 100644 (file)
@@ -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 \
index b58b05be3bc070dc85b0bcffa26972c382a886e4..19c67033509c45853457cd34292bef7c2b343d20 100644 (file)
@@ -32,8 +32,6 @@
 
 #define ustat __kernel_ustat
 #include <libxfs.h>
-#include <fcntl.h>
-#include <errno.h>
 #include <mntent.h>
 #include <sys/stat.h>
 #undef ustat
index 3c9aa38dc09da3a857b0c462512e93efc3a673b3..9cdcbc2c1e106af7bd2314749014357993a80959 100644 (file)
@@ -32,9 +32,6 @@
 
 #include <libxfs.h>
 #include <malloc.h>
-#include <errno.h>
-#include <fcntl.h>
-
 #include <xfs_log.h>
 #include <xfs_log_priv.h>
 
index cea2f0ce2a34a9df6c79fb193238d5c858a28d28..50025813ad1d01a0d164cf6368b9365421e6b1e2 100644 (file)
@@ -31,8 +31,6 @@
  */
 
 #include "logprint.h"
-#include <errno.h>
-#include <fcntl.h>
 
 int    print_data;
 int    print_only_data;
index 565de940b014933db9cec6f0c513edaec0273217..6027dfb0126d032db6f294031fdf629f359e5245 100644 (file)
@@ -33,8 +33,6 @@
 #define XFS_LOGPRINT_H
 
 #include <libxfs.h>
-#include <string.h>
-#include <errno.h>
 
 /*
  * define the userlevel xlog_t to be the subset of the kernel's
index a358f4aaf61228ba42b1b37b0315362d077e94e5..a7291d358db48bf0e5a7ea7ece9f599487fb4ecb 100644 (file)
@@ -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 (file)
index 0000000..f2368fa
--- /dev/null
@@ -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.
index e5b026cd98ee688403177c91f0bfaaaabd76668a..6903a83500f775db02a11f62b6d6027064f87f41 100644 (file)
  * Make file utility for xfs.
  */
 
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
+#include <libxfs.h>
+#include <malloc.h>
 #include <sys/stat.h>
-#include <fcntl.h>
+#include <sys/ioctl.h>
 #include <ctype.h>
-#include <malloc.h>
-#include <errno.h>
-#include <libxfs.h>
 
 #define        MAXBUFFERSIZE   (256 * 1024)
 
index abe566763546f4cf276e662473e22d373b142220..409557f311b12f24d1c3922574d48b7747bc57de 100644 (file)
@@ -31,8 +31,6 @@
  */
 
 #include <libxfs.h>
-#include <fcntl.h>
-#include <errno.h>
 #include "proto.h"
 
 /*
index 92dfecebfc07bc2d76c8bdc059b31c622fbce2e2..7272293ad4744c857fa2762058ee7d18acd0632e 100644 (file)
@@ -31,8 +31,7 @@
  */
 
 #include <libxfs.h>
-#include <fcntl.h>
-#include <errno.h>
+
 #include "xfs_mkfs.h"
 #include "proto.h"
 #include "volume.h"
index 727c2ce16bfb97a96be617984029e0b1d262261c..1cad070d2202585aaa5c6bf79ca144aee0b9b788 100644 (file)
@@ -31,8 +31,6 @@
  */
 
 #include <libxfs.h>
-#include <errno.h>
-
 #include "globals.h"
 #include "err_protos.h"
 #include "attr_repair.h"
index 0b400ceef8113470f1bec1b12b5c5df8def4256c..35de4d87034325c8663f3e085c038fb3e94396a8 100644 (file)
@@ -30,7 +30,6 @@
  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
  */
 
-#include <fcntl.h>
 #include <libxfs.h>
 #include "globals.h"
 #include "agheader.h"
index 8a78cb174a59a0f3cbbc7e640496a5638f240aba..0132c2b55ac1f98d611c50cf66104154f8bfc154 100644 (file)
@@ -30,7 +30,6 @@
  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
  */
 
-#include <errno.h>
 #include <libxfs.h>
 #include "avl.h"
 #include "globals.h"
index 2b2d6524d8f473aac7c019842c02df6e5c2b9247..bdbf2c72df49287795d9cdcc0b10b55e66f09353 100644 (file)
@@ -30,7 +30,6 @@
  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
  */
 
-#include <errno.h>
 #include <libxfs.h>
 #include <malloc.h>
 #include "agheader.h"
diff --git a/rtcp/Makefile b/rtcp/Makefile
new file mode 100644 (file)
index 0000000..b7d08bf
--- /dev/null
@@ -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 (file)
index 0000000..2f76ed2
--- /dev/null
@@ -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 <libxfs.h>
+#include <malloc.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+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;
+}