zts: block cloning tests

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Kay Pedersen <mail@mkwg.de>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Sponsored-By: OpenDrives Inc.
Sponsored-By: Klara Inc.
Closes #15050
Closes #405
Closes #13349
This commit is contained in:
Rob Norris 2023-07-11 20:46:33 +10:00 committed by Brian Behlendorf
parent 2768dc04cc
commit 36d1a3ef4e
19 changed files with 1016 additions and 0 deletions

View File

@ -34,6 +34,15 @@ tags = ['functional', 'acl', 'posix-sa']
tests = ['atime_003_pos', 'root_relatime_on'] tests = ['atime_003_pos', 'root_relatime_on']
tags = ['functional', 'atime'] tags = ['functional', 'atime']
[tests/functional/block_cloning:Linux]
tests = ['block_cloning_copyfilerange', 'block_cloning_copyfilerange_partial',
'block_cloning_ficlone', 'block_cloning_ficlonerange',
'block_cloning_ficlonerange_partial',
'block_cloning_disabled_copyfilerange', 'block_cloning_disabled_ficlone',
'block_cloning_disabled_ficlonerange',
'block_cloning_copyfilerange_cross_dataset']
tags = ['functional', 'block_cloning']
[tests/functional/chattr:Linux] [tests/functional/chattr:Linux]
tests = ['chattr_001_pos', 'chattr_002_neg'] tests = ['chattr_001_pos', 'chattr_002_neg']
tags = ['functional', 'chattr'] tags = ['functional', 'chattr']

View File

@ -134,6 +134,12 @@ ci_reason = 'CI runner doesn\'t have all requirements'
# #
idmap_reason = 'Idmapped mount needs kernel 5.12+' idmap_reason = 'Idmapped mount needs kernel 5.12+'
#
# copy_file_range() is not supported by all kernels
#
cfr_reason = 'Kernel copy_file_range support required'
cfr_cross_reason = 'copy_file_range(2) cross-filesystem needs kernel 5.3+'
# #
# These tests are known to fail, thus we use this list to prevent these # These tests are known to fail, thus we use this list to prevent these
# failures from failing the job as a whole; only unexpected failures # failures from failing the job as a whole; only unexpected failures
@ -288,6 +294,14 @@ elif sys.platform.startswith('linux'):
'idmap_mount/idmap_mount_003': ['SKIP', idmap_reason], 'idmap_mount/idmap_mount_003': ['SKIP', idmap_reason],
'idmap_mount/idmap_mount_004': ['SKIP', idmap_reason], 'idmap_mount/idmap_mount_004': ['SKIP', idmap_reason],
'idmap_mount/idmap_mount_005': ['SKIP', idmap_reason], 'idmap_mount/idmap_mount_005': ['SKIP', idmap_reason],
'block_cloning/block_cloning_disabled_copyfilerange':
['SKIP', cfr_reason],
'block_cloning/block_cloning_copyfilerange':
['SKIP', cfr_reason],
'block_cloning/block_cloning_copyfilerange_partial':
['SKIP', cfr_reason],
'block_cloning/block_cloning_copyfilerange_cross_dataset':
['SKIP', cfr_cross_reason],
}) })

View File

@ -1,6 +1,7 @@
/badsend /badsend
/btree_test /btree_test
/chg_usr_exec /chg_usr_exec
/clonefile
/devname2devid /devname2devid
/dir_rd_update /dir_rd_update
/draid /draid

View File

@ -119,6 +119,7 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/renameat2
scripts_zfs_tests_bin_PROGRAMS += %D%/xattrtest scripts_zfs_tests_bin_PROGRAMS += %D%/xattrtest
scripts_zfs_tests_bin_PROGRAMS += %D%/zed_fd_spill-zedlet scripts_zfs_tests_bin_PROGRAMS += %D%/zed_fd_spill-zedlet
scripts_zfs_tests_bin_PROGRAMS += %D%/idmap_util scripts_zfs_tests_bin_PROGRAMS += %D%/idmap_util
scripts_zfs_tests_bin_PROGRAMS += %D%/clonefile
%C%_idmap_util_LDADD = libspl.la %C%_idmap_util_LDADD = libspl.la

View File

@ -0,0 +1,333 @@
/*
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2023, Rob Norris <robn@despairlabs.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*
* This program is to test the availability and behaviour of copy_file_range,
* FICLONE, FICLONERANGE and FIDEDUPERANGE in the Linux kernel. It should
* compile and run even if these features aren't exposed through the libc.
*/
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <stdlib.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#ifndef __NR_copy_file_range
#if defined(__x86_64__)
#define __NR_copy_file_range (326)
#elif defined(__i386__)
#define __NR_copy_file_range (377)
#elif defined(__s390__)
#define __NR_copy_file_range (375)
#elif defined(__arm__)
#define __NR_copy_file_range (391)
#elif defined(__aarch64__)
#define __NR_copy_file_range (285)
#elif defined(__powerpc__)
#define __NR_copy_file_range (379)
#else
#error "no definition of __NR_copy_file_range for this platform"
#endif
#endif /* __NR_copy_file_range */
ssize_t
copy_file_range(int, loff_t *, int, loff_t *, size_t, unsigned int)
__attribute__((weak));
static inline ssize_t
cf_copy_file_range(int sfd, loff_t *soff, int dfd, loff_t *doff,
size_t len, unsigned int flags)
{
if (copy_file_range)
return (copy_file_range(sfd, soff, dfd, doff, len, flags));
return (
syscall(__NR_copy_file_range, sfd, soff, dfd, doff, len, flags));
}
/* Define missing FICLONE */
#ifdef FICLONE
#define CF_FICLONE FICLONE
#else
#define CF_FICLONE _IOW(0x94, 9, int)
#endif
/* Define missing FICLONERANGE and support structs */
#ifdef FICLONERANGE
#define CF_FICLONERANGE FICLONERANGE
typedef struct file_clone_range cf_file_clone_range_t;
#else
typedef struct {
int64_t src_fd;
uint64_t src_offset;
uint64_t src_length;
uint64_t dest_offset;
} cf_file_clone_range_t;
#define CF_FICLONERANGE _IOW(0x94, 13, cf_file_clone_range_t)
#endif
/* Define missing FIDEDUPERANGE and support structs */
#ifdef FIDEDUPERANGE
#define CF_FIDEDUPERANGE FIDEDUPERANGE
#define CF_FILE_DEDUPE_RANGE_SAME FILE_DEDUPE_RANGE_SAME
#define CF_FILE_DEDUPE_RANGE_DIFFERS FILE_DEDUPE_RANGE_DIFFERS
typedef struct file_dedupe_range_info cf_file_dedupe_range_info_t;
typedef struct file_dedupe_range cf_file_dedupe_range_t;
#else
typedef struct {
int64_t dest_fd;
uint64_t dest_offset;
uint64_t bytes_deduped;
int32_t status;
uint32_t reserved;
} cf_file_dedupe_range_info_t;
typedef struct {
uint64_t src_offset;
uint64_t src_length;
uint16_t dest_count;
uint16_t reserved1;
uint32_t reserved2;
cf_file_dedupe_range_info_t info[0];
} cf_file_dedupe_range_t;
#define CF_FIDEDUPERANGE _IOWR(0x94, 54, cf_file_dedupe_range_t)
#define CF_FILE_DEDUPE_RANGE_SAME (0)
#define CF_FILE_DEDUPE_RANGE_DIFFERS (1)
#endif
typedef enum {
CF_MODE_NONE,
CF_MODE_CLONE,
CF_MODE_CLONERANGE,
CF_MODE_COPYFILERANGE,
CF_MODE_DEDUPERANGE,
} cf_mode_t;
static int
usage(void)
{
printf(
"usage:\n"
" FICLONE:\n"
" clonefile -c <src> <dst>\n"
" FICLONERANGE:\n"
" clonefile -r <src> <dst> <soff> <doff> <len>\n"
" copy_file_range:\n"
" clonefile -f <src> <dst> <soff> <doff> <len>\n"
" FIDEDUPERANGE:\n"
" clonefile -d <src> <dst> <soff> <doff> <len>\n");
return (1);
}
int do_clone(int sfd, int dfd);
int do_clonerange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len);
int do_copyfilerange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len);
int do_deduperange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len);
int quiet = 0;
int
main(int argc, char **argv)
{
cf_mode_t mode = CF_MODE_NONE;
char c;
while ((c = getopt(argc, argv, "crfdq")) != -1) {
switch (c) {
case 'c':
mode = CF_MODE_CLONE;
break;
case 'r':
mode = CF_MODE_CLONERANGE;
break;
case 'f':
mode = CF_MODE_COPYFILERANGE;
break;
case 'd':
mode = CF_MODE_DEDUPERANGE;
break;
case 'q':
quiet = 1;
break;
}
}
if (mode == CF_MODE_NONE || (argc-optind) < 2 ||
(mode != CF_MODE_CLONE && (argc-optind) < 5))
return (usage());
loff_t soff = 0, doff = 0;
size_t len = 0;
if (mode != CF_MODE_CLONE) {
soff = strtoull(argv[optind+2], NULL, 10);
if (soff == ULLONG_MAX) {
fprintf(stderr, "invalid source offset");
return (1);
}
doff = strtoull(argv[optind+3], NULL, 10);
if (doff == ULLONG_MAX) {
fprintf(stderr, "invalid dest offset");
return (1);
}
len = strtoull(argv[optind+4], NULL, 10);
if (len == ULLONG_MAX) {
fprintf(stderr, "invalid length");
return (1);
}
}
int sfd = open(argv[optind], O_RDONLY);
if (sfd < 0) {
fprintf(stderr, "open: %s: %s\n",
argv[optind], strerror(errno));
return (1);
}
int dfd = open(argv[optind+1], O_WRONLY|O_CREAT,
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if (sfd < 0) {
fprintf(stderr, "open: %s: %s\n",
argv[optind+1], strerror(errno));
close(sfd);
return (1);
}
int err;
switch (mode) {
case CF_MODE_CLONE:
err = do_clone(sfd, dfd);
break;
case CF_MODE_CLONERANGE:
err = do_clonerange(sfd, dfd, soff, doff, len);
break;
case CF_MODE_COPYFILERANGE:
err = do_copyfilerange(sfd, dfd, soff, doff, len);
break;
case CF_MODE_DEDUPERANGE:
err = do_deduperange(sfd, dfd, soff, doff, len);
break;
default:
abort();
}
off_t spos = lseek(sfd, 0, SEEK_CUR);
off_t slen = lseek(sfd, 0, SEEK_END);
off_t dpos = lseek(dfd, 0, SEEK_CUR);
off_t dlen = lseek(dfd, 0, SEEK_END);
fprintf(stderr, "file offsets: src=%lu/%lu; dst=%lu/%lu\n", spos, slen,
dpos, dlen);
close(dfd);
close(sfd);
return (err == 0 ? 0 : 1);
}
int
do_clone(int sfd, int dfd)
{
fprintf(stderr, "using FICLONE\n");
int err = ioctl(dfd, CF_FICLONE, sfd);
if (err < 0) {
fprintf(stderr, "ioctl(FICLONE): %s\n", strerror(errno));
return (err);
}
return (0);
}
int
do_clonerange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len)
{
fprintf(stderr, "using FICLONERANGE\n");
cf_file_clone_range_t fcr = {
.src_fd = sfd,
.src_offset = soff,
.src_length = len,
.dest_offset = doff,
};
int err = ioctl(dfd, CF_FICLONERANGE, &fcr);
if (err < 0) {
fprintf(stderr, "ioctl(FICLONERANGE): %s\n", strerror(errno));
return (err);
}
return (0);
}
int
do_copyfilerange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len)
{
fprintf(stderr, "using copy_file_range\n");
ssize_t copied = cf_copy_file_range(sfd, &soff, dfd, &doff, len, 0);
if (copied < 0) {
fprintf(stderr, "copy_file_range: %s\n", strerror(errno));
return (1);
}
if (copied != len) {
fprintf(stderr, "copy_file_range: copied less than requested: "
"requested=%lu; copied=%lu\n", len, copied);
return (1);
}
return (0);
}
int
do_deduperange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len)
{
fprintf(stderr, "using FIDEDUPERANGE\n");
char buf[sizeof (cf_file_dedupe_range_t)+
sizeof (cf_file_dedupe_range_info_t)] = {0};
cf_file_dedupe_range_t *fdr = (cf_file_dedupe_range_t *)&buf[0];
cf_file_dedupe_range_info_t *fdri =
(cf_file_dedupe_range_info_t *)
&buf[sizeof (cf_file_dedupe_range_t)];
fdr->src_offset = soff;
fdr->src_length = len;
fdr->dest_count = 1;
fdri->dest_fd = dfd;
fdri->dest_offset = doff;
int err = ioctl(sfd, CF_FIDEDUPERANGE, fdr);
if (err != 0)
fprintf(stderr, "ioctl(FIDEDUPERANGE): %s\n", strerror(errno));
if (fdri->status < 0) {
fprintf(stderr, "dedup failed: %s\n", strerror(-fdri->status));
err = -1;
} else if (fdri->status == CF_FILE_DEDUPE_RANGE_DIFFERS) {
fprintf(stderr, "dedup failed: range differs\n");
err = -1;
}
return (err);
}

View File

@ -182,6 +182,7 @@ export ZFS_FILES='zdb
export ZFSTEST_FILES='badsend export ZFSTEST_FILES='badsend
btree_test btree_test
chg_usr_exec chg_usr_exec
clonefile
devname2devid devname2devid
dir_rd_update dir_rd_update
draid draid

View File

@ -90,6 +90,7 @@ nobase_dist_datadir_zfs_tests_tests_DATA += \
functional/alloc_class/alloc_class.kshlib \ functional/alloc_class/alloc_class.kshlib \
functional/atime/atime.cfg \ functional/atime/atime.cfg \
functional/atime/atime_common.kshlib \ functional/atime/atime_common.kshlib \
functional/block_cloning/block_cloning.kshlib \
functional/cache/cache.cfg \ functional/cache/cache.cfg \
functional/cache/cache.kshlib \ functional/cache/cache.kshlib \
functional/cachefile/cachefile.cfg \ functional/cachefile/cachefile.cfg \
@ -437,6 +438,17 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/atime/root_atime_on.ksh \ functional/atime/root_atime_on.ksh \
functional/atime/root_relatime_on.ksh \ functional/atime/root_relatime_on.ksh \
functional/atime/setup.ksh \ functional/atime/setup.ksh \
functional/block_cloning/cleanup.ksh \
functional/block_cloning/setup.ksh \
functional/block_cloning/block_cloning_copyfilerange_cross_dataset.ksh \
functional/block_cloning/block_cloning_copyfilerange.ksh \
functional/block_cloning/block_cloning_copyfilerange_partial.ksh \
functional/block_cloning/block_cloning_disabled_copyfilerange.ksh \
functional/block_cloning/block_cloning_disabled_ficlone.ksh \
functional/block_cloning/block_cloning_disabled_ficlonerange.ksh \
functional/block_cloning/block_cloning_ficlone.ksh \
functional/block_cloning/block_cloning_ficlonerange.ksh \
functional/block_cloning/block_cloning_ficlonerange_partial.ksh \
functional/bootfs/bootfs_001_pos.ksh \ functional/bootfs/bootfs_001_pos.ksh \
functional/bootfs/bootfs_002_neg.ksh \ functional/bootfs/bootfs_002_neg.ksh \
functional/bootfs/bootfs_003_pos.ksh \ functional/bootfs/bootfs_003_pos.ksh \

View File

@ -0,0 +1,46 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or https://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2023, Klara Inc.
#
. $STF_SUITE/include/libtest.shlib
function have_same_content
{
typeset hash1=$(cat $1 | md5sum)
typeset hash2=$(cat $2 | md5sum)
log_must [ "$hash1" = "$hash2" ]
}
function unique_blocks
{
typeset zdbout=${TMPDIR:-$TEST_BASE_DIR}/zdbout.$$
zdb -vvvvv $1 -O $2 | \
awk '/ L0 / { print ++l " " $3 " " $7 }' > $zdbout.a
zdb -vvvvv $3 -O $4 | \
awk '/ L0 / { print ++l " " $3 " " $7 }' > $zdbout.b
echo $(sort $zdbout.a $zdbout.b | uniq -d | cut -f1 -d' ')
}

View File

@ -0,0 +1,60 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or https://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2023, Klara Inc.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/block_cloning/block_cloning.kshlib
verify_runnable "global"
if [[ $(linux_version) -lt $(linux_version "4.5") ]]; then
log_unsupported "copy_file_range not available before Linux 4.5"
fi
claim="The copy_file_range syscall can clone whole files."
log_assert $claim
function cleanup
{
datasetexists $TESTPOOL && destroy_pool $TESTPOOL
}
log_onexit cleanup
log_must zpool create -o feature@block_cloning=enabled $TESTPOOL $DISKS
log_must dd if=/dev/urandom of=/$TESTPOOL/file1 bs=128K count=4
log_must sync_pool $TESTPOOL
log_must clonefile -f /$TESTPOOL/file1 /$TESTPOOL/file2 0 0 524288
log_must sync_pool $TESTPOOL
log_must have_same_content /$TESTPOOL/file1 /$TESTPOOL/file2
typeset blocks=$(unique_blocks $TESTPOOL file1 $TESTPOOL file2)
log_must [ "$blocks" = "1 2 3 4" ]
log_pass $claim

View File

@ -0,0 +1,65 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or https://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2023, Klara Inc.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/block_cloning/block_cloning.kshlib
verify_runnable "global"
if [[ $(linux_version) -lt $(linux_version "5.3") ]]; then
log_unsupported "copy_file_range can't copy cross-filesystem before Linux 5.3"
fi
claim="The copy_file_range syscall can clone across datasets."
log_assert $claim
function cleanup
{
datasetexists $TESTPOOL && destroy_pool $TESTPOOL
}
log_onexit cleanup
log_must zpool create -o feature@block_cloning=enabled $TESTPOOL $DISKS
log_must zfs create $TESTPOOL/$TESTFS1
log_must zfs create $TESTPOOL/$TESTFS2
log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS1/file1 bs=128K count=4
log_must sync_pool $TESTPOOL
log_must \
clonefile -f /$TESTPOOL/$TESTFS1/file1 /$TESTPOOL/$TESTFS2/file2 0 0 524288
log_must sync_pool $TESTPOOL
log_must have_same_content /$TESTPOOL/$TESTFS1/file1 /$TESTPOOL/$TESTFS2/file2
typeset blocks=$(unique_blocks \
$TESTPOOL/$TESTFS1 file1 $TESTPOOL/$TESTFS2 file2)
log_must [ "$blocks" = "1 2 3 4" ]
log_pass $claim

View File

@ -0,0 +1,68 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or https://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2023, Klara Inc.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/block_cloning/block_cloning.kshlib
verify_runnable "global"
if [[ $(linux_version) -lt $(linux_version "4.5") ]]; then
log_unsupported "copy_file_range not available before Linux 4.5"
fi
claim="The copy_file_range syscall can clone parts of a file."
log_assert $claim
function cleanup
{
datasetexists $TESTPOOL && destroy_pool $TESTPOOL
}
log_onexit cleanup
log_must zpool create -o feature@block_cloning=enabled $TESTPOOL $DISKS
log_must dd if=/dev/urandom of=/$TESTPOOL/file1 bs=128K count=4
log_must sync_pool $TESTPOOL
log_must dd if=/$TESTPOOL/file1 of=/$TESTPOOL/file2 bs=128K count=4
log_must sync_pool $TESTPOOL
log_must have_same_content /$TESTPOOL/file1 /$TESTPOOL/file2
typeset blocks=$(unique_blocks $TESTPOOL file1 $TESTPOOL file2)
log_must [ "$blocks" = "" ]
log_must clonefile -f /$TESTPOOL/file1 /$TESTPOOL/file2 131072 131072 262144
log_must sync_pool $TESTPOOL
log_must have_same_content /$TESTPOOL/file1 /$TESTPOOL/file2
typeset blocks=$(unique_blocks $TESTPOOL file1 $TESTPOOL file2)
log_must [ "$blocks" = "2 3" ]
log_pass $claim

View File

@ -0,0 +1,60 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or https://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2023, Klara Inc.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/block_cloning/block_cloning.kshlib
verify_runnable "global"
if [[ $(linux_version) -lt $(linux_version "4.5") ]]; then
log_unsupported "copy_file_range not available before Linux 4.5"
fi
claim="The copy_file_range syscall copies files when block cloning is disabled."
log_assert $claim
function cleanup
{
datasetexists $TESTPOOL && destroy_pool $TESTPOOL
}
log_onexit cleanup
log_must zpool create -o feature@block_cloning=disabled $TESTPOOL $DISKS
log_must dd if=/dev/urandom of=/$TESTPOOL/file1 bs=128K count=4
log_must sync_pool $TESTPOOL
log_must clonefile -f /$TESTPOOL/file1 /$TESTPOOL/file2 0 0 524288
log_must sync_pool $TESTPOOL
log_must have_same_content /$TESTPOOL/file1 /$TESTPOOL/file2
typeset blocks=$(unique_blocks $TESTPOOL file1 $TESTPOOL file2)
log_must [ "$blocks" = "" ]
log_pass $claim

View File

@ -0,0 +1,50 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or https://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2023, Klara Inc.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/block_cloning/block_cloning.kshlib
verify_runnable "global"
claim="The FICLONE ioctl fails when block cloning is disabled."
log_assert $claim
function cleanup
{
datasetexists $TESTPOOL && destroy_pool $TESTPOOL
}
log_onexit cleanup
log_must zpool create -o feature@block_cloning=disabled $TESTPOOL $DISKS
log_must dd if=/dev/urandom of=/$TESTPOOL/file1 bs=128K count=4
log_must sync_pool $TESTPOOL
log_mustnot clonefile -c /$TESTPOOL/file1 /$TESTPOOL/file2
log_pass $claim

View File

@ -0,0 +1,50 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or https://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2023, Klara Inc.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/block_cloning/block_cloning.kshlib
verify_runnable "global"
claim="The FICLONERANGE ioctl fails when block cloning is disabled."
log_assert $claim
function cleanup
{
datasetexists $TESTPOOL && destroy_pool $TESTPOOL
}
log_onexit cleanup
log_must zpool create -o feature@block_cloning=disabled $TESTPOOL $DISKS
log_must dd if=/dev/urandom of=/$TESTPOOL/file1 bs=128K count=4
log_must sync_pool $TESTPOOL
log_mustnot clonefile -r /$TESTPOOL/file1 /$TESTPOOL/file2 0 0 524288
log_pass $claim

View File

@ -0,0 +1,56 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or https://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2023, Klara Inc.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/block_cloning/block_cloning.kshlib
verify_runnable "global"
claim="The FICLONE ioctl can clone files."
log_assert $claim
function cleanup
{
datasetexists $TESTPOOL && destroy_pool $TESTPOOL
}
log_onexit cleanup
log_must zpool create -o feature@block_cloning=enabled $TESTPOOL $DISKS
log_must dd if=/dev/urandom of=/$TESTPOOL/file1 bs=128K count=4
log_must sync_pool $TESTPOOL
log_must clonefile -c /$TESTPOOL/file1 /$TESTPOOL/file2
log_must sync_pool $TESTPOOL
log_must have_same_content /$TESTPOOL/file1 /$TESTPOOL/file2
typeset blocks=$(unique_blocks $TESTPOOL file1 $TESTPOOL file2)
log_must [ "$blocks" = "1 2 3 4" ]
log_pass $claim

View File

@ -0,0 +1,56 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or https://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2023, Klara Inc.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/block_cloning/block_cloning.kshlib
verify_runnable "global"
claim="The FICLONERANGE ioctl can clone whole files."
log_assert $claim
function cleanup
{
datasetexists $TESTPOOL && destroy_pool $TESTPOOL
}
log_onexit cleanup
log_must zpool create -o feature@block_cloning=enabled $TESTPOOL $DISKS
log_must dd if=/dev/urandom of=/$TESTPOOL/file1 bs=128K count=4
log_must sync_pool $TESTPOOL
log_must clonefile -r /$TESTPOOL/file1 /$TESTPOOL/file2 0 0 524288
log_must sync_pool $TESTPOOL
log_must have_same_content /$TESTPOOL/file1 /$TESTPOOL/file2
typeset blocks=$(unique_blocks $TESTPOOL file1 $TESTPOOL file2)
log_must [ "$blocks" = "1 2 3 4" ]
log_pass $claim

View File

@ -0,0 +1,64 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or https://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2023, Klara Inc.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/block_cloning/block_cloning.kshlib
verify_runnable "global"
claim="The FICLONERANGE ioctl can clone parts of a file."
log_assert $claim
function cleanup
{
datasetexists $TESTPOOL && destroy_pool $TESTPOOL
}
log_onexit cleanup
log_must zpool create -o feature@block_cloning=enabled $TESTPOOL $DISKS
log_must dd if=/dev/urandom of=/$TESTPOOL/file1 bs=128K count=4
log_must sync_pool $TESTPOOL
log_must dd if=/$TESTPOOL/file1 of=/$TESTPOOL/file2 bs=128K count=4
log_must sync_pool $TESTPOOL
log_must have_same_content /$TESTPOOL/file1 /$TESTPOOL/file2
typeset blocks=$(unique_blocks $TESTPOOL file1 $TESTPOOL file2)
log_must [ "$blocks" = "" ]
log_must clonefile -r /$TESTPOOL/file1 /$TESTPOOL/file2 131072 131072 262144
log_must sync_pool $TESTPOOL
log_must have_same_content /$TESTPOOL/file1 /$TESTPOOL/file2
typeset blocks=$(unique_blocks $TESTPOOL file1 $TESTPOOL file2)
log_must [ "$blocks" = "2 3" ]
log_pass $claim

View File

@ -0,0 +1,34 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or https://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2023, Klara Inc.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/block_cloning/block_cloning.kshlib
verify_runnable "global"
default_cleanup_noexit
log_pass

View File

@ -0,0 +1,36 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or https://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2023, Klara Inc.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/block_cloning/block_cloning.kshlib
if ! command -v clonefile > /dev/null ; then
log_unsupported "clonefile program required to test block cloning"
fi
verify_runnable "global"
log_pass