Skip to content

Commit

Permalink
Ocfs2-test: Move reflink() call to api-compat.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Sunil Mushran <[email protected]>
  • Loading branch information
Tristan Ye committed Nov 12, 2009
1 parent c624b7c commit 88803b8
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 1 deletion.
1 change: 1 addition & 0 deletions Config.make.in
Original file line number Diff line number Diff line change
Expand Up @@ -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@
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
11 changes: 11 additions & 0 deletions api-compat/include/reflink.h
Original file line number Diff line number Diff line change
@@ -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

9 changes: 9 additions & 0 deletions configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
68 changes: 68 additions & 0 deletions programs/reflink_tests/compat_reflink.c
Original file line number Diff line number Diff line change
@@ -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 [email protected]
*
* 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;
}

0 comments on commit 88803b8

Please sign in to comment.