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:
parent
6b0a4be5fe
commit
48d0e9465d
|
@ -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']
|
||||||
|
|
|
@ -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],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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' ')
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue