[Ocfs2-test-devel] [PATCH 11/13] Ocfs2-test: Move reflink() call to api-compat.
Tristan Ye
tristan.ye at oracle.com
Wed Nov 11 01:59:38 PST 2009
Move reflink()(ioctl based) call to api-compat to make it
compatible for old kernels which have no reflink(2)
implementation(it will be included in mainline soon?)
For new kernels, we'll use reflink(2) system call by default.
Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
---
Config.make.in | 1 +
Makefile | 3 +-
api-compat/include/reflink.h | 11 +++++
configure.in | 9 ++++
programs/reflink_tests/compat_reflink.c | 68 +++++++++++++++++++++++++++++++
5 files changed, 91 insertions(+), 1 deletions(-)
create mode 100644 api-compat/include/reflink.h
create mode 100644 programs/reflink_tests/compat_reflink.c
diff --git a/Config.make.in b/Config.make.in
index a03274e..3fc6146 100644
--- a/Config.make.in
+++ b/Config.make.in
@@ -30,6 +30,7 @@ TESTDIR = $(libdir)/ocfs2-test
top_builddir = .
EXTRA_CFLAGS += @API_COMPAT_CFLAGS@
+NO_REFLINK = @NO_REFLINK@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
diff --git a/Makefile b/Makefile
index c412e61..fdbc31c 100644
--- a/Makefile
+++ b/Makefile
@@ -27,7 +27,8 @@ SUBDIRS = programs utilities tests suites
SUBDIRS += vendor
API_COMPAT_FILES = \
- api-compat/include/splice.h
+ api-compat/include/splice.h \
+ api-compat/include/reflink.h
DIST_FILES = \
COPYING \
diff --git a/api-compat/include/reflink.h b/api-compat/include/reflink.h
new file mode 100644
index 0000000..97f4c94
--- /dev/null
+++ b/api-compat/include/reflink.h
@@ -0,0 +1,11 @@
+#ifndef API_REFLINK_H
+#define API_REFLINK_H
+
+#ifdef NO_REFLINK
+
+int reflink(const char *oldpath, const char *newpath, unsigned long preserve);
+
+#endif
+
+#endif
+
diff --git a/configure.in b/configure.in
index b45bdba..9568d3e 100644
--- a/configure.in
+++ b/configure.in
@@ -135,6 +135,15 @@ OCFS2_CHECK_HEADERS([splice() in bits/fcntl.h], bits/fcntl.h,
, splice_compat_header="splice.h", [splice (int __fdin])
API_COMPAT_HEADERS="$API_COMPAT_HEADERS $splice_compat_header"
+NO_REFLINK=
+OCFS2_CHECK_HEADERS([reflink() in unistd.h], unistd.h, ,
+ NO_REFLINK=yes, [reflink])
+AC_SUBST(NO_REFLINK)
+
+if test "x$NO_REFLINK" = "xyes"; then
+API_COMPAT_HEADERS="$API_COMPAT_HEADERS reflink.h"
+fi
+
for h in $API_COMPAT_HEADERS; do
API_COMPAT_CFLAGS="$API_COMPAT_CFLAGS -include \$(TOPDIR)/api-compat/include/$h"
done
diff --git a/programs/reflink_tests/compat_reflink.c b/programs/reflink_tests/compat_reflink.c
new file mode 100644
index 0000000..0c30bf2
--- /dev/null
+++ b/programs/reflink_tests/compat_reflink.c
@@ -0,0 +1,68 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * compat_reflink.c
+ *
+ * Use ioctl() based reflink call for old kernels which have no
+ * reflink(2) system call implemented.
+ *
+ * Written by tristan.ye at oracle.com
+ *
+ * Copyright (C) 2009 Oracle. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#define _GNU_SOURCE
+#define _XOPEN_SOURCE 500
+#define _LARGEFILE64_SOURCE
+
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include <ocfs2/ocfs2.h>
+
+extern int open_ro_flags;
+
+int reflink(const char *oldpath, const char *newpath, unsigned long preserve)
+{
+ int fd, ret, o_ret;
+ struct reflink_arguments args;
+
+ args.old_path = (__u64)oldpath;
+ args.new_path = (__u64)newpath;
+ args.preserve = preserve;
+
+ fd = open64(oldpath, open_ro_flags);
+ if (fd < 0) {
+ o_ret = fd;
+ fd = errno;
+ fprintf(stderr, "open file %s failed:%d:%s\n", oldpath, fd,
+ strerror(fd));
+ fd = o_ret;
+ return fd;
+ }
+
+ ret = ioctl(fd, OCFS2_IOC_REFLINK, &args);
+ if (ret) {
+ o_ret = ret;
+ ret = errno;
+ fprintf(stderr, "ioctl failed:%d:%s\n", ret, strerror(ret));
+ close(fd);
+ ret = o_ret;
+ return ret;
+ }
+
+ close(fd);
+
+ return 0;
+}
--
1.5.5
More information about the Ocfs2-test-devel
mailing list