mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
zfs: merge openzfs/zfs@3ee08abd2
Notable upstream pull request merges: #17000 -multiple cmd/zfs: support creating parents with canmount=no #17926b481a8bbbMake zpool status dedup table support raw bytes -p output #18238 -multiple Report space metrics per allocation class #182405dad9459dAdd --no-preserve-encryption flag #182571eace5906libzfs: use mount_setattr for selective remount including legacy mounts #182591e2c94a04More consistent use of TREE_* macros in AVL comparators #18262c58b8b7dcFix check for .cfi_negate_ra_state on aarch64 #18264f109c7bb9Add the --file-layout (-f) option to zdb(8) #18268304de7f19libzfs: handle EDOM error in zpool_create #18275753f1e1e2zstream: add a drop_record subcommand #182760f90a797dFix vdev_rebuild_range() tx commit #182771e1d64d66Fix log vdev removal issues #1827806b0abfe6Fix the send --exclude option to work with encryption #18281e73ada771libzpool: lift zfs_file ops out to separate source file #18284d97945776zstream: consolidate shared code #18285 -multiple Separate SIMD compile checks for userspace and kernel #18288c5905b2cbImplement lzc_send_progress #18289 -multiple L2ARC: Add depth cap and write budget fairness for persistent markers #18290d45c8d648FreeBSD: Improve dmesg kernel message prefix #18294b403040c4draid: fix data corruption after disk clear #18296 -multiple libzfs: mnttab cleanup #18300d35951b18zpool clear: remove undocumented rewind flags #18301ae7fcd5f9fix libzfs diff mem leak in an error path #1830365165df12zilstat: add man page #183147f65e04ablibzfs: scrub: only include start and end nv pairs if needed for scrub #18315 -multiple Sync ZVOLs block cloning conditions with file systems #18330f80338faczarcsummary: add man page #18337f259a47c7zpool-iostat.8: clarify first report shows per-second averages Obtained from: OpenZFS OpenZFS commit:3ee08abd2f
This commit is contained in:
commit
80aae8a3f8
180 files changed
+5804
-2661
No files matched your search
@@ -104,6 +104,7 @@ CFLAGS+= -I${SRCTOP}/sys
|
||||
CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/include
|
||||
CFLAGS+= -I${ZFSTOP}/module/icp/include
|
||||
CFLAGS+= -I${ZFSTOP}/lib/libzpool/include
|
||||
CFLAGS+= -include ${ZFSTOP}/include/sys/simd_config.h
|
||||
CFLAGS+= -include ${ZFSTOP}/include/os/freebsd/spl/sys/ccompile.h
|
||||
CFLAGS+= -DHAVE_ISSETUGID
|
||||
CFLAGS+= -include ${SRCTOP}/sys/modules/zfs/zfs_config.h
|
||||
|
||||
@@ -102,6 +102,7 @@ CFLAGS+= -I${SRCTOP}/sys
|
||||
CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/include
|
||||
CFLAGS+= -I${ZFSTOP}/module/icp/include
|
||||
CFLAGS+= -I${ZFSTOP}/lib/libzpool/include
|
||||
CFLAGS+= -include ${ZFSTOP}/include/sys/simd_config.h
|
||||
CFLAGS+= -include ${ZFSTOP}/include/os/freebsd/spl/sys/ccompile.h
|
||||
CFLAGS+= -DHAVE_ISSETUGID -UHAVE_AVX -DRESCUE
|
||||
CFLAGS+= -include ${SRCTOP}/sys/modules/zfs/zfs_config.h
|
||||
|
||||
@@ -42,7 +42,7 @@ SRCS += \
|
||||
tunables.c \
|
||||
os/freebsd/getexecname.c \
|
||||
os/freebsd/gethostid.c \
|
||||
os/freebsd/getmntany.c \
|
||||
os/freebsd/getextmntent.c \
|
||||
os/freebsd/mnttab.c
|
||||
.endif
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ CFLAGS+= -I${ZFSTOP}/lib/libzpool/include
|
||||
CFLAGS+= -I${ZFSTOP}/include/os/freebsd/zfs
|
||||
CFLAGS+= -I${SRCTOP}/sys
|
||||
CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/include
|
||||
CFLAGS+= -include ${ZFSTOP}/include/sys/simd_config.h
|
||||
CFLAGS+= -include ${ZFSTOP}/include/os/freebsd/spl/sys/ccompile.h
|
||||
CFLAGS+= -I${ZFSTOP}/lib/libzutil
|
||||
CFLAGS+= -DHAVE_ISSETUGID -DIN_BASE
|
||||
|
||||
@@ -35,6 +35,7 @@ USER_C = \
|
||||
libzfs_diff.c \
|
||||
libzfs_import.c \
|
||||
libzfs_iter.c \
|
||||
libzfs_mnttab.c \
|
||||
libzfs_mount.c \
|
||||
libzfs_pool.c \
|
||||
libzfs_sendrecv.c \
|
||||
@@ -94,6 +95,7 @@ CFLAGS+= -I${SRCTOP}/sys/contrib/ck/include
|
||||
CFLAGS+= -I${SRCTOP}/sys
|
||||
CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/include
|
||||
CFLAGS+= -I${ZFSTOP}/module/icp/include
|
||||
CFLAGS+= -include ${ZFSTOP}/include/sys/simd_config.h
|
||||
CFLAGS+= -include ${ZFSTOP}/include/os/freebsd/spl/sys/ccompile.h
|
||||
CFLAGS+= -DHAVE_ISSETUGID
|
||||
CFLAGS+= -DHAVE_EXECVPE
|
||||
|
||||
@@ -176,6 +176,7 @@ KERNEL_C = \
|
||||
zfs_chksum.c \
|
||||
zfs_crrd.c \
|
||||
zfs_debug_common.c \
|
||||
zfs_file_os.c \
|
||||
zfs_fm.c \
|
||||
zfs_fuid.c \
|
||||
zfs_impl.c \
|
||||
@@ -265,6 +266,7 @@ CFLAGS+= \
|
||||
-I${SRCTOP}/cddl/compat/opensolaris/include \
|
||||
-I${ZFSTOP}/module/icp/include \
|
||||
-I${SRCTOP}/compat/linuxkpi/common/include/linux \
|
||||
-include ${ZFSTOP}/include/sys/simd_config.h \
|
||||
-include ${ZFSTOP}/include/os/freebsd/spl/sys/ccompile.h \
|
||||
-DHAVE_ISSETUGID \
|
||||
-include ${SRCTOP}/sys/modules/zfs/zfs_config.h \
|
||||
|
||||
@@ -9,10 +9,12 @@ INCS= zstream.h
|
||||
SRCS= \
|
||||
zstream.c \
|
||||
zstream_decompress.c \
|
||||
zstream_drop_record.c \
|
||||
zstream_dump.c \
|
||||
zstream_recompress.c \
|
||||
zstream_redup.c \
|
||||
zstream_token.c
|
||||
zstream_token.c \
|
||||
zstream_util.c
|
||||
|
||||
SYMLINKS= zstream ${BINDIR}/zstreamdump
|
||||
|
||||
@@ -27,6 +29,7 @@ CFLAGS+= \
|
||||
-I${SRCTOP}/sys \
|
||||
-I${SRCTOP}/cddl/compat/opensolaris/include \
|
||||
-I${ZFSTOP}/module/icp/include \
|
||||
-include ${ZFSTOP}/include/sys/simd_config.h \
|
||||
-include ${ZFSTOP}/include/os/freebsd/spl/sys/ccompile.h \
|
||||
-DHAVE_ISSETUGID \
|
||||
-include ${SRCTOP}/sys/modules/zfs/zfs_config.h
|
||||
|
||||
@@ -16,6 +16,7 @@ CFLAGS+= \
|
||||
-I${ZFSTOP}/lib/libzpool/include \
|
||||
-I${SRCTOP}/cddl/compat/opensolaris/include \
|
||||
-I${ZFSTOP}/module/icp/include \
|
||||
-include ${ZFSTOP}/include/sys/simd_config.h \
|
||||
-include ${ZFSTOP}/include/os/freebsd/spl/sys/ccompile.h \
|
||||
-DHAVE_ISSETUGID \
|
||||
-include ${SRCTOP}/sys/modules/zfs/zfs_config.h
|
||||
|
||||
@@ -18,6 +18,7 @@ CFLAGS+= \
|
||||
-I${ZFSTOP}/lib/libspl/include/os/freebsd/spl \
|
||||
-I${ZFSTOP}/lib/libzpool/include \
|
||||
-I${SRCTOP}/sys \
|
||||
-include ${ZFSTOP}/include/sys/simd_config.h \
|
||||
-include ${ZFSTOP}/include/os/freebsd/spl/sys/ccompile.h \
|
||||
-DHAVE_ISSETUGID
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ CFLAGS+= -I${ZFSTOP}/lib/libzpool/include
|
||||
CFLAGS+= -I${SRCTOP}/sys
|
||||
CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/include
|
||||
CFLAGS+= -I${ZFSTOP}/module/icp/include
|
||||
CFLAGS+= -include ${ZFSTOP}/include/sys/simd_config.h
|
||||
CFLAGS+= -include ${ZFSTOP}/include/os/freebsd/spl/sys/ccompile.h
|
||||
CFLAGS+= -DHAVE_ISSETUGID
|
||||
CFLAGS+= -include ${SRCTOP}/sys/modules/zfs/zfs_config.h
|
||||
|
||||
@@ -43,7 +43,9 @@ ZFS_EARLY= -I${SAZFSSRC}/spl \
|
||||
# from FreeBSD.
|
||||
#
|
||||
.for i in ${ZFS_SRC} ${ZSTD_SRC}
|
||||
CFLAGS.$i+= -include ${ZFSOSINC}/spl/sys/ccompile.h -Wformat -Wall -I${ZFSTOP}/include \
|
||||
CFLAGS.$i+= -include ${ZFSTOP}/include/sys/simd_config.h \
|
||||
-include ${ZFSOSINC}/spl/sys/ccompile.h \
|
||||
-Wformat -Wall -I${ZFSTOP}/include \
|
||||
-DNEED_SOLARIS_BOOLEAN
|
||||
.endfor
|
||||
|
||||
|
||||
@@ -205,6 +205,7 @@ CDDL_C= ${CC} -c ${CDDL_CFLAGS} ${WERROR} ${.IMPSRC}
|
||||
|
||||
# Special flags for managing the compat compiles for ZFS
|
||||
ZFS_CFLAGS+= -I$S/contrib/openzfs/module/icp/include \
|
||||
-include $S/contrib/openzfs/include/sys/simd_config.h \
|
||||
${CDDL_CFLAGS} -DBUILDING_ZFS -DHAVE_UIO_ZEROCOPY \
|
||||
-DWITH_NETDUMP -D__KERNEL__ -D_SYS_CONDVAR_H_ -DSMP
|
||||
|
||||
|
||||
@@ -30,6 +30,42 @@ We have a [Code of Conduct](./CODE_OF_CONDUCT.md).
|
||||
OpenZFS is released under a CDDL license.
|
||||
For more details see the NOTICE, LICENSE and COPYRIGHT files; `UCRL-CODE-235197`
|
||||
|
||||
# Supported Kernels
|
||||
* The `META` file contains the officially recognized supported Linux kernel versions.
|
||||
* Supported FreeBSD versions are any supported branches and releases starting from 13.0-RELEASE.
|
||||
# Supported Kernels and Distributions
|
||||
|
||||
## Linux
|
||||
|
||||
Given the wide variety of Linux environments, we prioritize development and testing on stable, supported kernels and distributions.
|
||||
|
||||
### Kernel ([kernel.org](https://kernel.org))
|
||||
|
||||
All **longterm** kernels from [kernel.org](https://kernel.org) are supported. **stable** kernels are usually supported in the next OpenZFS release.
|
||||
|
||||
**Supported longterm kernels**: **6.18**, **6.12**, **6.6**, **6.1**, **5.15**, **5.10**.
|
||||
|
||||
### Red Hat Enterprise Linux (RHEL)
|
||||
|
||||
All RHEL (and compatible systems: AlmaLinux OS, Rocky Linux, etc) on the **full** or **maintenance** support tracks are supported.
|
||||
|
||||
**Supported RHEL releases**: **8.10**, **9.7**, **10.1**.
|
||||
|
||||
### Ubuntu
|
||||
|
||||
All Ubuntu **LTS** releases are supported.
|
||||
|
||||
**Supported Ubuntu releases**: **24.04 “Noble”**, **22.04 “Jammy”**.
|
||||
|
||||
### Debian
|
||||
|
||||
All Debian **stable** and **LTS** releases are supported.
|
||||
|
||||
**Supported Debian releases**: **13 “Trixie”**, **12 “Bookworm”**, **11 “Bullseye”**.
|
||||
|
||||
### Other Distributions
|
||||
|
||||
Generally, if a distribution is following an LTS kernel, it should work well with OpenZFS.
|
||||
|
||||
## FreeBSD
|
||||
|
||||
All FreeBSD releases receiving [security support](https://www.freebsd.org/security/#sup) are supported by OpenZFS.
|
||||
|
||||
**Supported FreeBSD releases**: **15.0**, **14.4**, **13.5**.
|
||||
@@ -87,6 +87,8 @@
|
||||
#include <sys/brt.h>
|
||||
#include <sys/brt_impl.h>
|
||||
#include <zfs_comutil.h>
|
||||
#include <sys/vdev_raidz.h>
|
||||
#include <sys/vdev_raidz_impl.h>
|
||||
#include <sys/zstd/zstd.h>
|
||||
#include <sys/backtrace.h>
|
||||
|
||||
@@ -743,11 +745,13 @@ usage(void)
|
||||
"\t%s -r [-K <key>] -O <dataset> <object-id> <destination>\n"
|
||||
"\t%s -R [-A] [-e [-V] [-p <path> ...]] [-U <cache>]\n"
|
||||
"\t\t<poolname> <vdev>:<offset>:<size>[:<flags>]\n"
|
||||
"\t%s -f [-H] [-e [-V] [-p <path> ...]] [-U <cache>]\n"
|
||||
"\t\t[<poolname>[/<dataset | objset id>] [<object | range> ...]]\n"
|
||||
"\t%s -E [-A] word0:word1:...:word15\n"
|
||||
"\t%s -S [-AP] [-e [-V] [-p <path> ...]] [-U <cache>] "
|
||||
"<poolname>\n\n",
|
||||
cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname,
|
||||
cmdname, cmdname, cmdname, cmdname, cmdname, cmdname);
|
||||
cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname);
|
||||
|
||||
(void) fprintf(stderr, " Dataset name must include at least one "
|
||||
"separator character '/' or '@'\n");
|
||||
@@ -786,6 +790,8 @@ usage(void)
|
||||
"dataset(s)\n");
|
||||
(void) fprintf(stderr, " -D --dedup-stats "
|
||||
"dedup statistics\n");
|
||||
(void) fprintf(stderr, " -f --file-layout "
|
||||
"display a file's layout across raidz disks\n");
|
||||
(void) fprintf(stderr, " -E --embedded-block-pointer=INTEGER\n"
|
||||
" decode and display block "
|
||||
"from an embedded block pointer\n");
|
||||
@@ -818,6 +824,7 @@ usage(void)
|
||||
(void) fprintf(stderr, " -y --livelist "
|
||||
"perform livelist and metaslab validation on any livelists being "
|
||||
"deleted\n\n");
|
||||
|
||||
(void) fprintf(stderr, " Below options are intended for use "
|
||||
"with other options:\n");
|
||||
(void) fprintf(stderr, " -A --ignore-assertions "
|
||||
@@ -830,6 +837,8 @@ usage(void)
|
||||
"groups\n");
|
||||
(void) fprintf(stderr, " -G --dump-debug-msg "
|
||||
"dump zfs_dbgmsg buffer before exiting\n");
|
||||
(void) fprintf(stderr, " -H --scripting-mode "
|
||||
"dump output in a format that is scripting friendly\n");
|
||||
(void) fprintf(stderr, " -I --inflight=INTEGER "
|
||||
"specify the maximum number of checksumming I/Os "
|
||||
"[default is 200]\n");
|
||||
@@ -2135,7 +2144,8 @@ dump_ddt_object(ddt_t *ddt, ddt_type_t type, ddt_class_t class)
|
||||
|
||||
(void) printf("%s: object=%llu\n", name,
|
||||
(u_longlong_t)ddt->ddt_object[type][class]);
|
||||
zpool_dump_ddt(NULL, &ddt->ddt_histogram[type][class]);
|
||||
zpool_dump_ddt(NULL, &ddt->ddt_histogram[type][class],
|
||||
dump_opt['P'] > 0);
|
||||
|
||||
if (dump_opt['D'] < 4)
|
||||
return;
|
||||
@@ -2212,7 +2222,7 @@ dump_all_ddts(spa_t *spa)
|
||||
if (dump_opt['D'] > 1) {
|
||||
(void) printf("DDT histogram (aggregated over all DDTs):\n");
|
||||
ddt_get_dedup_histogram(spa, &ddh_total);
|
||||
zpool_dump_ddt(&dds_total, &ddh_total);
|
||||
zpool_dump_ddt(&dds_total, &ddh_total, dump_opt['P'] > 0);
|
||||
}
|
||||
|
||||
dump_dedup_ratio(&dds_total);
|
||||
@@ -2645,6 +2655,7 @@ snprintf_blkptr_compact(char *blkbuf, size_t buflen, const blkptr_t *bp,
|
||||
if (bp_freed)
|
||||
(void) snprintf(blkbuf + strlen(blkbuf),
|
||||
buflen - strlen(blkbuf), " %s", "FREE");
|
||||
|
||||
(void) snprintf(blkbuf + strlen(blkbuf),
|
||||
buflen - strlen(blkbuf),
|
||||
" cksum=%016llx:%016llx:%016llx:%016llx",
|
||||
@@ -2655,6 +2666,74 @@ snprintf_blkptr_compact(char *blkbuf, size_t buflen, const blkptr_t *bp,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
inverse_text(boolean_t on)
|
||||
{
|
||||
if (isatty(STDOUT_FILENO)) {
|
||||
if (on)
|
||||
fputs("\x1b[7m", stdout);
|
||||
else
|
||||
fputs("\x1b[m", stdout);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_file_layout_line(int line, int first_disk, int last_disk, int ashift,
|
||||
raidz_row_t *rr)
|
||||
{
|
||||
if (first_disk != 0) {
|
||||
/* Account for empty columns */
|
||||
for (int c = 0; c < first_disk; c++) {
|
||||
(void) printf("%s%s", (c == 0) ? " │ " : " ",
|
||||
line == 0 ? "` ` ` ` ` " : " ` ` ` ` `");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we need to account for out of order disks in raidz1.
|
||||
* Here flip means the disks in first two column were exchanged.
|
||||
*/
|
||||
boolean_t flip = rr->rr_firstdatacol == 1 &&
|
||||
(rr->rr_offset & (1ULL << 20));
|
||||
|
||||
for (int c = 0; c < rr->rr_cols; c++) {
|
||||
raidz_col_t *rc = &rr->rr_col[c];
|
||||
char colname[8];
|
||||
boolean_t pcol = flip ? (c == 1) : (c < rr->rr_firstdatacol);
|
||||
|
||||
if (rc->rc_devidx > last_disk)
|
||||
continue;
|
||||
|
||||
(void) snprintf(colname, sizeof (colname), "%c%d",
|
||||
pcol ? 'P' : 'D', (flip && c < 2) ? 0 :
|
||||
pcol ? c : c - rr->rr_firstdatacol);
|
||||
|
||||
(void) printf("%s", (rc->rc_devidx == 0) ? " │ " : " ");
|
||||
if (pcol)
|
||||
inverse_text(B_TRUE);
|
||||
if (line == 0) {
|
||||
(void) printf("%3s %5d", colname,
|
||||
(int)(rc->rc_size >> ashift));
|
||||
} else {
|
||||
(void) printf("%10llx",
|
||||
(u_longlong_t)((rc->rc_offset +
|
||||
VDEV_LABEL_START_SIZE) >> ashift));
|
||||
}
|
||||
if (pcol)
|
||||
inverse_text(B_FALSE);
|
||||
if (rc->rc_devidx == last_disk) {
|
||||
/* empty columns */
|
||||
for (int c = last_disk + 1; c < rr->rr_cols; c++) {
|
||||
(void) printf(" %s",
|
||||
line == 0 ? "` ` ` ` ` " : " ` ` ` ` `");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
(void) printf(" │\n");
|
||||
}
|
||||
|
||||
|
||||
static u_longlong_t
|
||||
print_indirect(spa_t *spa, blkptr_t *bp, const zbookmark_phys_t *zb,
|
||||
const dnode_phys_t *dnp)
|
||||
@@ -2701,17 +2780,133 @@ print_indirect(spa_t *spa, blkptr_t *bp, const zbookmark_phys_t *zb,
|
||||
return (offset);
|
||||
}
|
||||
|
||||
static void
|
||||
print_file_layout_raidz(vdev_t *vd, blkptr_t *bp, uint64_t file_offset,
|
||||
boolean_t last)
|
||||
{
|
||||
/*
|
||||
* RAIDZ file data layout
|
||||
*
|
||||
* Use vdev_raidz_map_alloc() to get the actual layout
|
||||
*/
|
||||
const dva_t *dva = bp->blk_dva;
|
||||
zio_t zio = {0};
|
||||
zio.io_size = P2ROUNDUP_TYPED(BP_GET_PSIZE(bp),
|
||||
1ULL << vd->vdev_ashift, uint64_t);
|
||||
zio.io_offset = DVA_GET_OFFSET(&dva[0]);
|
||||
zio.io_type = ZIO_TYPE_READ;
|
||||
zio.io_abd = abd_alloc_for_io(zio.io_size, B_FALSE);
|
||||
|
||||
vdev_raidz_t *vdrz = vd->vdev_tsd;
|
||||
raidz_map_t *rm = vdev_raidz_map_alloc(&zio, vd->vdev_ashift,
|
||||
vd->vdev_children, vdrz->vd_nparity);
|
||||
raidz_row_t *rr = rm->rm_row[0];
|
||||
|
||||
/*
|
||||
* Account for out of order disks in raidz1.
|
||||
* For now just reverse them back and adjust for it later.
|
||||
*/
|
||||
if (rr->rr_firstdatacol == 1 && (zio.io_offset & (1ULL << 20))) {
|
||||
uint64_t devidx = rr->rr_col[0].rc_devidx;
|
||||
rr->rr_col[0].rc_devidx = rr->rr_col[1].rc_devidx;
|
||||
rr->rr_col[1].rc_devidx = devidx;
|
||||
}
|
||||
|
||||
if (!dump_opt['H']) {
|
||||
int last_disk = vd->vdev_children - 1;
|
||||
int first_disk = rr->rr_col[0].rc_devidx;
|
||||
|
||||
(void) printf("%12llx", (u_longlong_t)file_offset);
|
||||
print_file_layout_line(0, first_disk, last_disk,
|
||||
vd->vdev_ashift, rr);
|
||||
(void) printf("%*c", 12, ' ');
|
||||
print_file_layout_line(1, first_disk, last_disk,
|
||||
vd->vdev_ashift, rr);
|
||||
/* Check for split row */
|
||||
if (first_disk != 0) {
|
||||
(void) printf("%*c", 12, ' ');
|
||||
print_file_layout_line(0, 0, first_disk - 1,
|
||||
vd->vdev_ashift, rr);
|
||||
(void) printf("%*c", 12, ' ');
|
||||
print_file_layout_line(1, 0, first_disk - 1,
|
||||
vd->vdev_ashift, rr);
|
||||
}
|
||||
/* seperate rows with a line */
|
||||
(void) printf("%*c", 12, ' ');
|
||||
for (int c = 0; c < vd->vdev_children; c++) {
|
||||
(void) printf("%s%10s", (c == 0) ?
|
||||
(last ? " └─" : " ├─") : "──",
|
||||
"──────────");
|
||||
}
|
||||
(void) printf("─%s\n", last ? "┘" : "┤");
|
||||
} else {
|
||||
static uint64_t next_offset = 0;
|
||||
|
||||
if (next_offset != file_offset) {
|
||||
(void) printf("skip hole\t-\t%llx\n",
|
||||
(u_longlong_t)((file_offset - next_offset) >>
|
||||
vd->vdev_ashift));
|
||||
}
|
||||
next_offset = file_offset + BP_GET_LSIZE(bp);
|
||||
|
||||
for (int c = 0; c < rr->rr_cols; c++) {
|
||||
raidz_col_t *rc = &rr->rr_col[c];
|
||||
char *path = vd->vdev_child[rc->rc_devidx]->vdev_path;
|
||||
// c < rr->rr_firstdatacol
|
||||
if (rc->rc_size == 0)
|
||||
continue;
|
||||
(void) printf("%s\t%llu\t%d\n",
|
||||
zfs_basename(path),
|
||||
(u_longlong_t)(rc->rc_offset +
|
||||
VDEV_LABEL_START_SIZE)/512,
|
||||
(int)rc->rc_size/512);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_file_layout(spa_t *spa, blkptr_t *bp, const zbookmark_phys_t *zb,
|
||||
const dnode_phys_t *dnp)
|
||||
{
|
||||
if (!BP_IS_EMBEDDED(bp)) {
|
||||
ASSERT3U(BP_GET_TYPE(bp), ==, dnp->dn_type);
|
||||
ASSERT3U(BP_GET_LEVEL(bp), ==, zb->zb_level);
|
||||
}
|
||||
ASSERT(zb->zb_level >= 0);
|
||||
|
||||
if (BP_IS_HOLE(bp))
|
||||
return;
|
||||
|
||||
if (BP_IS_EMBEDDED(bp))
|
||||
return;
|
||||
|
||||
const dva_t *dva = bp->blk_dva;
|
||||
vdev_t *vd = spa->spa_root_vdev->vdev_child[DVA_GET_VDEV(&dva[0])];
|
||||
uint64_t file_offset = blkid2offset(dnp, bp, zb);
|
||||
|
||||
if (strcmp("raidz", vd->vdev_ops->vdev_op_type) == 0) {
|
||||
boolean_t last = (file_offset + BP_GET_LSIZE(bp)) >=
|
||||
(dnp->dn_used & ~0x03ffULL);
|
||||
print_file_layout_raidz(vd, bp, file_offset, last);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
visit_indirect(spa_t *spa, const dnode_phys_t *dnp,
|
||||
blkptr_t *bp, const zbookmark_phys_t *zb)
|
||||
{
|
||||
u_longlong_t offset;
|
||||
u_longlong_t offset = 0;
|
||||
int err = 0;
|
||||
|
||||
if (BP_GET_BIRTH(bp) == 0)
|
||||
return (0);
|
||||
|
||||
offset = print_indirect(spa, bp, zb, dnp);
|
||||
if (dump_opt['f']) {
|
||||
if (BP_GET_LEVEL(bp) == 0)
|
||||
print_file_layout(spa, bp, zb, dnp);
|
||||
} else {
|
||||
print_indirect(spa, bp, zb, dnp);
|
||||
}
|
||||
|
||||
if (BP_GET_LEVEL(bp) > 0 && !BP_IS_HOLE(bp)) {
|
||||
arc_flags_t flags = ARC_FLAG_WAIT;
|
||||
@@ -2763,6 +2958,63 @@ dump_indirect(dnode_t *dn)
|
||||
zbookmark_phys_t czb;
|
||||
|
||||
(void) printf("Indirect blocks:\n");
|
||||
SET_BOOKMARK(&czb, dmu_objset_id(dn->dn_objset),
|
||||
dn->dn_object, dnp->dn_nlevels - 1, 0);
|
||||
for (int j = 0; j < dnp->dn_nblkptr; j++) {
|
||||
czb.zb_blkid = j;
|
||||
(void) visit_indirect(dmu_objset_spa(dn->dn_objset), dnp,
|
||||
&dnp->dn_blkptr[j], &czb);
|
||||
}
|
||||
|
||||
(void) printf("\n");
|
||||
}
|
||||
|
||||
static int
|
||||
dump_indirect_layout(dnode_t *dn)
|
||||
{
|
||||
dnode_phys_t *dnp = dn->dn_phys;
|
||||
zbookmark_phys_t czb;
|
||||
|
||||
spa_t *spa = dmu_objset_spa(dn->dn_objset);
|
||||
int ashift = spa->spa_root_vdev->vdev_child[0]->vdev_ashift;
|
||||
int children = spa->spa_root_vdev->vdev_child[0]->vdev_children;
|
||||
|
||||
if (strcmp(spa->spa_root_vdev->vdev_child[0]->vdev_ops->vdev_op_type,
|
||||
"raidz") != 0) {
|
||||
(void) fprintf(stderr, "file layout only supports raidz\n");
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start layout with a header
|
||||
*/
|
||||
if (dump_opt['H']) {
|
||||
(void) printf("DISK\t\tLBA\t\tCOUNT\n");
|
||||
} else {
|
||||
char diskhdr[16];
|
||||
|
||||
(void) printf("%12s: %d\n", "block size", dn->dn_datablksz);
|
||||
(void) printf("%12s: %s%d\n", "vdev_type",
|
||||
spa->spa_root_vdev->vdev_child[0]->vdev_ops->vdev_op_type,
|
||||
(int)vdev_get_nparity(spa->spa_root_vdev->vdev_child[0]));
|
||||
(void) printf("%12s: %d\n", "sector size", 1 << ashift);
|
||||
(void) printf("%12s: %d\n\n", "child disks", children);
|
||||
|
||||
(void) printf("%*c ", 12, ' ');
|
||||
|
||||
for (int c = 0; c < children; c++) {
|
||||
(void) snprintf(diskhdr, sizeof (diskhdr),
|
||||
"V%d:DISK-%d", 0, c);
|
||||
(void) printf(" %10s ", diskhdr);
|
||||
}
|
||||
(void) printf("\n");
|
||||
|
||||
(void) printf("%12s", "FILE OFFSET");
|
||||
for (int c = 0; c < children; c++)
|
||||
(void) printf("%s%10s", (c == 0) ? " ┌─" : "──",
|
||||
"──────────");
|
||||
(void) printf("─┐\n");
|
||||
}
|
||||
|
||||
SET_BOOKMARK(&czb, dmu_objset_id(dn->dn_objset),
|
||||
dn->dn_object, dnp->dn_nlevels - 1, 0);
|
||||
@@ -2773,6 +3025,7 @@ dump_indirect(dnode_t *dn)
|
||||
}
|
||||
|
||||
(void) printf("\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3033,7 +3286,6 @@ dump_full_bpobj(bpobj_t *bpo, const char *name, int indent)
|
||||
if (dump_opt['d'] < 5)
|
||||
return;
|
||||
|
||||
|
||||
if (indent == 0) {
|
||||
(void) bpobj_iterate_nofree(bpo, dump_bpobj_cb, NULL, NULL);
|
||||
(void) printf("\n");
|
||||
@@ -4161,7 +4413,6 @@ dump_object(objset_t *os, uint64_t object, int verbosity,
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (db != NULL)
|
||||
dmu_buf_rele(db, FTAG);
|
||||
@@ -4169,6 +4420,60 @@ out:
|
||||
dnode_rele(dn, FTAG);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_object_file_layout(objset_t *os, uint64_t object, int verbosity)
|
||||
{
|
||||
(void) verbosity;
|
||||
dmu_buf_t *db = NULL;
|
||||
dmu_object_info_t doi;
|
||||
dnode_t *dn;
|
||||
boolean_t dnode_held = B_FALSE;
|
||||
int error;
|
||||
|
||||
char osname[ZFS_MAX_DATASET_NAME_LEN];
|
||||
dmu_objset_name(os, osname);
|
||||
(void) printf("%12s: '%s'\n", "objset", osname);
|
||||
(void) printf("%12s: %d\n", "object", (int)object);
|
||||
|
||||
if (object == 0) {
|
||||
dn = DMU_META_DNODE(os);
|
||||
dmu_object_info_from_dnode(dn, &doi);
|
||||
} else {
|
||||
/*
|
||||
* Encrypted datasets will have sensitive bonus buffers
|
||||
* encrypted. Therefore we cannot hold the bonus buffer and
|
||||
* must hold the dnode itself instead.
|
||||
*/
|
||||
error = dmu_object_info(os, object, &doi);
|
||||
if (error)
|
||||
fatal("dmu_object_info() failed, errno %u", error);
|
||||
|
||||
if (!key_loaded && os->os_encrypted &&
|
||||
DMU_OT_IS_ENCRYPTED(doi.doi_bonus_type)) {
|
||||
error = dnode_hold(os, object, FTAG, &dn);
|
||||
if (error)
|
||||
fatal("dnode_hold() failed, errno %u", error);
|
||||
dnode_held = B_TRUE;
|
||||
} else {
|
||||
error = dmu_bonus_hold(os, object, FTAG, &db);
|
||||
if (error)
|
||||
fatal("dmu_bonus_hold(%llu) failed, errno %u",
|
||||
object, error);
|
||||
dn = DB_DNODE((dmu_buf_impl_t *)db);
|
||||
}
|
||||
}
|
||||
|
||||
error = dump_indirect_layout(dn);
|
||||
|
||||
if (db != NULL)
|
||||
dmu_buf_rele(db, FTAG);
|
||||
if (dnode_held)
|
||||
dnode_rele(dn, FTAG);
|
||||
|
||||
if (error)
|
||||
zdb_exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
count_dir_mos_objects(dsl_dir_t *dd)
|
||||
{
|
||||
@@ -4357,7 +4662,7 @@ dump_objset(objset_t *os)
|
||||
|
||||
zdb_nicenum(refdbytes, numbuf, sizeof (numbuf));
|
||||
|
||||
if (verbosity >= 4) {
|
||||
if (verbosity >= 4 || dump_opt['d']) {
|
||||
(void) snprintf(blkbuf, sizeof (blkbuf), ", rootbp ");
|
||||
(void) snprintf_blkptr(blkbuf + strlen(blkbuf),
|
||||
sizeof (blkbuf) - strlen(blkbuf), os->os_rootbp);
|
||||
@@ -4380,21 +4685,21 @@ dump_objset(objset_t *os)
|
||||
flags = zopt_object_ranges[i].zor_flags;
|
||||
|
||||
object = obj_start;
|
||||
if (object == 0 || obj_start == obj_end)
|
||||
dump_object(os, object, verbosity, &print_header, NULL,
|
||||
flags);
|
||||
else
|
||||
if (object == 0 || obj_start == obj_end) {
|
||||
dump_object(os, object, verbosity,
|
||||
&print_header, NULL, flags);
|
||||
} else {
|
||||
object--;
|
||||
}
|
||||
|
||||
while ((dmu_object_next(os, &object, B_FALSE, 0) == 0) &&
|
||||
object <= obj_end) {
|
||||
dump_object(os, object, verbosity, &print_header, NULL,
|
||||
flags);
|
||||
dump_object(os, object, verbosity,
|
||||
&print_header, NULL, flags);
|
||||
}
|
||||
}
|
||||
|
||||
if (zopt_object_args > 0) {
|
||||
(void) printf("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4477,6 +4782,32 @@ dump_objset(objset_t *os)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dump_file_data_layout(objset_t *os)
|
||||
{
|
||||
uint64_t object;
|
||||
int verbosity = dump_opt['d'];
|
||||
unsigned i;
|
||||
uint64_t obj_start;
|
||||
uint64_t obj_end;
|
||||
|
||||
for (i = 0; i < zopt_object_args; i++) {
|
||||
obj_start = zopt_object_ranges[i].zor_obj_start;
|
||||
obj_end = zopt_object_ranges[i].zor_obj_end;
|
||||
|
||||
object = obj_start;
|
||||
if (object == 0 || obj_start == obj_end)
|
||||
dump_object_file_layout(os, object, verbosity);
|
||||
else
|
||||
object--;
|
||||
|
||||
while ((dmu_object_next(os, &object, B_FALSE, 0) == 0) &&
|
||||
object <= obj_end) {
|
||||
dump_object_file_layout(os, object, verbosity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dump_uberblock(uberblock_t *ub, const char *header, const char *footer)
|
||||
{
|
||||
@@ -5708,7 +6039,6 @@ dump_one_objset(const char *dsname, void *arg)
|
||||
!dmu_objset_is_snapshot(os)) {
|
||||
global_feature_count[SPA_FEATURE_LIVELIST]++;
|
||||
}
|
||||
|
||||
dump_objset(os);
|
||||
close_objset(os, FTAG);
|
||||
fuid_table_destroy();
|
||||
@@ -7789,7 +8119,7 @@ dump_simulated_ddt(spa_t *spa)
|
||||
|
||||
(void) printf("Simulated DDT histogram:\n");
|
||||
|
||||
zpool_dump_ddt(&dds_total, &ddh_total);
|
||||
zpool_dump_ddt(&dds_total, &ddh_total, dump_opt['P'] > 0);
|
||||
|
||||
dump_dedup_ratio(&dds_total);
|
||||
}
|
||||
@@ -9528,9 +9858,11 @@ main(int argc, char **argv)
|
||||
{"dedup-stats", no_argument, NULL, 'D'},
|
||||
{"exported", no_argument, NULL, 'e'},
|
||||
{"embedded-block-pointer", no_argument, NULL, 'E'},
|
||||
{"file-layout", no_argument, NULL, 'f'},
|
||||
{"automatic-rewind", no_argument, NULL, 'F'},
|
||||
{"dump-debug-msg", no_argument, NULL, 'G'},
|
||||
{"history", no_argument, NULL, 'h'},
|
||||
{"scripting-mode", no_argument, NULL, 'H'},
|
||||
{"intent-logs", no_argument, NULL, 'i'},
|
||||
{"inflight", required_argument, NULL, 'I'},
|
||||
{"checkpointed-state", no_argument, NULL, 'k'},
|
||||
@@ -9570,7 +9902,7 @@ main(int argc, char **argv)
|
||||
};
|
||||
|
||||
while ((c = getopt_long(argc, argv,
|
||||
"AbBcCdDeEFGhiI:kK:lLmMNo:Op:PqrRsSt:TuU:vVx:XYyZ",
|
||||
"AbBcCdDeEfFGhHiI:kK:lLmMNo:Op:PqrRsSt:TuU:vVx:XYyZ",
|
||||
long_options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'b':
|
||||
@@ -9580,6 +9912,7 @@ main(int argc, char **argv)
|
||||
case 'd':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'f':
|
||||
case 'G':
|
||||
case 'h':
|
||||
case 'i':
|
||||
@@ -9603,6 +9936,7 @@ main(int argc, char **argv)
|
||||
case 'A':
|
||||
case 'e':
|
||||
case 'F':
|
||||
case 'H':
|
||||
case 'k':
|
||||
case 'L':
|
||||
case 'P':
|
||||
@@ -9742,6 +10076,10 @@ main(int argc, char **argv)
|
||||
(void) fprintf(stderr, "-p option requires use of -e\n");
|
||||
usage();
|
||||
}
|
||||
if (dump_opt['H'] && !dump_opt['f']) {
|
||||
(void) fprintf(stderr, "-H option requires use of -f\n");
|
||||
usage();
|
||||
}
|
||||
#if defined(_LP64)
|
||||
/*
|
||||
* ZDB does not typically re-read blocks; therefore limit the ARC
|
||||
@@ -9781,7 +10119,7 @@ main(int argc, char **argv)
|
||||
verbose = MAX(verbose, 1);
|
||||
|
||||
for (c = 0; c < 256; c++) {
|
||||
if (dump_all && strchr("ABeEFkKlLNOPrRSXy", c) == NULL)
|
||||
if (dump_all && strchr("ABeEfFkKlLNOPrRSXy", c) == NULL)
|
||||
dump_opt[c] = 1;
|
||||
if (dump_opt[c])
|
||||
dump_opt[c] += verbose;
|
||||
@@ -10153,7 +10491,7 @@ retry_lookup:
|
||||
flagbits['z'] = ZOR_FLAG_ZAP;
|
||||
flagbits['A'] = ZOR_FLAG_ALL_TYPES;
|
||||
|
||||
if (argc > 0 && dump_opt['d']) {
|
||||
if (argc > 0 && (dump_opt['d'] || dump_opt['f'])) {
|
||||
zopt_object_args = argc;
|
||||
zopt_object_ranges = calloc(zopt_object_args,
|
||||
sizeof (zopt_object_range_t));
|
||||
@@ -10179,7 +10517,10 @@ retry_lookup:
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
if (dump_opt['B']) {
|
||||
|
||||
if (dump_opt['f'] && os != NULL) {
|
||||
dump_file_data_layout(os);
|
||||
} else if (dump_opt['B']) {
|
||||
dump_backup(target, objset_id,
|
||||
argc > 0 ? argv[0] : NULL);
|
||||
} else if (os != NULL) {
|
||||
|
||||
@@ -45,21 +45,10 @@ struct launched_process_node {
|
||||
static int
|
||||
_launched_process_node_compare(const void *x1, const void *x2)
|
||||
{
|
||||
pid_t p1;
|
||||
pid_t p2;
|
||||
const struct launched_process_node *node1 = x1;
|
||||
const struct launched_process_node *node2 = x2;
|
||||
|
||||
assert(x1 != NULL);
|
||||
assert(x2 != NULL);
|
||||
|
||||
p1 = ((const struct launched_process_node *) x1)->pid;
|
||||
p2 = ((const struct launched_process_node *) x2)->pid;
|
||||
|
||||
if (p1 < p2)
|
||||
return (-1);
|
||||
else if (p1 == p2)
|
||||
return (0);
|
||||
else
|
||||
return (1);
|
||||
return (TREE_CMP(node1->pid, node2->pid));
|
||||
}
|
||||
|
||||
static pthread_t _reap_children_tid = (pthread_t)-1;
|
||||
|
||||
@@ -42,26 +42,10 @@ typedef struct zed_strings_node zed_strings_node_t;
|
||||
static int
|
||||
_zed_strings_node_compare(const void *x1, const void *x2)
|
||||
{
|
||||
const char *s1;
|
||||
const char *s2;
|
||||
int rv;
|
||||
const zed_strings_node_t *n1 = x1;
|
||||
const zed_strings_node_t *n2 = x2;
|
||||
|
||||
assert(x1 != NULL);
|
||||
assert(x2 != NULL);
|
||||
|
||||
s1 = ((const zed_strings_node_t *) x1)->key;
|
||||
assert(s1 != NULL);
|
||||
s2 = ((const zed_strings_node_t *) x2)->key;
|
||||
assert(s2 != NULL);
|
||||
rv = strcmp(s1, s2);
|
||||
|
||||
if (rv < 0)
|
||||
return (-1);
|
||||
|
||||
if (rv > 0)
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
return (TREE_ISIGN(strcmp(n1->key, n2->key)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -413,14 +413,12 @@ zfs_sort(const void *larg, const void *rarg)
|
||||
|
||||
if (lstr)
|
||||
ret = TREE_ISIGN(strcmp(lstr, rstr));
|
||||
else if (lnum < rnum)
|
||||
ret = -1;
|
||||
else if (lnum > rnum)
|
||||
ret = 1;
|
||||
else
|
||||
ret = TREE_CMP(lnum, rnum);
|
||||
|
||||
if (ret != 0) {
|
||||
if (psc->sc_reverse == B_TRUE)
|
||||
ret = (ret < 0) ? 1 : -1;
|
||||
ret = -ret;
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,12 +292,13 @@ get_usage(zfs_help_t idx)
|
||||
{
|
||||
switch (idx) {
|
||||
case HELP_CLONE:
|
||||
return (gettext("\tclone [-pu] [-o property=value] ... "
|
||||
return (gettext("\tclone [-p[p]u] [-o property=value] ... "
|
||||
"<snapshot> <filesystem|volume>\n"));
|
||||
case HELP_CREATE:
|
||||
return (gettext("\tcreate [-Pnpuv] [-o property=value] ... "
|
||||
return (gettext("\tcreate [-Pnp[p]uv] [-o property=value] ... "
|
||||
"<filesystem>\n"
|
||||
"\tcreate [-Pnpsv] [-b blocksize] [-o property=value] ... "
|
||||
"\tcreate [-Pnp[p]sv] [-b blocksize] "
|
||||
"[-o property=value] ... "
|
||||
"-V <size> <volume>\n"));
|
||||
case HELP_DESTROY:
|
||||
return (gettext("\tdestroy [-fnpRrv] <filesystem|volume>\n"
|
||||
@@ -338,16 +339,17 @@ get_usage(zfs_help_t idx)
|
||||
case HELP_RENAME:
|
||||
return (gettext("\trename [-f] <filesystem|volume|snapshot> "
|
||||
"<filesystem|volume|snapshot>\n"
|
||||
"\trename -p [-f] <filesystem|volume> <filesystem|volume>\n"
|
||||
"\trename -p[p] [-f] <filesystem|volume> "
|
||||
"<filesystem|volume>\n"
|
||||
"\trename -u [-f] <filesystem> <filesystem>\n"
|
||||
"\trename -r <snapshot> <snapshot>\n"));
|
||||
case HELP_ROLLBACK:
|
||||
return (gettext("\trollback [-rRf] <snapshot>\n"));
|
||||
case HELP_SEND:
|
||||
return (gettext("\tsend [-DLPbcehnpsVvw] "
|
||||
return (gettext("\tsend [-DLPbcehnpsUVvw] "
|
||||
"[-i|-I snapshot]\n"
|
||||
"\t [-R [-X dataset[,dataset]...]] <snapshot>\n"
|
||||
"\tsend [-DnVvPLecw] [-i snapshot|bookmark] "
|
||||
"\tsend [-DnVvPLecwU] [-i snapshot|bookmark] "
|
||||
"<filesystem|volume|snapshot>\n"
|
||||
"\tsend [-DnPpVvLec] [-i bookmark|snapshot] "
|
||||
"--redact <bookmark> <snapshot>\n"
|
||||
@@ -766,6 +768,26 @@ finish_progress(const char *done)
|
||||
pt_header = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
makeprops_parents(nvlist_t **ptr, boolean_t parents_nomount)
|
||||
{
|
||||
nvlist_t *props = NULL;
|
||||
|
||||
if (parents_nomount) {
|
||||
if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
|
||||
nomem();
|
||||
|
||||
if (nvlist_add_string(props,
|
||||
zfs_prop_to_name(ZFS_PROP_CANMOUNT),
|
||||
"off") != 0) {
|
||||
nvlist_free(props);
|
||||
nomem();
|
||||
}
|
||||
}
|
||||
|
||||
*ptr = props;
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_mount_and_share(libzfs_handle_t *hdl, const char *dataset, zfs_type_t type)
|
||||
{
|
||||
@@ -826,6 +848,7 @@ zfs_mount_and_share(libzfs_handle_t *hdl, const char *dataset, zfs_type_t type)
|
||||
* the clone exists.
|
||||
*
|
||||
* The '-p' flag creates all the non-existing ancestors of the target first.
|
||||
* If repeated twice, the ancestors are created with `canmount=off`.
|
||||
*
|
||||
* The '-u' flag prevents the newly created file system from being mounted.
|
||||
*/
|
||||
@@ -834,8 +857,10 @@ zfs_do_clone(int argc, char **argv)
|
||||
{
|
||||
zfs_handle_t *zhp = NULL;
|
||||
boolean_t parents = B_FALSE;
|
||||
boolean_t parents_nomount = B_FALSE;
|
||||
boolean_t nomount = B_FALSE;
|
||||
nvlist_t *props;
|
||||
nvlist_t *props_parents = NULL;
|
||||
int ret = 1;
|
||||
int c;
|
||||
|
||||
@@ -852,7 +877,10 @@ zfs_do_clone(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
parents = B_TRUE;
|
||||
if (!parents)
|
||||
parents = B_TRUE;
|
||||
else
|
||||
parents_nomount = B_TRUE;
|
||||
break;
|
||||
case 'u':
|
||||
nomount = B_TRUE;
|
||||
@@ -900,9 +928,11 @@ zfs_do_clone(int argc, char **argv)
|
||||
ret = 0;
|
||||
goto error;
|
||||
}
|
||||
if (zfs_create_ancestors(g_zfs, argv[1]) != 0) {
|
||||
|
||||
makeprops_parents(&props_parents, parents_nomount);
|
||||
if (zfs_create_ancestors_props(g_zfs, argv[1],
|
||||
props_parents) != 0)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* pass to libzfs */
|
||||
@@ -930,11 +960,13 @@ error:
|
||||
zfs_close(zhp);
|
||||
error_open:
|
||||
nvlist_free(props);
|
||||
nvlist_free(props_parents);
|
||||
return (!!ret);
|
||||
|
||||
usage:
|
||||
ASSERT0P(zhp);
|
||||
nvlist_free(props);
|
||||
nvlist_free(props_parents);
|
||||
usage(B_FALSE);
|
||||
return (-1);
|
||||
}
|
||||
@@ -1068,6 +1100,7 @@ default_volblocksize(zpool_handle_t *zhp, nvlist_t *props)
|
||||
* SPA_VERSION_REFRESERVATION, we set a refreservation instead.
|
||||
*
|
||||
* The '-p' flag creates all the non-existing ancestors of the target first.
|
||||
* If repeated twice, the ancestors are created with `canmount=off`.
|
||||
*
|
||||
* The '-n' flag is no-op (dry run) mode. This will perform a user-space sanity
|
||||
* check of arguments and properties, but does not check for permissions,
|
||||
@@ -1090,12 +1123,14 @@ zfs_do_create(int argc, char **argv)
|
||||
boolean_t noreserve = B_FALSE;
|
||||
boolean_t bflag = B_FALSE;
|
||||
boolean_t parents = B_FALSE;
|
||||
boolean_t parents_nomount = B_FALSE;
|
||||
boolean_t dryrun = B_FALSE;
|
||||
boolean_t nomount = B_FALSE;
|
||||
boolean_t verbose = B_FALSE;
|
||||
boolean_t parseable = B_FALSE;
|
||||
int ret = 1;
|
||||
nvlist_t *props;
|
||||
nvlist_t *props_parents = NULL;
|
||||
uint64_t intval;
|
||||
const char *strval;
|
||||
|
||||
@@ -1124,7 +1159,10 @@ zfs_do_create(int argc, char **argv)
|
||||
parseable = B_TRUE;
|
||||
break;
|
||||
case 'p':
|
||||
parents = B_TRUE;
|
||||
if (!parents)
|
||||
parents = B_TRUE;
|
||||
else
|
||||
parents_nomount = B_TRUE;
|
||||
break;
|
||||
case 'b':
|
||||
bflag = B_TRUE;
|
||||
@@ -1274,6 +1312,8 @@ zfs_do_create(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (parents && zfs_name_valid(argv[0], type)) {
|
||||
makeprops_parents(&props_parents, parents_nomount);
|
||||
|
||||
/*
|
||||
* Now create the ancestors of target dataset. If the target
|
||||
* already exists and '-p' option was used we should not
|
||||
@@ -1289,7 +1329,8 @@ zfs_do_create(int argc, char **argv)
|
||||
"create ancestors of %s\n", argv[0]);
|
||||
}
|
||||
if (!dryrun) {
|
||||
if (zfs_create_ancestors(g_zfs, argv[0]) != 0) {
|
||||
if (zfs_create_ancestors_props(g_zfs, argv[0],
|
||||
props_parents) != 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
@@ -1348,9 +1389,11 @@ zfs_do_create(int argc, char **argv)
|
||||
(void) zfs_mount_and_share(g_zfs, argv[0], ZFS_TYPE_DATASET);
|
||||
error:
|
||||
nvlist_free(props);
|
||||
nvlist_free(props_parents);
|
||||
return (ret);
|
||||
badusage:
|
||||
nvlist_free(props);
|
||||
nvlist_free(props_parents);
|
||||
usage(B_FALSE);
|
||||
return (2);
|
||||
}
|
||||
@@ -2905,15 +2948,13 @@ us_compare(const void *larg, const void *rarg)
|
||||
uint64_t rv64 = 0;
|
||||
zfs_prop_t prop = sortcol->sc_prop;
|
||||
const char *propname = NULL;
|
||||
boolean_t reverse = sortcol->sc_reverse;
|
||||
|
||||
switch (prop) {
|
||||
case ZFS_PROP_TYPE:
|
||||
propname = "type";
|
||||
(void) nvlist_lookup_uint32(lnvl, propname, &lv32);
|
||||
(void) nvlist_lookup_uint32(rnvl, propname, &rv32);
|
||||
if (rv32 != lv32)
|
||||
rc = (rv32 < lv32) ? 1 : -1;
|
||||
rc = TREE_CMP(lv32, rv32);
|
||||
break;
|
||||
case ZFS_PROP_NAME:
|
||||
propname = "name";
|
||||
@@ -2923,8 +2964,7 @@ compare_nums:
|
||||
&lv64);
|
||||
(void) nvlist_lookup_uint64(rnvl, propname,
|
||||
&rv64);
|
||||
if (rv64 != lv64)
|
||||
rc = (rv64 < lv64) ? 1 : -1;
|
||||
rc = TREE_CMP(lv64, rv64);
|
||||
} else {
|
||||
if ((nvlist_lookup_string(lnvl, propname,
|
||||
&lvstr) == ENOENT) ||
|
||||
@@ -2932,7 +2972,7 @@ compare_nums:
|
||||
&rvstr) == ENOENT)) {
|
||||
goto compare_nums;
|
||||
}
|
||||
rc = strcmp(lvstr, rvstr);
|
||||
rc = TREE_ISIGN(strcmp(lvstr, rvstr));
|
||||
}
|
||||
break;
|
||||
case ZFS_PROP_USED:
|
||||
@@ -2945,8 +2985,7 @@ compare_nums:
|
||||
propname = "quota";
|
||||
(void) nvlist_lookup_uint64(lnvl, propname, &lv64);
|
||||
(void) nvlist_lookup_uint64(rnvl, propname, &rv64);
|
||||
if (rv64 != lv64)
|
||||
rc = (rv64 < lv64) ? 1 : -1;
|
||||
rc = TREE_CMP(lv64, rv64);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -2954,10 +2993,9 @@ compare_nums:
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
if (rc < 0)
|
||||
return (reverse ? 1 : -1);
|
||||
else
|
||||
return (reverse ? -1 : 1);
|
||||
if (sortcol->sc_reverse)
|
||||
return (-rc);
|
||||
return (rc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2967,9 +3005,8 @@ compare_nums:
|
||||
* translation where we can have duplicate type/name combinations).
|
||||
*/
|
||||
if (nvlist_lookup_boolean_value(lnvl, "smbentity", &lvb) == 0 &&
|
||||
nvlist_lookup_boolean_value(rnvl, "smbentity", &rvb) == 0 &&
|
||||
lvb != rvb)
|
||||
return (lvb < rvb ? -1 : 1);
|
||||
nvlist_lookup_boolean_value(rnvl, "smbentity", &rvb) == 0)
|
||||
return (TREE_CMP(lvb, rvb));
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -4045,6 +4082,8 @@ found3:;
|
||||
* Renames the given dataset to another of the same type.
|
||||
*
|
||||
* The '-p' flag creates all the non-existing ancestors of the target first.
|
||||
* If repeated twice, the ancestors are created with `canmount=off`.
|
||||
*
|
||||
* The '-u' flag prevents file systems from being remounted during rename.
|
||||
*/
|
||||
static int
|
||||
@@ -4056,12 +4095,17 @@ zfs_do_rename(int argc, char **argv)
|
||||
int ret = 1;
|
||||
int types;
|
||||
boolean_t parents = B_FALSE;
|
||||
boolean_t parents_nomount = B_FALSE;
|
||||
nvlist_t *props_parents = NULL;
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, "pruf")) != -1) {
|
||||
switch (c) {
|
||||
case 'p':
|
||||
parents = B_TRUE;
|
||||
if (parents)
|
||||
parents_nomount = B_TRUE;
|
||||
else
|
||||
parents = B_TRUE;
|
||||
break;
|
||||
case 'r':
|
||||
flags.recursive = B_TRUE;
|
||||
@@ -4128,9 +4172,13 @@ zfs_do_rename(int argc, char **argv)
|
||||
goto error_open;
|
||||
|
||||
/* If we were asked and the name looks good, try to create ancestors. */
|
||||
if (parents && zfs_name_valid(argv[1], zfs_get_type(zhp)) &&
|
||||
zfs_create_ancestors(g_zfs, argv[1]) != 0) {
|
||||
goto error;
|
||||
if (parents && zfs_name_valid(argv[1], zfs_get_type(zhp))) {
|
||||
|
||||
makeprops_parents(&props_parents, parents_nomount);
|
||||
if (zfs_create_ancestors_props(g_zfs, argv[1],
|
||||
props_parents) != 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
ret = (zfs_rename(zhp, argv[1], flags) != 0);
|
||||
@@ -4138,6 +4186,7 @@ zfs_do_rename(int argc, char **argv)
|
||||
error:
|
||||
zfs_close(zhp);
|
||||
error_open:
|
||||
nvlist_free(props_parents);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@@ -4759,11 +4808,12 @@ zfs_do_send(int argc, char **argv)
|
||||
{"holds", no_argument, NULL, 'h'},
|
||||
{"saved", no_argument, NULL, 'S'},
|
||||
{"exclude", required_argument, NULL, 'X'},
|
||||
{"no-preserve-encryption", no_argument, NULL, 'U'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt_long(argc, argv, ":i:I:RsDpVvnPLeht:cwbd:SX:",
|
||||
while ((c = getopt_long(argc, argv, ":i:I:RsDpVvnPLeht:cwbd:SX:U",
|
||||
long_options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'X':
|
||||
@@ -4849,6 +4899,9 @@ zfs_do_send(int argc, char **argv)
|
||||
case 'S':
|
||||
flags.saved = B_TRUE;
|
||||
break;
|
||||
case 'U':
|
||||
flags.no_preserve_encryption = B_TRUE;
|
||||
break;
|
||||
case ':':
|
||||
/*
|
||||
* If a parameter was not passed, optopt contains the
|
||||
@@ -5497,11 +5550,11 @@ who_perm_compare(const void *larg, const void *rarg)
|
||||
zfs_deleg_who_type_t rtype = r->who_perm.who_type;
|
||||
int lweight = who_type2weight(ltype);
|
||||
int rweight = who_type2weight(rtype);
|
||||
int res = lweight - rweight;
|
||||
int res = TREE_CMP(lweight, rweight);
|
||||
if (res == 0)
|
||||
res = strncmp(l->who_perm.who_name, r->who_perm.who_name,
|
||||
ZFS_MAX_DELEG_NAME-1);
|
||||
return (TREE_ISIGN(res));
|
||||
res = TREE_ISIGN(strncmp(l->who_perm.who_name,
|
||||
r->who_perm.who_name, ZFS_MAX_DELEG_NAME-1));
|
||||
return (res);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -7641,15 +7694,11 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual)
|
||||
zfs_handle_t *zhp;
|
||||
int ret = 0;
|
||||
struct stat64 statbuf;
|
||||
struct extmnttab entry;
|
||||
struct mnttab entry;
|
||||
const char *cmdname = (op == OP_SHARE) ? "unshare" : "unmount";
|
||||
ino_t path_inode;
|
||||
char *zfs_mntpnt, *entry_mntpnt;
|
||||
|
||||
/*
|
||||
* Search for the given (major,minor) pair in the mount table.
|
||||
*/
|
||||
|
||||
if (getextmntent(path, &entry, &statbuf) != 0) {
|
||||
if (op == OP_SHARE) {
|
||||
(void) fprintf(stderr, gettext("cannot %s '%s': not "
|
||||
@@ -9373,7 +9422,6 @@ main(int argc, char **argv)
|
||||
/*
|
||||
* Run the appropriate command.
|
||||
*/
|
||||
libzfs_mnttab_cache(g_zfs, B_TRUE);
|
||||
if (find_command_idx(cmdname, &i) == 0) {
|
||||
current_command = &command_table[i];
|
||||
ret = command_table[i].func(argc - 1, newargv + 1);
|
||||
|
||||
@@ -85,7 +85,7 @@ static int
|
||||
parse_pathname(const char *inpath, char *dataset, char *relpath,
|
||||
struct stat64 *statbuf)
|
||||
{
|
||||
struct extmnttab mp;
|
||||
struct mnttab mp;
|
||||
const char *rel;
|
||||
char fullpath[MAXPATHLEN];
|
||||
|
||||
|
||||
@@ -458,7 +458,7 @@ get_usage(zpool_help_t idx)
|
||||
return (gettext("\tattach [-fsw] [-o property=value] "
|
||||
"<pool> <vdev> <new-device>\n"));
|
||||
case HELP_CLEAR:
|
||||
return (gettext("\tclear [[--power]|[-nF]] <pool> [device]\n"));
|
||||
return (gettext("\tclear [--power] <pool> [device]\n"));
|
||||
case HELP_CREATE:
|
||||
return (gettext("\tcreate [-fnd] [-o property=value] ... \n"
|
||||
"\t [-O file-system-property=value] ... \n"
|
||||
@@ -6960,7 +6960,19 @@ collect_vdev_prop(zpool_prop_t prop, uint64_t value, const char *str,
|
||||
|
||||
switch (prop) {
|
||||
case ZPOOL_PROP_SIZE:
|
||||
case ZPOOL_PROP_NORMAL_SIZE:
|
||||
case ZPOOL_PROP_SPECIAL_SIZE:
|
||||
case ZPOOL_PROP_DEDUP_SIZE:
|
||||
case ZPOOL_PROP_LOG_SIZE:
|
||||
case ZPOOL_PROP_ELOG_SIZE:
|
||||
case ZPOOL_PROP_SELOG_SIZE:
|
||||
case ZPOOL_PROP_EXPANDSZ:
|
||||
case ZPOOL_PROP_NORMAL_EXPANDSZ:
|
||||
case ZPOOL_PROP_SPECIAL_EXPANDSZ:
|
||||
case ZPOOL_PROP_DEDUP_EXPANDSZ:
|
||||
case ZPOOL_PROP_LOG_EXPANDSZ:
|
||||
case ZPOOL_PROP_ELOG_EXPANDSZ:
|
||||
case ZPOOL_PROP_SELOG_EXPANDSZ:
|
||||
case ZPOOL_PROP_CHECKPOINT:
|
||||
case ZPOOL_PROP_DEDUPRATIO:
|
||||
case ZPOOL_PROP_DEDUPCACHED:
|
||||
@@ -6971,6 +6983,12 @@ collect_vdev_prop(zpool_prop_t prop, uint64_t value, const char *str,
|
||||
format);
|
||||
break;
|
||||
case ZPOOL_PROP_FRAGMENTATION:
|
||||
case ZPOOL_PROP_NORMAL_FRAGMENTATION:
|
||||
case ZPOOL_PROP_SPECIAL_FRAGMENTATION:
|
||||
case ZPOOL_PROP_DEDUP_FRAGMENTATION:
|
||||
case ZPOOL_PROP_LOG_FRAGMENTATION:
|
||||
case ZPOOL_PROP_ELOG_FRAGMENTATION:
|
||||
case ZPOOL_PROP_SELOG_FRAGMENTATION:
|
||||
if (value == ZFS_FRAG_INVALID) {
|
||||
(void) strlcpy(propval, "-", sizeof (propval));
|
||||
} else if (format == ZFS_NICENUM_RAW) {
|
||||
@@ -6982,6 +7000,12 @@ collect_vdev_prop(zpool_prop_t prop, uint64_t value, const char *str,
|
||||
}
|
||||
break;
|
||||
case ZPOOL_PROP_CAPACITY:
|
||||
case ZPOOL_PROP_NORMAL_CAPACITY:
|
||||
case ZPOOL_PROP_SPECIAL_CAPACITY:
|
||||
case ZPOOL_PROP_DEDUP_CAPACITY:
|
||||
case ZPOOL_PROP_LOG_CAPACITY:
|
||||
case ZPOOL_PROP_ELOG_CAPACITY:
|
||||
case ZPOOL_PROP_SELOG_CAPACITY:
|
||||
/* capacity value is in parts-per-10,000 (aka permyriad) */
|
||||
if (format == ZFS_NICENUM_RAW)
|
||||
(void) snprintf(propval, sizeof (propval), "%llu",
|
||||
@@ -8227,7 +8251,7 @@ zpool_do_offline(int argc, char **argv)
|
||||
}
|
||||
|
||||
/*
|
||||
* zpool clear [-nF]|[--power] <pool> [device]
|
||||
* zpool clear [--power] <pool> [device]
|
||||
*
|
||||
* Clear all errors associated with a pool or a particular device.
|
||||
*/
|
||||
@@ -8236,11 +8260,7 @@ zpool_do_clear(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
int ret = 0;
|
||||
boolean_t dryrun = B_FALSE;
|
||||
boolean_t do_rewind = B_FALSE;
|
||||
boolean_t xtreme_rewind = B_FALSE;
|
||||
boolean_t is_power_on = B_FALSE;
|
||||
uint32_t rewind_policy = ZPOOL_NO_REWIND;
|
||||
nvlist_t *policy = NULL;
|
||||
zpool_handle_t *zhp;
|
||||
char *pool, *device;
|
||||
@@ -8251,18 +8271,9 @@ zpool_do_clear(int argc, char **argv)
|
||||
};
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt_long(argc, argv, "FnX", long_options,
|
||||
while ((c = getopt_long(argc, argv, "", long_options,
|
||||
NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'F':
|
||||
do_rewind = B_TRUE;
|
||||
break;
|
||||
case 'n':
|
||||
dryrun = B_TRUE;
|
||||
break;
|
||||
case 'X':
|
||||
xtreme_rewind = B_TRUE;
|
||||
break;
|
||||
case ZPOOL_OPTION_POWER:
|
||||
is_power_on = B_TRUE;
|
||||
break;
|
||||
@@ -8289,24 +8300,8 @@ zpool_do_clear(int argc, char **argv)
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
if ((dryrun || xtreme_rewind) && !do_rewind) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("-n or -X only meaningful with -F\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
if (dryrun)
|
||||
rewind_policy = ZPOOL_TRY_REWIND;
|
||||
else if (do_rewind)
|
||||
rewind_policy = ZPOOL_DO_REWIND;
|
||||
if (xtreme_rewind)
|
||||
rewind_policy |= ZPOOL_EXTREME_REWIND;
|
||||
|
||||
/* In future, further rewind policy choices can be passed along here */
|
||||
if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
|
||||
nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY,
|
||||
rewind_policy) != 0) {
|
||||
if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0)
|
||||
return (1);
|
||||
}
|
||||
|
||||
pool = argv[0];
|
||||
device = argc == 2 ? argv[1] : NULL;
|
||||
@@ -10500,7 +10495,7 @@ print_dedup_stats(zpool_handle_t *zhp, nvlist_t *config, boolean_t literal)
|
||||
(uint64_t **)&dds, &c) == 0);
|
||||
verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM,
|
||||
(uint64_t **)&ddh, &c) == 0);
|
||||
zpool_dump_ddt(dds, ddh);
|
||||
zpool_dump_ddt(dds, ddh, literal);
|
||||
}
|
||||
|
||||
#define ST_SIZE 4096
|
||||
|
||||
@@ -8,10 +8,13 @@ zstream_SOURCES = \
|
||||
%D%/zstream.c \
|
||||
%D%/zstream.h \
|
||||
%D%/zstream_decompress.c \
|
||||
%D%/zstream_drop_record.c \
|
||||
%D%/zstream_dump.c \
|
||||
%D%/zstream_recompress.c \
|
||||
%D%/zstream_redup.c \
|
||||
%D%/zstream_token.c
|
||||
%D%/zstream_token.c \
|
||||
%D%/zstream_util.c \
|
||||
%D%/zstream_util.h
|
||||
|
||||
zstream_LDADD = \
|
||||
libzfs.la \
|
||||
|
||||
@@ -43,6 +43,8 @@ zstream_usage(void)
|
||||
"\n"
|
||||
"\tzstream decompress [-v] [OBJECT,OFFSET[,TYPE]] ...\n"
|
||||
"\n"
|
||||
"\tzstream drop_record [-v] [OBJECT,OFFSET] ...\n"
|
||||
"\n"
|
||||
"\tzstream recompress [ -l level] TYPE\n"
|
||||
"\n"
|
||||
"\tzstream token resume_token\n"
|
||||
@@ -68,6 +70,8 @@ main(int argc, char *argv[])
|
||||
return (zstream_do_dump(argc - 1, argv + 1));
|
||||
} else if (strcmp(subcommand, "decompress") == 0) {
|
||||
return (zstream_do_decompress(argc - 1, argv + 1));
|
||||
} else if (strcmp(subcommand, "drop_record") == 0) {
|
||||
return (zstream_do_drop_record(argc - 1, argv + 1));
|
||||
} else if (strcmp(subcommand, "recompress") == 0) {
|
||||
return (zstream_do_recompress(argc - 1, argv + 1));
|
||||
} else if (strcmp(subcommand, "token") == 0) {
|
||||
|
||||
@@ -25,12 +25,10 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void *safe_calloc(size_t n);
|
||||
extern int sfread(void *buf, size_t size, FILE *fp);
|
||||
extern void *safe_malloc(size_t size);
|
||||
extern int zstream_do_redup(int, char *[]);
|
||||
extern int zstream_do_dump(int, char *[]);
|
||||
extern int zstream_do_decompress(int argc, char *argv[]);
|
||||
extern int zstream_do_drop_record(int argc, char *argv[]);
|
||||
extern int zstream_do_recompress(int argc, char *argv[]);
|
||||
extern int zstream_do_token(int, char *[]);
|
||||
extern void zstream_usage(void);
|
||||
|
||||
@@ -37,31 +37,7 @@
|
||||
#include <sys/zstd/zstd.h>
|
||||
#include "zfs_fletcher.h"
|
||||
#include "zstream.h"
|
||||
|
||||
static int
|
||||
dump_record(dmu_replay_record_t *drr, void *payload, int payload_len,
|
||||
zio_cksum_t *zc, int outfd)
|
||||
{
|
||||
assert(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum)
|
||||
== sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
|
||||
fletcher_4_incremental_native(drr,
|
||||
offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc);
|
||||
if (drr->drr_type != DRR_BEGIN) {
|
||||
assert(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.
|
||||
drr_checksum.drr_checksum));
|
||||
drr->drr_u.drr_checksum.drr_checksum = *zc;
|
||||
}
|
||||
fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum,
|
||||
sizeof (zio_cksum_t), zc);
|
||||
if (write(outfd, drr, sizeof (*drr)) == -1)
|
||||
return (errno);
|
||||
if (payload_len != 0) {
|
||||
fletcher_4_incremental_native(payload, payload_len, zc);
|
||||
if (write(outfd, payload, payload_len) == -1)
|
||||
return (errno);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#include "zstream_util.h"
|
||||
|
||||
int
|
||||
zstream_do_decompress(int argc, char *argv[])
|
||||
|
||||
@@ -0,0 +1,324 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* 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 2026 ConnectWise. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <search.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/zfs_ioctl.h>
|
||||
#include <sys/zio_checksum.h>
|
||||
#include <sys/zstd/zstd.h>
|
||||
#include "zfs_fletcher.h"
|
||||
#include "zstream.h"
|
||||
#include "zstream_util.h"
|
||||
|
||||
int
|
||||
zstream_do_drop_record(int argc, char *argv[])
|
||||
{
|
||||
const int KEYSIZE = 64;
|
||||
int bufsz = SPA_MAXBLOCKSIZE;
|
||||
char *buf = safe_malloc(bufsz);
|
||||
dmu_replay_record_t thedrr;
|
||||
dmu_replay_record_t *drr = &thedrr;
|
||||
zio_cksum_t stream_cksum;
|
||||
int c;
|
||||
boolean_t verbose = B_FALSE;
|
||||
|
||||
while ((c = getopt(argc, argv, "v")) != -1) {
|
||||
switch (c) {
|
||||
case 'v':
|
||||
verbose = B_TRUE;
|
||||
break;
|
||||
case '?':
|
||||
(void) fprintf(stderr, "invalid option '%c'\n",
|
||||
optopt);
|
||||
zstream_usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 0)
|
||||
zstream_usage();
|
||||
|
||||
if (hcreate(argc) == 0)
|
||||
errx(1, "hcreate");
|
||||
for (int i = 0; i < argc; i++) {
|
||||
uint64_t object, offset;
|
||||
char *obj_str;
|
||||
char *offset_str;
|
||||
char *key;
|
||||
char *end;
|
||||
|
||||
obj_str = strsep(&argv[i], ",");
|
||||
if (argv[i] == NULL) {
|
||||
zstream_usage();
|
||||
exit(2);
|
||||
}
|
||||
errno = 0;
|
||||
object = strtoull(obj_str, &end, 0);
|
||||
if (errno || *end != '\0')
|
||||
errx(1, "invalid value for object");
|
||||
offset_str = strsep(&argv[i], ",");
|
||||
offset = strtoull(offset_str, &end, 0);
|
||||
if (errno || *end != '\0')
|
||||
errx(1, "invalid value for offset");
|
||||
|
||||
if (asprintf(&key, "%llu,%llu", (u_longlong_t)object,
|
||||
(u_longlong_t)offset) < 0) {
|
||||
err(1, "asprintf");
|
||||
}
|
||||
ENTRY e = {.key = key};
|
||||
ENTRY *p;
|
||||
|
||||
p = hsearch(e, ENTER);
|
||||
if (p == NULL)
|
||||
errx(1, "hsearch");
|
||||
p->data = (void*)(intptr_t)B_TRUE;
|
||||
}
|
||||
|
||||
if (isatty(STDIN_FILENO)) {
|
||||
(void) fprintf(stderr,
|
||||
"Error: The send stream is a binary format "
|
||||
"and can not be read from a\n"
|
||||
"terminal. Standard input must be redirected.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fletcher_4_init();
|
||||
int begin = 0;
|
||||
boolean_t seen = B_FALSE;
|
||||
while (sfread(drr, sizeof (*drr), stdin) != 0) {
|
||||
struct drr_write *drrw;
|
||||
uint64_t payload_size = 0;
|
||||
|
||||
/*
|
||||
* We need to regenerate the checksum.
|
||||
*/
|
||||
if (drr->drr_type != DRR_BEGIN) {
|
||||
memset(&drr->drr_u.drr_checksum.drr_checksum, 0,
|
||||
sizeof (drr->drr_u.drr_checksum.drr_checksum));
|
||||
}
|
||||
|
||||
switch (drr->drr_type) {
|
||||
case DRR_BEGIN:
|
||||
{
|
||||
ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0);
|
||||
VERIFY0(begin++);
|
||||
seen = B_TRUE;
|
||||
|
||||
uint32_t sz = drr->drr_payloadlen;
|
||||
|
||||
VERIFY3U(sz, <=, 1U << 28);
|
||||
|
||||
if (sz != 0) {
|
||||
if (sz > bufsz) {
|
||||
buf = realloc(buf, sz);
|
||||
if (buf == NULL)
|
||||
err(1, "realloc");
|
||||
bufsz = sz;
|
||||
}
|
||||
(void) sfread(buf, sz, stdin);
|
||||
}
|
||||
payload_size = sz;
|
||||
break;
|
||||
}
|
||||
case DRR_END:
|
||||
{
|
||||
struct drr_end *drre = &drr->drr_u.drr_end;
|
||||
/*
|
||||
* We would prefer to just check --begin == 0, but
|
||||
* replication streams have an end of stream END
|
||||
* record, so we must avoid tripping it.
|
||||
*/
|
||||
VERIFY3B(seen, ==, B_TRUE);
|
||||
begin--;
|
||||
/*
|
||||
* Use the recalculated checksum, unless this is
|
||||
* the END record of a stream package, which has
|
||||
* no checksum.
|
||||
*/
|
||||
if (!ZIO_CHECKSUM_IS_ZERO(&drre->drr_checksum))
|
||||
drre->drr_checksum = stream_cksum;
|
||||
break;
|
||||
}
|
||||
|
||||
case DRR_OBJECT:
|
||||
{
|
||||
struct drr_object *drro = &drr->drr_u.drr_object;
|
||||
VERIFY3S(begin, ==, 1);
|
||||
|
||||
if (drro->drr_bonuslen > 0) {
|
||||
payload_size = DRR_OBJECT_PAYLOAD_SIZE(drro);
|
||||
(void) sfread(buf, payload_size, stdin);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case DRR_SPILL:
|
||||
{
|
||||
struct drr_spill *drrs = &drr->drr_u.drr_spill;
|
||||
VERIFY3S(begin, ==, 1);
|
||||
payload_size = DRR_SPILL_PAYLOAD_SIZE(drrs);
|
||||
(void) sfread(buf, payload_size, stdin);
|
||||
break;
|
||||
}
|
||||
|
||||
case DRR_WRITE_BYREF:
|
||||
VERIFY3S(begin, ==, 1);
|
||||
fprintf(stderr,
|
||||
"Deduplicated streams are not supported\n");
|
||||
exit(1);
|
||||
break;
|
||||
|
||||
case DRR_WRITE:
|
||||
{
|
||||
VERIFY3S(begin, ==, 1);
|
||||
drrw = &thedrr.drr_u.drr_write;
|
||||
payload_size = DRR_WRITE_PAYLOAD_SIZE(drrw);
|
||||
ENTRY *p;
|
||||
char key[KEYSIZE];
|
||||
|
||||
snprintf(key, KEYSIZE, "%llu,%llu",
|
||||
(u_longlong_t)drrw->drr_object,
|
||||
(u_longlong_t)drrw->drr_offset);
|
||||
ENTRY e = {.key = key};
|
||||
|
||||
(void) sfread(buf, payload_size, stdin);
|
||||
p = hsearch(e, FIND);
|
||||
if (p == NULL) {
|
||||
/*
|
||||
* Dump the contents of the block unaltered
|
||||
*/
|
||||
} else {
|
||||
/*
|
||||
* Read and discard the block
|
||||
*/
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
"Dropping WRITE record for object "
|
||||
"%llu offset %llu\n",
|
||||
(u_longlong_t)drrw->drr_object,
|
||||
(u_longlong_t)drrw->drr_offset);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case DRR_WRITE_EMBEDDED:
|
||||
{
|
||||
ENTRY *p;
|
||||
char key[KEYSIZE];
|
||||
|
||||
VERIFY3S(begin, ==, 1);
|
||||
struct drr_write_embedded *drrwe =
|
||||
&drr->drr_u.drr_write_embedded;
|
||||
payload_size =
|
||||
P2ROUNDUP((uint64_t)drrwe->drr_psize, 8);
|
||||
|
||||
snprintf(key, KEYSIZE, "%llu,%llu",
|
||||
(u_longlong_t)drrwe->drr_object,
|
||||
(u_longlong_t)drrwe->drr_offset);
|
||||
ENTRY e = {.key = key};
|
||||
|
||||
(void) sfread(buf, payload_size, stdin);
|
||||
p = hsearch(e, FIND);
|
||||
if (p == NULL) {
|
||||
/*
|
||||
* Dump the contents of the block unaltered
|
||||
*/
|
||||
} else {
|
||||
/*
|
||||
* Read and discard the block
|
||||
*/
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
"Dropping WRITE_EMBEDDED record for"
|
||||
" object %llu offset %llu\n",
|
||||
(u_longlong_t)drrwe->drr_object,
|
||||
(u_longlong_t)drrwe->drr_offset);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case DRR_FREEOBJECTS:
|
||||
case DRR_FREE:
|
||||
case DRR_OBJECT_RANGE:
|
||||
VERIFY3S(begin, ==, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
(void) fprintf(stderr, "INVALID record type 0x%x\n",
|
||||
drr->drr_type);
|
||||
/* should never happen, so assert */
|
||||
assert(B_FALSE);
|
||||
}
|
||||
|
||||
if (feof(stdout)) {
|
||||
fprintf(stderr, "Error: unexpected end-of-file\n");
|
||||
exit(1);
|
||||
}
|
||||
if (ferror(stdout)) {
|
||||
fprintf(stderr, "Error while reading file: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to recalculate the checksum, and it needs to be
|
||||
* initially zero to do that. BEGIN records don't have
|
||||
* a checksum.
|
||||
*/
|
||||
if (drr->drr_type != DRR_BEGIN) {
|
||||
memset(&drr->drr_u.drr_checksum.drr_checksum, 0,
|
||||
sizeof (drr->drr_u.drr_checksum.drr_checksum));
|
||||
}
|
||||
if (dump_record(drr, buf, payload_size,
|
||||
&stream_cksum, STDOUT_FILENO) != 0)
|
||||
break;
|
||||
if (drr->drr_type == DRR_END) {
|
||||
/*
|
||||
* Typically the END record is either the last
|
||||
* thing in the stream, or it is followed
|
||||
* by a BEGIN record (which also zeros the checksum).
|
||||
* However, a stream package ends with two END
|
||||
* records. The last END record's checksum starts
|
||||
* from zero.
|
||||
*/
|
||||
ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
fletcher_4_fini();
|
||||
hdestroy();
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <sys/zio.h>
|
||||
#include <zfs_fletcher.h>
|
||||
#include "zstream.h"
|
||||
#include "zstream_util.h"
|
||||
|
||||
/*
|
||||
* If dump mode is enabled, the number of bytes to print per line
|
||||
@@ -60,18 +61,6 @@ static FILE *send_stream = 0;
|
||||
static boolean_t do_byteswap = B_FALSE;
|
||||
static boolean_t do_cksum = B_TRUE;
|
||||
|
||||
void *
|
||||
safe_malloc(size_t size)
|
||||
{
|
||||
void *rv = malloc(size);
|
||||
if (rv == NULL) {
|
||||
(void) fprintf(stderr, "ERROR; failed to allocate %zu bytes\n",
|
||||
size);
|
||||
abort();
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* ssread - send stream read.
|
||||
*
|
||||
|
||||
@@ -37,31 +37,7 @@
|
||||
#include <sys/zstd/zstd.h>
|
||||
#include "zfs_fletcher.h"
|
||||
#include "zstream.h"
|
||||
|
||||
static int
|
||||
dump_record(dmu_replay_record_t *drr, void *payload, int payload_len,
|
||||
zio_cksum_t *zc, int outfd)
|
||||
{
|
||||
assert(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum)
|
||||
== sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
|
||||
fletcher_4_incremental_native(drr,
|
||||
offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc);
|
||||
if (drr->drr_type != DRR_BEGIN) {
|
||||
assert(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.
|
||||
drr_checksum.drr_checksum));
|
||||
drr->drr_u.drr_checksum.drr_checksum = *zc;
|
||||
}
|
||||
fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum,
|
||||
sizeof (zio_cksum_t), zc);
|
||||
if (write(outfd, drr, sizeof (*drr)) == -1)
|
||||
return (errno);
|
||||
if (payload_len != 0) {
|
||||
fletcher_4_incremental_native(payload, payload_len, zc);
|
||||
if (write(outfd, payload, payload_len) == -1)
|
||||
return (errno);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#include "zstream_util.h"
|
||||
|
||||
int
|
||||
zstream_do_recompress(int argc, char *argv[])
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <sys/zio_checksum.h>
|
||||
#include "zfs_fletcher.h"
|
||||
#include "zstream.h"
|
||||
#include "zstream_util.h"
|
||||
|
||||
|
||||
#define MAX_RDT_PHYSMEM_PERCENT 20
|
||||
@@ -57,34 +58,6 @@ typedef struct redup_table {
|
||||
int numhashbits;
|
||||
} redup_table_t;
|
||||
|
||||
void *
|
||||
safe_calloc(size_t n)
|
||||
{
|
||||
void *rv = calloc(1, n);
|
||||
if (rv == NULL) {
|
||||
fprintf(stderr,
|
||||
"Error: could not allocate %u bytes of memory\n",
|
||||
(int)n);
|
||||
exit(1);
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Safe version of fread(), exits on error.
|
||||
*/
|
||||
int
|
||||
sfread(void *buf, size_t size, FILE *fp)
|
||||
{
|
||||
int rv = fread(buf, size, 1, fp);
|
||||
if (rv == 0 && ferror(fp)) {
|
||||
(void) fprintf(stderr, "Error while reading file: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Safe version of pread(), exits on error.
|
||||
*/
|
||||
@@ -104,31 +77,6 @@ spread(int fd, void *buf, size_t count, off_t offset)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
dump_record(dmu_replay_record_t *drr, void *payload, int payload_len,
|
||||
zio_cksum_t *zc, int outfd)
|
||||
{
|
||||
assert(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum)
|
||||
== sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
|
||||
fletcher_4_incremental_native(drr,
|
||||
offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc);
|
||||
if (drr->drr_type != DRR_BEGIN) {
|
||||
assert(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.
|
||||
drr_checksum.drr_checksum));
|
||||
drr->drr_u.drr_checksum.drr_checksum = *zc;
|
||||
}
|
||||
fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum,
|
||||
sizeof (zio_cksum_t), zc);
|
||||
if (write(outfd, drr, sizeof (*drr)) == -1)
|
||||
return (errno);
|
||||
if (payload_len != 0) {
|
||||
fletcher_4_incremental_native(payload, payload_len, zc);
|
||||
if (write(outfd, payload, payload_len) == -1)
|
||||
return (errno);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
rdt_insert(redup_table_t *rdt,
|
||||
uint64_t guid, uint64_t object, uint64_t offset, uint64_t stream_offset)
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* This file and its contents are supplied under the terms of the
|
||||
* Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
* You may only use this file in accordance with the terms of version
|
||||
* 1.0 of the CDDL.
|
||||
*
|
||||
* A full copy of the text of the CDDL should have accompanied this
|
||||
* source. A copy of the CDDL is also available via the Internet at
|
||||
* http://www.illumos.org/license/CDDL.
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2020 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
||||
* All rights reserved
|
||||
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
||||
* Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
|
||||
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
|
||||
* Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
|
||||
* Copyright (c) 2019 Datto Inc.
|
||||
* Copyright (c) 2024, Klara, Inc.
|
||||
*/
|
||||
|
||||
#include <sys/debug.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <zfs_fletcher.h>
|
||||
#include "zstream_util.h"
|
||||
|
||||
/*
|
||||
* From libzfs_sendrecv.c
|
||||
*/
|
||||
int
|
||||
dump_record(dmu_replay_record_t *drr, void *payload, size_t payload_len,
|
||||
zio_cksum_t *zc, int outfd)
|
||||
{
|
||||
ASSERT3U(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum),
|
||||
==, sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
|
||||
fletcher_4_incremental_native(drr,
|
||||
offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc);
|
||||
if (drr->drr_type != DRR_BEGIN) {
|
||||
ASSERT(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.
|
||||
drr_checksum.drr_checksum));
|
||||
drr->drr_u.drr_checksum.drr_checksum = *zc;
|
||||
}
|
||||
fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum,
|
||||
sizeof (zio_cksum_t), zc);
|
||||
if (write(outfd, drr, sizeof (*drr)) == -1)
|
||||
return (errno);
|
||||
if (payload_len != 0) {
|
||||
fletcher_4_incremental_native(payload, payload_len, zc);
|
||||
if (write(outfd, payload, payload_len) == -1)
|
||||
return (errno);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void *
|
||||
safe_malloc(size_t size)
|
||||
{
|
||||
void *rv = malloc(size);
|
||||
if (rv == NULL) {
|
||||
(void) fprintf(stderr, "Error: failed to allocate %zu bytes\n",
|
||||
size);
|
||||
exit(1);
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
|
||||
void *
|
||||
safe_calloc(size_t size)
|
||||
{
|
||||
void *rv = calloc(1, size);
|
||||
if (rv == NULL) {
|
||||
(void) fprintf(stderr,
|
||||
"Error: failed to allocate %zu bytes\n", size);
|
||||
exit(1);
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Safe version of fread(), exits on error.
|
||||
*/
|
||||
int
|
||||
sfread(void *buf, size_t size, FILE *fp)
|
||||
{
|
||||
int rv = fread(buf, size, 1, fp);
|
||||
if (rv == 0 && ferror(fp)) {
|
||||
(void) fprintf(stderr, "Error while reading file: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* This file and its contents are supplied under the terms of the
|
||||
* Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
* You may only use this file in accordance with the terms of version
|
||||
* 1.0 of the CDDL.
|
||||
*
|
||||
* A full copy of the text of the CDDL should have accompanied this
|
||||
* source. A copy of the CDDL is also available via the Internet at
|
||||
* http://www.illumos.org/license/CDDL.
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2026 by Garth Snyder. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _ZSTREAM_UTIL_H
|
||||
#define _ZSTREAM_UTIL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/zfs_ioctl.h>
|
||||
#include <sys/zio_checksum.h>
|
||||
|
||||
/*
|
||||
* The safe_ versions of the functions below terminate the process if the
|
||||
* operation doesn't succeed instead of returning an error.
|
||||
*/
|
||||
extern void *
|
||||
safe_malloc(size_t size);
|
||||
|
||||
extern void *
|
||||
safe_calloc(size_t n);
|
||||
|
||||
extern int
|
||||
sfread(void *buf, size_t size, FILE *fp);
|
||||
|
||||
/*
|
||||
* 1) Update checksum with the record header up to drr_checksum.
|
||||
* 2) Update checksum field in the record header.
|
||||
* 3) Update checksum with the checksum field in the record header.
|
||||
* 4) Update checksum with the contents of the payload.
|
||||
* 5) Write header and payload to fd.
|
||||
*/
|
||||
extern int
|
||||
dump_record(dmu_replay_record_t *drr, void *payload, size_t payload_len,
|
||||
zio_cksum_t *zc, int outfd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ZSTREAM_UTIL_H */
|
||||
@@ -7,6 +7,7 @@
|
||||
PHONY =
|
||||
AM_CPPFLAGS = \
|
||||
-include $(top_builddir)/zfs_config.h \
|
||||
-include $(top_srcdir)/include/sys/simd_config.h \
|
||||
-I$(top_builddir)/include \
|
||||
-I$(top_srcdir)/include \
|
||||
-I$(top_srcdir)/lib/libspl/include \
|
||||
|
||||
@@ -29,5 +29,8 @@ AC_DEFUN([ZFS_AC_KERNEL_FS_CONTEXT], [
|
||||
AC_DEFINE(HAVE_FS_CONTEXT, 1, [fs_context exists])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR([
|
||||
*** This kernel does not have `struct fs_context`. OpenZFS cannot be compiled.
|
||||
])
|
||||
])
|
||||
])
|
||||
@@ -37,6 +37,7 @@ dnl # only once the compilation can be done in parallel significantly
|
||||
dnl # speeding up the process.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
|
||||
ZFS_AC_KERNEL_SRC_SIMD
|
||||
ZFS_AC_KERNEL_SRC_TYPES
|
||||
ZFS_AC_KERNEL_SRC_OBJTOOL
|
||||
ZFS_AC_KERNEL_SRC_ACCESS_OK_TYPE
|
||||
@@ -161,6 +162,7 @@ dnl #
|
||||
dnl # Check results of kernel interface tests.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
|
||||
ZFS_AC_KERNEL_SIMD
|
||||
ZFS_AC_KERNEL_TYPES
|
||||
ZFS_AC_KERNEL_ACCESS_OK_TYPE
|
||||
ZFS_AC_KERNEL_OBJTOOL
|
||||
@@ -450,13 +452,6 @@ AC_DEFUN([ZFS_AC_KERNEL], [
|
||||
|
||||
AC_MSG_RESULT([$kernsrcver])
|
||||
|
||||
AX_COMPARE_VERSION([$kernsrcver], [ge], [$ZFS_META_KVER_MIN], [], [
|
||||
AC_MSG_ERROR([
|
||||
*** Cannot build against kernel version $kernsrcver.
|
||||
*** The minimum supported kernel version is $ZFS_META_KVER_MIN.
|
||||
])
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE([linux-experimental],
|
||||
AS_HELP_STRING([--enable-linux-experimental],
|
||||
[Allow building against some unsupported kernel versions]))
|
||||
@@ -898,7 +893,7 @@ AC_DEFUN([ZFS_LINUX_TEST_ERROR], [
|
||||
*** incompatible modifications.
|
||||
***
|
||||
*** ZFS Version: $ZFS_META_ALIAS
|
||||
*** Compatible Kernels: $ZFS_META_KVER_MIN - $ZFS_META_KVER_MAX
|
||||
*** Highest compatible kernel version: $ZFS_META_KVER_MAX
|
||||
])
|
||||
])
|
||||
|
||||
@@ -1069,7 +1064,7 @@ AC_DEFUN([ZFS_LINUX_REQUIRE_API], [
|
||||
*** APIs.
|
||||
***
|
||||
*** ZFS Version: $ZFS_META_ALIAS
|
||||
*** Compatible Kernels: $ZFS_META_KVER_MIN - $ZFS_META_KVER_MAX
|
||||
*** Highest compatible kernel version: $ZFS_META_KVER_MAX
|
||||
])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
dnl # SPDX-License-Identifier: CDDL-1.0
|
||||
dnl #
|
||||
dnl # Check whether assembler supports .cfi_negate_ra_state on AArch64.
|
||||
dnl #
|
||||
|
||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_TOOLCHAIN_CFI_PSEUDO_OP], [
|
||||
case "$host_cpu" in
|
||||
aarch64*)
|
||||
AC_CACHE_CHECK([whether assembler supports .cfi_negate_ra_state],
|
||||
[zfs_cv_as_cfi_pseudo_op], [
|
||||
cat > conftest.S <<_ACEOF
|
||||
.text
|
||||
conftest:
|
||||
.cfi_startproc
|
||||
.cfi_negate_ra_state
|
||||
ret
|
||||
.cfi_endproc
|
||||
_ACEOF
|
||||
if AC_TRY_COMMAND([$CC -c $CFLAGS $CPPFLAGS conftest.S -o conftest.o]) >/dev/null 2>&1; then
|
||||
zfs_cv_as_cfi_pseudo_op=yes
|
||||
else
|
||||
zfs_cv_as_cfi_pseudo_op=no
|
||||
fi
|
||||
rm -f conftest.S conftest.o
|
||||
])
|
||||
|
||||
AS_IF([test "x$zfs_cv_as_cfi_pseudo_op" = xyes], [
|
||||
AC_DEFINE([HAVE_AS_CFI_PSEUDO_OP], 1,
|
||||
[Define if your assembler supports .cfi_negate_ra_state.])
|
||||
])
|
||||
;;
|
||||
esac
|
||||
])
|
||||
@@ -2,579 +2,87 @@ dnl # SPDX-License-Identifier: CDDL-1.0
|
||||
dnl #
|
||||
dnl # Checks if host toolchain supports SIMD instructions
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_TOOLCHAIN_SIMD], [
|
||||
case "$host_cpu" in
|
||||
amd64 | x86_64 | x86 | i686)
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE2
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE3
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSSE3
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE4_1
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE4_2
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX2
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512F
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512CD
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512DQ
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512BW
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512IFMA
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512VBMI
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512PF
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512ER
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512VL
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AES
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_PCLMULQDQ
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_MOVBE
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_VAES
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_VPCLMULQDQ
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SHA512EXT
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVE
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVEOPT
|
||||
ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVES
|
||||
;;
|
||||
esac
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE
|
||||
dnl # Each invocation of ZFS_AC_TOOLCHAIN_SIMD_CHECK(name, asmsrc) creates
|
||||
dnl # two sets of macros:
|
||||
dnl # - ZFS_AC_TOOLCHAIN_SIMD_<name>
|
||||
dnl # - ZFS_AC_KERNEL_SRC_SIMD_<name> & ZFS_AC_KERNEL_SIMD_<name>
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports SSE])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("xorps %xmm0, %xmm1");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_DEFINE([HAVE_SSE], 1, [Define if host toolchain supports SSE])
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
dnl # These try to compile the given <asmsrc> in a __asm__ directive, using
|
||||
dnl # either the host or the kernel toolchains. Successful checks set
|
||||
dnl # HAVE_TOOLCHAIN_<name> or HAVE_KERNEL_<name>, respectively.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_SIMD_CHECK], [
|
||||
AC_DEFUN([ZFS_AC_TOOLCHAIN_SIMD_]m4_quote($1), [
|
||||
AC_MSG_CHECKING([whether host toolchain supports $1])
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[
|
||||
int main () {
|
||||
__asm__ __volatile__($2);
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_DEFINE([HAVE_TOOLCHAIN_$1], 1,
|
||||
[Define if host toolchain supports $1])
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE2
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE2], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports SSE2])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("pxor %xmm0, %xmm1");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_DEFINE([HAVE_SSE2], 1, [Define if host toolchain supports SSE2])
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_SIMD_]m4_quote($1), [
|
||||
ZFS_LINUX_TEST_SRC(
|
||||
[simd_]m4_quote(m4_translit([$1], [A-Z], [a-z])), [], [
|
||||
__asm__ __volatile__($2);
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE3
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE3], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports SSE3])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[
|
||||
int main()
|
||||
{
|
||||
char v[16];
|
||||
__asm__ __volatile__("lddqu %0,%%xmm0" :: "m"(v[0]));
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_DEFINE([HAVE_SSE3], 1, [Define if host toolchain supports SSE3])
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SIMD_]m4_quote($1), [
|
||||
AC_MSG_CHECKING([whether kernel toolchain supports $1])
|
||||
ZFS_LINUX_TEST_RESULT(
|
||||
[simd_]m4_quote(m4_translit([$1], [A-Z], [a-z])), [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_KERNEL_$1], 1,
|
||||
[Define if kernel toolchain supports $1])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl Stash the names of the new functions so we can execute them later.
|
||||
m4_pushdef([_zfs_ac_toolchain_simd_checks],
|
||||
[ZFS_AC_TOOLCHAIN_SIMD_]m4_quote($1))
|
||||
m4_pushdef([_zfs_ac_kernel_src_simd_checks],
|
||||
[ZFS_AC_KERNEL_SRC_SIMD_]m4_quote($1))
|
||||
m4_pushdef([_zfs_ac_kernel_simd_checks],
|
||||
[ZFS_AC_KERNEL_SIMD_]m4_quote($1))
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSSE3
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSSE3], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports SSSE3])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("pshufb %xmm0,%xmm1");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_DEFINE([HAVE_SSSE3], 1, [Define if host toolchain supports SSSE3])
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
dnl # Invoke the macros created by ZFS_AC_TOOLCHAIN_SIMD_CHECK.
|
||||
AC_DEFUN([ZFS_AC_TOOLCHAIN_SIMD], [
|
||||
m4_stack_foreach([_zfs_ac_toolchain_simd_checks], [m4_indir])
|
||||
])
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_SIMD], [
|
||||
m4_stack_foreach([_zfs_ac_kernel_src_simd_checks], [m4_indir])
|
||||
])
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SIMD], [
|
||||
m4_stack_foreach([_zfs_ac_kernel_simd_checks], [m4_indir])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE4_1
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE4_1], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports SSE4.1])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("pmaxsb %xmm0,%xmm1");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_DEFINE([HAVE_SSE4_1], 1, [Define if host toolchain supports SSE4.1])
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE4_2
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE4_2], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports SSE4.2])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("pcmpgtq %xmm0, %xmm1");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_DEFINE([HAVE_SSE4_2], 1, [Define if host toolchain supports SSE4.2])
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports AVX])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[
|
||||
int main()
|
||||
{
|
||||
char v[32];
|
||||
__asm__ __volatile__("vmovdqa %0,%%ymm0" :: "m"(v[0]));
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_AVX], 1, [Define if host toolchain supports AVX])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX2
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX2], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports AVX2])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("vpshufb %ymm0,%ymm1,%ymm2");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_AVX2], 1, [Define if host toolchain supports AVX2])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512F
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512F], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports AVX512F])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("vpandd %zmm0,%zmm1,%zmm2");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_AVX512F], 1, [Define if host toolchain supports AVX512F])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512CD
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512CD], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports AVX512CD])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("vplzcntd %zmm0,%zmm1");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_AVX512CD], 1, [Define if host toolchain supports AVX512CD])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512DQ
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512DQ], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports AVX512DQ])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("vandpd %zmm0,%zmm1,%zmm2");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_AVX512DQ], 1, [Define if host toolchain supports AVX512DQ])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512BW
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512BW], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports AVX512BW])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("vpshufb %zmm0,%zmm1,%zmm2");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_AVX512BW], 1, [Define if host toolchain supports AVX512BW])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512IFMA
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512IFMA], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports AVX512IFMA])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("vpmadd52luq %zmm0,%zmm1,%zmm2");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_AVX512IFMA], 1, [Define if host toolchain supports AVX512IFMA])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512VBMI
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512VBMI], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports AVX512VBMI])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("vpermb %zmm0,%zmm1,%zmm2");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_AVX512VBMI], 1, [Define if host toolchain supports AVX512VBMI])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512PF
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512PF], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports AVX512PF])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("vgatherpf0dps (%rsi,%zmm0,4){%k1}");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_AVX512PF], 1, [Define if host toolchain supports AVX512PF])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512ER
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512ER], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports AVX512ER])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("vexp2pd %zmm0,%zmm1");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_AVX512ER], 1, [Define if host toolchain supports AVX512ER])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512VL
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512VL], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports AVX512VL])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("vpabsq %zmm0,%zmm1");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_AVX512VL], 1, [Define if host toolchain supports AVX512VL])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AES
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AES], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports AES])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("aesenc %xmm0, %xmm1");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_AES], 1, [Define if host toolchain supports AES])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_PCLMULQDQ
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_PCLMULQDQ], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports PCLMULQDQ])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("pclmulqdq %0, %%xmm0, %%xmm1" :: "i"(0));
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_PCLMULQDQ], 1, [Define if host toolchain supports PCLMULQDQ])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_MOVBE
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_MOVBE], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports MOVBE])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("movbe 0(%eax), %eax");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_MOVBE], 1, [Define if host toolchain supports MOVBE])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_VAES
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_VAES], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports VAES])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("vaesenc %ymm0, %ymm1, %ymm0");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_VAES], 1, [Define if host toolchain supports VAES])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_VPCLMULQDQ
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_VPCLMULQDQ], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports VPCLMULQDQ])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("vpclmulqdq %0, %%ymm4, %%ymm3, %%ymm5" :: "i"(0));
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_VPCLMULQDQ], 1, [Define if host toolchain supports VPCLMULQDQ])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SHA512EXT
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SHA512EXT], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports SHA512])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
__asm__ __volatile__("vsha512msg2 %ymm5, %ymm6");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_SHA512EXT], 1, [Define if host toolchain supports SHA512])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVE
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVE], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports XSAVE])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
char b[4096] __attribute__ ((aligned (64)));
|
||||
__asm__ __volatile__("xsave %[b]\n" : : [b] "m" (*b) : "memory");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_XSAVE], 1, [Define if host toolchain supports XSAVE])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVEOPT
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVEOPT], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports XSAVEOPT])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
char b[4096] __attribute__ ((aligned (64)));
|
||||
__asm__ __volatile__("xsaveopt %[b]\n" : : [b] "m" (*b) : "memory");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_XSAVEOPT], 1, [Define if host toolchain supports XSAVEOPT])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVES
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVES], [
|
||||
AC_MSG_CHECKING([whether host toolchain supports XSAVES])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
[
|
||||
int main()
|
||||
{
|
||||
char b[4096] __attribute__ ((aligned (64)));
|
||||
__asm__ __volatile__("xsaves %[b]\n" : : [b] "m" (*b) : "memory");
|
||||
return (0);
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_XSAVES], 1, [Define if host toolchain supports XSAVES])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
dnl # Instruction sets to test
|
||||
ZFS_AC_SIMD_CHECK([SSE2], ["pxor %xmm0, %xmm1"])
|
||||
ZFS_AC_SIMD_CHECK([SSSE3], ["pshufb %xmm0, %xmm1"])
|
||||
ZFS_AC_SIMD_CHECK([SSE4_1], ["pmaxsb %xmm0, %xmm1"])
|
||||
ZFS_AC_SIMD_CHECK([AVX], ["vmovdqa %ymm0, %ymm1"])
|
||||
ZFS_AC_SIMD_CHECK([AVX2], ["vpshufb %ymm0, %ymm1, %ymm2"])
|
||||
ZFS_AC_SIMD_CHECK([AVX512F], ["vpandd %zmm0, %zmm1, %zmm2"])
|
||||
ZFS_AC_SIMD_CHECK([AVX512BW], ["vpshufb %zmm0, %zmm1, %zmm2"])
|
||||
ZFS_AC_SIMD_CHECK([AVX512VL], ["vpabsq %zmm0,%zmm1"])
|
||||
ZFS_AC_SIMD_CHECK([AES], ["aesenc %xmm0, %xmm1"])
|
||||
ZFS_AC_SIMD_CHECK([PCLMULQDQ], ["pclmulqdq %0, %%xmm0, %%xmm1" :: "i"(0)])
|
||||
ZFS_AC_SIMD_CHECK([MOVBE], ["movbe 0(%eax), %eax"])
|
||||
ZFS_AC_SIMD_CHECK([VAES], ["vaesenc %ymm0, %ymm1, %ymm0"])
|
||||
ZFS_AC_SIMD_CHECK([VPCLMULQDQ], ["vpclmulqdq %0, %%ymm4, %%ymm3, %%ymm5" :: "i"(0)])
|
||||
ZFS_AC_SIMD_CHECK([SHA512EXT], ["vsha512msg2 %ymm5, %ymm6"])
|
||||
ZFS_AC_SIMD_CHECK([XSAVE], ["xsave 0"])
|
||||
ZFS_AC_SIMD_CHECK([XSAVEOPT], ["xsaveopt 0"])
|
||||
ZFS_AC_SIMD_CHECK([XSAVES], ["xsaves 0"])
|
||||
@@ -0,0 +1,27 @@
|
||||
dnl # SPDX-License-Identifier: CDDL-1.0
|
||||
dnl #
|
||||
dnl # Check for mount_setattr() and struct mount_attr availability
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_USER_MOUNT_SETATTR], [
|
||||
AC_CHECK_FUNC([mount_setattr], [
|
||||
AC_MSG_CHECKING([for struct mount_attr])
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
#include <sys/mount.h>
|
||||
]], [[
|
||||
struct mount_attr attr = {
|
||||
.attr_set = MOUNT_ATTR_RDONLY,
|
||||
.attr_clr = MOUNT_ATTR_NOEXEC,
|
||||
};
|
||||
(void) attr;
|
||||
]])
|
||||
], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_MOUNT_SETATTR], [1],
|
||||
[mount_setattr() and struct mount_attr
|
||||
are available])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
])
|
||||
@@ -15,6 +15,7 @@ AC_DEFUN([ZFS_AC_CONFIG_USER_STATX], [
|
||||
AC_MSG_CHECKING([for STATX_MNT_ID])
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
#define _GNU_SOURCE
|
||||
#include <sys/stat.h>
|
||||
]], [[
|
||||
struct statx stx;
|
||||
|
||||
@@ -20,6 +20,7 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [
|
||||
ZFS_AC_CONFIG_USER_LIBUUID
|
||||
ZFS_AC_CONFIG_USER_LIBBLKID
|
||||
ZFS_AC_CONFIG_USER_STATX
|
||||
ZFS_AC_CONFIG_USER_MOUNT_SETATTR
|
||||
])
|
||||
ZFS_AC_CONFIG_USER_LIBTIRPC
|
||||
ZFS_AC_CONFIG_USER_LIBCRYPTO
|
||||
|
||||
@@ -265,7 +265,8 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
|
||||
ZFS_AC_CONFIG_ALWAYS_KERNEL_CC_NO_IPA_SRA
|
||||
ZFS_AC_CONFIG_ALWAYS_CC_ASAN
|
||||
ZFS_AC_CONFIG_ALWAYS_CC_UBSAN
|
||||
ZFS_AC_CONFIG_ALWAYS_TOOLCHAIN_SIMD
|
||||
ZFS_AC_TOOLCHAIN_SIMD
|
||||
ZFS_AC_CONFIG_ALWAYS_TOOLCHAIN_CFI_PSEUDO_OP
|
||||
ZFS_AC_CONFIG_ALWAYS_SYSTEM
|
||||
ZFS_AC_CONFIG_ALWAYS_ARCH
|
||||
ZFS_AC_CONFIG_CHECK_ARCH_VAR
|
||||
|
||||
@@ -42,8 +42,10 @@ usr/bin/dbufstat usr/sbin
|
||||
usr/bin/zilstat
|
||||
usr/share/zfs/compatibility.d/
|
||||
usr/share/bash-completion/completions
|
||||
usr/share/man/man1/zarcsummary.1
|
||||
usr/share/man/man1/zarcstat.1
|
||||
usr/share/man/man1/zhack.1
|
||||
usr/share/man/man1/zilstat.1
|
||||
usr/share/man/man1/zvol_wait.1
|
||||
usr/share/man/man5/
|
||||
usr/share/man/man8/fsck.zfs.8
|
||||
|
||||
@@ -82,6 +82,7 @@ COMMON_H = \
|
||||
sys/sa.h \
|
||||
sys/sa_impl.h \
|
||||
sys/sha2.h \
|
||||
sys/simd_config.h \
|
||||
sys/skein.h \
|
||||
sys/spa.h \
|
||||
sys/spa_checkpoint.h \
|
||||
|
||||
@@ -766,6 +766,8 @@ _LIBZFS_H void libzfs_add_handle(get_all_cb_t *, zfs_handle_t *);
|
||||
_LIBZFS_H int zfs_create(libzfs_handle_t *, const char *, zfs_type_t,
|
||||
nvlist_t *);
|
||||
_LIBZFS_H int zfs_create_ancestors(libzfs_handle_t *, const char *);
|
||||
_LIBZFS_H int zfs_create_ancestors_props(libzfs_handle_t *, const char *,
|
||||
nvlist_t *);
|
||||
_LIBZFS_H int zfs_destroy(zfs_handle_t *, boolean_t);
|
||||
_LIBZFS_H int zfs_destroy_snaps(zfs_handle_t *, char *, boolean_t);
|
||||
_LIBZFS_H int zfs_destroy_snaps_nvl(libzfs_handle_t *, nvlist_t *, boolean_t);
|
||||
@@ -844,6 +846,9 @@ typedef struct sendflags {
|
||||
|
||||
/* stream represents a partially received dataset */
|
||||
boolean_t saved;
|
||||
|
||||
/* allow sending datasets with props, without preserving encryption */
|
||||
boolean_t no_preserve_encryption;
|
||||
} sendflags_t;
|
||||
|
||||
typedef boolean_t (snapfilter_cb_t)(zfs_handle_t *, void *);
|
||||
|
||||
@@ -125,7 +125,7 @@ _LIBZFS_CORE_H int lzc_send_space(const char *, const char *,
|
||||
_LIBZFS_CORE_H int lzc_send_space_resume_redacted(const char *, const char *,
|
||||
enum lzc_send_flags, uint64_t, uint64_t, uint64_t, const char *,
|
||||
int, uint64_t *);
|
||||
_LIBZFS_CORE_H uint64_t lzc_send_progress(int);
|
||||
_LIBZFS_CORE_H int lzc_send_progress(const char *, int, uint64_t *, uint64_t *);
|
||||
|
||||
_LIBZFS_CORE_H boolean_t lzc_exists(const char *);
|
||||
|
||||
|
||||
@@ -167,7 +167,8 @@ _LIBZUTIL_H void zfs_niceraw(uint64_t, char *, size_t);
|
||||
#define nicenum(num, buf, size) zfs_nicenum(num, buf, size)
|
||||
#define NN_NUMBUF_SZ (6)
|
||||
|
||||
_LIBZUTIL_H void zpool_dump_ddt(const ddt_stat_t *, const ddt_histogram_t *);
|
||||
_LIBZUTIL_H void zpool_dump_ddt(const ddt_stat_t *, const ddt_histogram_t *,
|
||||
boolean_t parsable);
|
||||
_LIBZUTIL_H int zpool_history_unpack(char *, uint64_t, uint64_t *, nvlist_t ***,
|
||||
uint_t *);
|
||||
_LIBZUTIL_H void fsleep(float sec);
|
||||
|
||||
@@ -315,19 +315,19 @@ kfpu_begin(void)
|
||||
* FPU state to be correctly preserved and restored.
|
||||
*/
|
||||
uint8_t *state = zfs_kfpu_fpregs[smp_processor_id()];
|
||||
#if defined(HAVE_XSAVES)
|
||||
#if HAVE_SIMD(XSAVES)
|
||||
if (static_cpu_has(X86_FEATURE_XSAVES)) {
|
||||
kfpu_do_xsave("xsaves", state, ~XFEATURE_MASK_XTILE);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_XSAVEOPT)
|
||||
#if HAVE_SIMD(XSAVEOPT)
|
||||
if (static_cpu_has(X86_FEATURE_XSAVEOPT)) {
|
||||
kfpu_do_xsave("xsaveopt", state, ~XFEATURE_MASK_XTILE);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_XSAVE)
|
||||
#if HAVE_SIMD(XSAVE)
|
||||
if (static_cpu_has(X86_FEATURE_XSAVE)) {
|
||||
kfpu_do_xsave("xsave", state, ~XFEATURE_MASK_XTILE);
|
||||
return;
|
||||
@@ -380,13 +380,13 @@ static inline void
|
||||
kfpu_end(void)
|
||||
{
|
||||
uint8_t *state = zfs_kfpu_fpregs[smp_processor_id()];
|
||||
#if defined(HAVE_XSAVES)
|
||||
#if HAVE_SIMD(XSAVES)
|
||||
if (static_cpu_has(X86_FEATURE_XSAVES)) {
|
||||
kfpu_do_xrstor("xrstors", state, ~XFEATURE_MASK_XTILE);
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_XSAVE)
|
||||
#if HAVE_SIMD(XSAVE)
|
||||
if (static_cpu_has(X86_FEATURE_XSAVE)) {
|
||||
kfpu_do_xrstor("xrstor", state, ~XFEATURE_MASK_XTILE);
|
||||
goto out;
|
||||
@@ -440,15 +440,9 @@ zfs_xgetbv(uint32_t index)
|
||||
static inline boolean_t
|
||||
__simd_state_enabled(const uint64_t state)
|
||||
{
|
||||
boolean_t has_osxsave;
|
||||
uint64_t xcr0;
|
||||
|
||||
#if defined(X86_FEATURE_OSXSAVE)
|
||||
has_osxsave = !!boot_cpu_has(X86_FEATURE_OSXSAVE);
|
||||
#else
|
||||
has_osxsave = B_FALSE;
|
||||
#endif
|
||||
if (!has_osxsave)
|
||||
if (!boot_cpu_has(X86_FEATURE_OSXSAVE))
|
||||
return (B_FALSE);
|
||||
|
||||
xcr0 = zfs_xgetbv(0);
|
||||
@@ -539,11 +533,7 @@ zfs_avx2_available(void)
|
||||
static inline boolean_t
|
||||
zfs_bmi1_available(void)
|
||||
{
|
||||
#if defined(X86_FEATURE_BMI1)
|
||||
return (!!boot_cpu_has(X86_FEATURE_BMI1));
|
||||
#else
|
||||
return (B_FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -552,11 +542,7 @@ zfs_bmi1_available(void)
|
||||
static inline boolean_t
|
||||
zfs_bmi2_available(void)
|
||||
{
|
||||
#if defined(X86_FEATURE_BMI2)
|
||||
return (!!boot_cpu_has(X86_FEATURE_BMI2));
|
||||
#else
|
||||
return (B_FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -565,11 +551,7 @@ zfs_bmi2_available(void)
|
||||
static inline boolean_t
|
||||
zfs_aes_available(void)
|
||||
{
|
||||
#if defined(X86_FEATURE_AES)
|
||||
return (!!boot_cpu_has(X86_FEATURE_AES));
|
||||
#else
|
||||
return (B_FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -578,11 +560,7 @@ zfs_aes_available(void)
|
||||
static inline boolean_t
|
||||
zfs_pclmulqdq_available(void)
|
||||
{
|
||||
#if defined(X86_FEATURE_PCLMULQDQ)
|
||||
return (!!boot_cpu_has(X86_FEATURE_PCLMULQDQ));
|
||||
#else
|
||||
return (B_FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -591,11 +569,7 @@ zfs_pclmulqdq_available(void)
|
||||
static inline boolean_t
|
||||
zfs_movbe_available(void)
|
||||
{
|
||||
#if defined(X86_FEATURE_MOVBE)
|
||||
return (!!boot_cpu_has(X86_FEATURE_MOVBE));
|
||||
#else
|
||||
return (B_FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -604,11 +578,7 @@ zfs_movbe_available(void)
|
||||
static inline boolean_t
|
||||
zfs_vaes_available(void)
|
||||
{
|
||||
#if defined(X86_FEATURE_VAES)
|
||||
return (!!boot_cpu_has(X86_FEATURE_VAES));
|
||||
#else
|
||||
return (B_FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -617,15 +587,12 @@ zfs_vaes_available(void)
|
||||
static inline boolean_t
|
||||
zfs_vpclmulqdq_available(void)
|
||||
{
|
||||
#if defined(X86_FEATURE_VPCLMULQDQ)
|
||||
return (!!boot_cpu_has(X86_FEATURE_VPCLMULQDQ));
|
||||
#else
|
||||
return (B_FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if SHA512 instructions are available
|
||||
* Kernel added X86_FEATURE_SHA512 in 6.13 (torvalds/linux@a0423af92cb3)
|
||||
*/
|
||||
static inline boolean_t
|
||||
zfs_sha512ext_available(void)
|
||||
@@ -643,11 +610,7 @@ zfs_sha512ext_available(void)
|
||||
static inline boolean_t
|
||||
zfs_shani_available(void)
|
||||
{
|
||||
#if defined(X86_FEATURE_SHA_NI)
|
||||
return (!!boot_cpu_has(X86_FEATURE_SHA_NI));
|
||||
#else
|
||||
return (B_FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -662,7 +625,7 @@ zfs_shani_available(void)
|
||||
* AVX512DQ Double-word and Quadword Instructions
|
||||
* AVX512VL Vector Length Extensions
|
||||
*
|
||||
* AVX512IFMA Integer Fused Multiply Add (Not supported by kernel 4.4)
|
||||
* AVX512IFMA Integer Fused Multiply Add
|
||||
* AVX512VBMI Vector Byte Manipulation Instructions
|
||||
*/
|
||||
|
||||
@@ -672,12 +635,7 @@ zfs_shani_available(void)
|
||||
static inline boolean_t
|
||||
zfs_avx512f_available(void)
|
||||
{
|
||||
boolean_t has_avx512 = B_FALSE;
|
||||
|
||||
#if defined(X86_FEATURE_AVX512F)
|
||||
has_avx512 = !!boot_cpu_has(X86_FEATURE_AVX512F);
|
||||
#endif
|
||||
return (has_avx512 && __zmm_enabled());
|
||||
return (boot_cpu_has(X86_FEATURE_AVX512F) && __zmm_enabled());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -686,13 +644,7 @@ zfs_avx512f_available(void)
|
||||
static inline boolean_t
|
||||
zfs_avx512cd_available(void)
|
||||
{
|
||||
boolean_t has_avx512 = B_FALSE;
|
||||
|
||||
#if defined(X86_FEATURE_AVX512CD)
|
||||
has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
|
||||
boot_cpu_has(X86_FEATURE_AVX512CD);
|
||||
#endif
|
||||
return (has_avx512 && __zmm_enabled());
|
||||
return (zfs_avx512f_available() && boot_cpu_has(X86_FEATURE_AVX512F));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -701,13 +653,7 @@ zfs_avx512cd_available(void)
|
||||
static inline boolean_t
|
||||
zfs_avx512er_available(void)
|
||||
{
|
||||
boolean_t has_avx512 = B_FALSE;
|
||||
|
||||
#if defined(X86_FEATURE_AVX512ER)
|
||||
has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
|
||||
boot_cpu_has(X86_FEATURE_AVX512ER);
|
||||
#endif
|
||||
return (has_avx512 && __zmm_enabled());
|
||||
return (zfs_avx512f_available() && boot_cpu_has(X86_FEATURE_AVX512ER));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -716,13 +662,7 @@ zfs_avx512er_available(void)
|
||||
static inline boolean_t
|
||||
zfs_avx512pf_available(void)
|
||||
{
|
||||
boolean_t has_avx512 = B_FALSE;
|
||||
|
||||
#if defined(X86_FEATURE_AVX512PF)
|
||||
has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
|
||||
boot_cpu_has(X86_FEATURE_AVX512PF);
|
||||
#endif
|
||||
return (has_avx512 && __zmm_enabled());
|
||||
return (zfs_avx512f_available() && boot_cpu_has(X86_FEATURE_AVX512PF));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -731,14 +671,7 @@ zfs_avx512pf_available(void)
|
||||
static inline boolean_t
|
||||
zfs_avx512bw_available(void)
|
||||
{
|
||||
boolean_t has_avx512 = B_FALSE;
|
||||
|
||||
#if defined(X86_FEATURE_AVX512BW)
|
||||
has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
|
||||
boot_cpu_has(X86_FEATURE_AVX512BW);
|
||||
#endif
|
||||
|
||||
return (has_avx512 && __zmm_enabled());
|
||||
return (zfs_avx512f_available() && boot_cpu_has(X86_FEATURE_AVX512BW));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -747,13 +680,7 @@ zfs_avx512bw_available(void)
|
||||
static inline boolean_t
|
||||
zfs_avx512dq_available(void)
|
||||
{
|
||||
boolean_t has_avx512 = B_FALSE;
|
||||
|
||||
#if defined(X86_FEATURE_AVX512DQ)
|
||||
has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
|
||||
boot_cpu_has(X86_FEATURE_AVX512DQ);
|
||||
#endif
|
||||
return (has_avx512 && __zmm_enabled());
|
||||
return (zfs_avx512f_available() && boot_cpu_has(X86_FEATURE_AVX512DQ));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -762,13 +689,7 @@ zfs_avx512dq_available(void)
|
||||
static inline boolean_t
|
||||
zfs_avx512vl_available(void)
|
||||
{
|
||||
boolean_t has_avx512 = B_FALSE;
|
||||
|
||||
#if defined(X86_FEATURE_AVX512VL)
|
||||
has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
|
||||
boot_cpu_has(X86_FEATURE_AVX512VL);
|
||||
#endif
|
||||
return (has_avx512 && __zmm_enabled());
|
||||
return (zfs_avx512f_available() && boot_cpu_has(X86_FEATURE_AVX512VL));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -777,13 +698,8 @@ zfs_avx512vl_available(void)
|
||||
static inline boolean_t
|
||||
zfs_avx512ifma_available(void)
|
||||
{
|
||||
boolean_t has_avx512 = B_FALSE;
|
||||
|
||||
#if defined(X86_FEATURE_AVX512IFMA)
|
||||
has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
|
||||
boot_cpu_has(X86_FEATURE_AVX512IFMA);
|
||||
#endif
|
||||
return (has_avx512 && __zmm_enabled());
|
||||
return (zfs_avx512f_available() &&
|
||||
boot_cpu_has(X86_FEATURE_AVX512IFMA));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -792,13 +708,8 @@ zfs_avx512ifma_available(void)
|
||||
static inline boolean_t
|
||||
zfs_avx512vbmi_available(void)
|
||||
{
|
||||
boolean_t has_avx512 = B_FALSE;
|
||||
|
||||
#if defined(X86_FEATURE_AVX512VBMI)
|
||||
has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
|
||||
boot_cpu_has(X86_FEATURE_AVX512VBMI);
|
||||
#endif
|
||||
return (has_avx512 && __zmm_enabled());
|
||||
return (zfs_avx512f_available() &&
|
||||
boot_cpu_has(X86_FEATURE_AVX512VBMI));
|
||||
}
|
||||
|
||||
#endif /* defined(__x86) */
|
||||
|
||||
@@ -46,6 +46,10 @@ extern "C" {
|
||||
* and each of the states has two types: data and metadata.
|
||||
*/
|
||||
#define L2ARC_FEED_TYPES 4
|
||||
#define L2ARC_MFU_META 0
|
||||
#define L2ARC_MRU_META 1
|
||||
#define L2ARC_MFU_DATA 2
|
||||
#define L2ARC_MRU_DATA 3
|
||||
|
||||
/*
|
||||
* L2ARC state and statistics for persistent marker management.
|
||||
@@ -56,10 +60,19 @@ typedef struct l2arc_info {
|
||||
uint64_t l2arc_total_capacity; /* total L2ARC capacity */
|
||||
uint64_t l2arc_smallest_capacity; /* smallest device capacity */
|
||||
/*
|
||||
* Per-device thread coordination for sublist processing
|
||||
* Per-device thread coordination for sublist processing.
|
||||
* reset: flags sublist marker for lazy reset to tail.
|
||||
*/
|
||||
boolean_t *l2arc_sublist_busy[L2ARC_FEED_TYPES];
|
||||
kmutex_t l2arc_sublist_lock; /* protects busy flags */
|
||||
boolean_t *l2arc_sublist_reset[L2ARC_FEED_TYPES];
|
||||
kmutex_t l2arc_sublist_lock; /* protects busy/reset flags */
|
||||
/*
|
||||
* Cumulative bytes scanned per pass since marker reset.
|
||||
* Limits how far persistent markers advance from tail
|
||||
* before resetting, based on % of state size.
|
||||
*/
|
||||
uint64_t l2arc_ext_scanned[L2ARC_FEED_TYPES];
|
||||
int l2arc_next_sublist[L2ARC_FEED_TYPES]; /* round-robin */
|
||||
} l2arc_info_t;
|
||||
|
||||
/*
|
||||
@@ -456,6 +469,12 @@ typedef struct l2arc_dev {
|
||||
boolean_t l2ad_thread_exit; /* signal thread exit */
|
||||
kmutex_t l2ad_feed_thr_lock; /* thread sleep/wake */
|
||||
kcondvar_t l2ad_feed_cv; /* thread wakeup cv */
|
||||
/*
|
||||
* Consecutive cycles where metadata filled write budget
|
||||
* while data passes got nothing written. Used to detect
|
||||
* monopolization and skip metadata to give data a chance.
|
||||
*/
|
||||
uint64_t l2ad_meta_cycles;
|
||||
} l2arc_dev_t;
|
||||
|
||||
/*
|
||||
|
||||
@@ -275,9 +275,90 @@ typedef enum {
|
||||
ZPOOL_PROP_LAST_SCRUBBED_TXG,
|
||||
ZPOOL_PROP_DEDUPUSED,
|
||||
ZPOOL_PROP_DEDUPSAVED,
|
||||
ZPOOL_PROP_AVAILABLE,
|
||||
ZPOOL_PROP_USABLE,
|
||||
ZPOOL_PROP_USED,
|
||||
ZPOOL_PROP_NORMAL_SIZE,
|
||||
ZPOOL_PROP_NORMAL_CAPACITY,
|
||||
ZPOOL_PROP_NORMAL_FREE,
|
||||
ZPOOL_PROP_NORMAL_ALLOCATED,
|
||||
ZPOOL_PROP_NORMAL_AVAILABLE,
|
||||
ZPOOL_PROP_NORMAL_USABLE,
|
||||
ZPOOL_PROP_NORMAL_USED,
|
||||
ZPOOL_PROP_NORMAL_EXPANDSZ,
|
||||
ZPOOL_PROP_NORMAL_FRAGMENTATION,
|
||||
ZPOOL_PROP_SPECIAL_SIZE,
|
||||
ZPOOL_PROP_SPECIAL_CAPACITY,
|
||||
ZPOOL_PROP_SPECIAL_FREE,
|
||||
ZPOOL_PROP_SPECIAL_ALLOCATED,
|
||||
ZPOOL_PROP_SPECIAL_AVAILABLE,
|
||||
ZPOOL_PROP_SPECIAL_USABLE,
|
||||
ZPOOL_PROP_SPECIAL_USED,
|
||||
ZPOOL_PROP_SPECIAL_EXPANDSZ,
|
||||
ZPOOL_PROP_SPECIAL_FRAGMENTATION,
|
||||
ZPOOL_PROP_DEDUP_SIZE,
|
||||
ZPOOL_PROP_DEDUP_CAPACITY,
|
||||
ZPOOL_PROP_DEDUP_FREE,
|
||||
ZPOOL_PROP_DEDUP_ALLOCATED,
|
||||
ZPOOL_PROP_DEDUP_AVAILABLE,
|
||||
ZPOOL_PROP_DEDUP_USABLE,
|
||||
ZPOOL_PROP_DEDUP_USED,
|
||||
ZPOOL_PROP_DEDUP_EXPANDSZ,
|
||||
ZPOOL_PROP_DEDUP_FRAGMENTATION,
|
||||
ZPOOL_PROP_LOG_SIZE,
|
||||
ZPOOL_PROP_LOG_CAPACITY,
|
||||
ZPOOL_PROP_LOG_FREE,
|
||||
ZPOOL_PROP_LOG_ALLOCATED,
|
||||
ZPOOL_PROP_LOG_AVAILABLE,
|
||||
ZPOOL_PROP_LOG_USABLE,
|
||||
ZPOOL_PROP_LOG_USED,
|
||||
ZPOOL_PROP_LOG_EXPANDSZ,
|
||||
ZPOOL_PROP_LOG_FRAGMENTATION,
|
||||
ZPOOL_PROP_ELOG_SIZE,
|
||||
ZPOOL_PROP_ELOG_CAPACITY,
|
||||
ZPOOL_PROP_ELOG_FREE,
|
||||
ZPOOL_PROP_ELOG_ALLOCATED,
|
||||
ZPOOL_PROP_ELOG_AVAILABLE,
|
||||
ZPOOL_PROP_ELOG_USABLE,
|
||||
ZPOOL_PROP_ELOG_USED,
|
||||
ZPOOL_PROP_ELOG_EXPANDSZ,
|
||||
ZPOOL_PROP_ELOG_FRAGMENTATION,
|
||||
ZPOOL_PROP_SELOG_SIZE,
|
||||
ZPOOL_PROP_SELOG_CAPACITY,
|
||||
ZPOOL_PROP_SELOG_FREE,
|
||||
ZPOOL_PROP_SELOG_ALLOCATED,
|
||||
ZPOOL_PROP_SELOG_AVAILABLE,
|
||||
ZPOOL_PROP_SELOG_USABLE,
|
||||
ZPOOL_PROP_SELOG_USED,
|
||||
ZPOOL_PROP_SELOG_EXPANDSZ,
|
||||
ZPOOL_PROP_SELOG_FRAGMENTATION,
|
||||
ZPOOL_NUM_PROPS
|
||||
} zpool_prop_t;
|
||||
|
||||
/* Offsets for metaslab class properties. */
|
||||
typedef enum {
|
||||
ZPOOL_MC_PROP_SIZE,
|
||||
ZPOOL_MC_PROP_CAPACITY,
|
||||
ZPOOL_MC_PROP_FREE,
|
||||
ZPOOL_MC_PROP_ALLOCATED,
|
||||
ZPOOL_MC_PROP_AVAILABLE,
|
||||
ZPOOL_MC_PROP_USABLE,
|
||||
ZPOOL_MC_PROP_USED,
|
||||
ZPOOL_MC_PROP_EXPANDSZ,
|
||||
ZPOOL_MC_PROP_FRAGMENTATION,
|
||||
ZPOOL_NUM_MC_PROPS
|
||||
} zpool_mc_prop_t;
|
||||
|
||||
/* Offsets for metaslab class property groups. */
|
||||
typedef enum {
|
||||
ZPOOL_MC_PROPS_NORMAL = ZPOOL_PROP_NORMAL_SIZE,
|
||||
ZPOOL_MC_PROPS_SPECIAL = ZPOOL_PROP_SPECIAL_SIZE,
|
||||
ZPOOL_MC_PROPS_DEDUP = ZPOOL_PROP_DEDUP_SIZE,
|
||||
ZPOOL_MC_PROPS_LOG = ZPOOL_PROP_LOG_SIZE,
|
||||
ZPOOL_MC_PROPS_ELOG = ZPOOL_PROP_ELOG_SIZE,
|
||||
ZPOOL_MC_PROPS_SELOG = ZPOOL_PROP_SELOG_SIZE,
|
||||
} zpool_mc_props_t;
|
||||
|
||||
/* Small enough to not hog a whole line of printout in zpool(8). */
|
||||
#define ZPROP_MAX_COMMENT 32
|
||||
#define ZPROP_BOOLEAN_NA 2
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* 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) 2026, TrueNAS.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_SIMD_CONFIG_H
|
||||
#define _SYS_SIMD_CONFIG_H
|
||||
|
||||
/*
|
||||
* Goal: a HAVE_SIMD(x) macro that expands to either 1 or 0 depending on
|
||||
* the availabilty of that extension on the wanted toolchain.
|
||||
*
|
||||
* We need to allow the following:
|
||||
* - #define HAVE_TOOLCHAIN_AVX 1 (zfs_config.h, detected by configure)
|
||||
* - #undef HAVE_TOOLCHAIN_AVX (zfs_config.h, probed but not detected)
|
||||
* - -DHAVE_TOOLCHAIN_AVX (Makefile.bsd)
|
||||
*
|
||||
* For completeness, we also allow disabling by defined HAVE_TOOLCHAIN_AVX=0.
|
||||
*
|
||||
* The "obvious" implementation of this would be a macro that includes
|
||||
* defined(...) in its expansion, but unfortunately that is not portable, and
|
||||
* can produce compiler warnings (see -Wexpansion-to-defined). So we need to
|
||||
* build our own version.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 1. Expand incoming token to its defined value, if anything:
|
||||
* eg HAVE_SIMD(AVX)
|
||||
* -> _zfs_deftrue(HAVE_TOOLCHAIN_AVX)
|
||||
* or -> __zfs_deftrue() (HAVE_TOOLCHAIN_AVX defined)
|
||||
* or -> __zfs_deftrue(1) (HAVE_TOOLCHAIN_AVX = 1)
|
||||
* -> __zfs_deftrue(0) (HAVE_TOOLCHAIN_AVX = 0)
|
||||
* or -> __zfs_deftrue(HAVE_TOOLCHAIN_AVX) (HAVE_TOOLCHAIN_AVX undef)
|
||||
*/
|
||||
#define _zfs_deftrue(x) __zfs_deftrue(x)
|
||||
|
||||
/*
|
||||
* 2. Replace know values with a token that we control:
|
||||
* __zfs_deftrue()
|
||||
* -> ___zfs_deftrue(___zfs_deftrue_arg_)
|
||||
* __zfs_deftrue(1)
|
||||
* -> ___zfs_deftrue(___zfs_deftrue_arg_1)
|
||||
* __zfs_deftrue(0)
|
||||
* -> ___zfs_deftrue(___zfs_deftrue_arg_0)
|
||||
* __zfs_deftrue(HAVE_TOOLCHAIN_AVX)
|
||||
* -> ___zfs_deftrue(___zfs_deftrue_arg_HAVE_TOOLCHAIN_AVX)
|
||||
*/
|
||||
#define __zfs_deftrue(v) ___zfs_deftrue(___zfs_deftrue_arg_##v)
|
||||
|
||||
/*
|
||||
* 3. Expand the incoming token into positional parameters for the next call:
|
||||
* ___zfs_deftrue(___zfs_deftrue_arg_0)
|
||||
* -> ____zfs_deftrue(0, 0, 0)
|
||||
* ___zfs_deftrue(___zfs_deftrue_arg_1)
|
||||
* -> ____zfs_deftrue(0, 1, 0)
|
||||
* ___zfs_deftrue(___zfs_deftrue_arg_HAVE_TOOLCHAIN_AVX)
|
||||
* -> ____zfs_deftrue(___zfs_deftrue_arg_HAVE_TOOLCHAIN_AVX, 0)
|
||||
*/
|
||||
#define ___zfs_deftrue_arg_ 0, 1
|
||||
#define ___zfs_deftrue_arg_1 0, 1
|
||||
#define ___zfs_deftrue_arg_0 0, 0
|
||||
#define ___zfs_deftrue(t, ...) ____zfs_deftrue(t, 0)
|
||||
|
||||
/*
|
||||
* 4. Emit the second argument, either the original value or the default 0.
|
||||
* ____zfs_deftrue(0, 0, 0) -> 0
|
||||
* ____zfs_deftrue(0, 1, 0) -> 1
|
||||
* ____zfs_deftrue(___zfs_deftrue_arg_HAVE_TOOLCHAIN_AVX, 0) -> 0
|
||||
*/
|
||||
#define ____zfs_deftrue(_n, v, ...) v
|
||||
|
||||
/*
|
||||
* The Linux kernel requires a specific toolchain. Everything else uses the
|
||||
* regular compiler toolchain.
|
||||
*/
|
||||
#if defined(_KERNEL) && defined(__linux__)
|
||||
#define HAVE_SIMD(ext) _zfs_deftrue(HAVE_KERNEL_##ext)
|
||||
#else
|
||||
#define HAVE_SIMD(ext) _zfs_deftrue(HAVE_TOOLCHAIN_##ext)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1082,6 +1082,7 @@ extern uint64_t spa_guid(spa_t *spa);
|
||||
extern uint64_t spa_load_guid(spa_t *spa);
|
||||
extern uint64_t spa_last_synced_txg(spa_t *spa);
|
||||
extern uint64_t spa_first_txg(spa_t *spa);
|
||||
extern uint64_t spa_open_txg(spa_t *spa);
|
||||
extern uint64_t spa_syncing_txg(spa_t *spa);
|
||||
extern uint64_t spa_final_dirty_txg(spa_t *spa);
|
||||
extern uint64_t spa_version(spa_t *spa);
|
||||
|
||||
@@ -172,19 +172,19 @@ typedef struct reflow_node {
|
||||
extern const raidz_impl_ops_t vdev_raidz_scalar_impl;
|
||||
extern boolean_t raidz_will_scalar_work(void);
|
||||
|
||||
#if defined(__x86_64) && defined(HAVE_SSE2) /* only x86_64 for now */
|
||||
#if defined(__x86_64) && HAVE_SIMD(SSE2) /* only x86_64 for now */
|
||||
extern const raidz_impl_ops_t vdev_raidz_sse2_impl;
|
||||
#endif
|
||||
#if defined(__x86_64) && defined(HAVE_SSSE3) /* only x86_64 for now */
|
||||
#if defined(__x86_64) && HAVE_SIMD(SSSE3) /* only x86_64 for now */
|
||||
extern const raidz_impl_ops_t vdev_raidz_ssse3_impl;
|
||||
#endif
|
||||
#if defined(__x86_64) && defined(HAVE_AVX2) /* only x86_64 for now */
|
||||
#if defined(__x86_64) && HAVE_SIMD(AVX2) /* only x86_64 for now */
|
||||
extern const raidz_impl_ops_t vdev_raidz_avx2_impl;
|
||||
#endif
|
||||
#if defined(__x86_64) && defined(HAVE_AVX512F) /* only x86_64 for now */
|
||||
#if defined(__x86_64) && HAVE_SIMD(AVX512F) /* only x86_64 for now */
|
||||
extern const raidz_impl_ops_t vdev_raidz_avx512f_impl;
|
||||
#endif
|
||||
#if defined(__x86_64) && defined(HAVE_AVX512BW) /* only x86_64 for now */
|
||||
#if defined(__x86_64) && HAVE_SIMD(AVX512BW) /* only x86_64 for now */
|
||||
extern const raidz_impl_ops_t vdev_raidz_avx512bw_impl;
|
||||
#endif
|
||||
#if defined(__aarch64__)
|
||||
|
||||
@@ -91,6 +91,7 @@ boolean_t vdev_rebuild_active(vdev_t *);
|
||||
|
||||
int vdev_rebuild_load(vdev_t *);
|
||||
void vdev_rebuild(vdev_t *, uint64_t);
|
||||
void vdev_rebuild_txgs(vdev_t *, uint64_t *, uint64_t *);
|
||||
void vdev_rebuild_stop_wait(vdev_t *);
|
||||
void vdev_rebuild_stop_all(spa_t *);
|
||||
void vdev_rebuild_restart(spa_t *);
|
||||
|
||||
@@ -97,13 +97,13 @@ typedef union fletcher_4_ctx {
|
||||
zio_cksum_t scalar;
|
||||
zfs_fletcher_superscalar_t superscalar[4];
|
||||
|
||||
#if defined(HAVE_SSE2) || (defined(HAVE_SSE2) && defined(HAVE_SSSE3))
|
||||
#if HAVE_SIMD(SSE2) || (HAVE_SIMD(SSE2) && HAVE_SIMD(SSSE3))
|
||||
zfs_fletcher_sse_t sse[4];
|
||||
#endif
|
||||
#if defined(HAVE_AVX) && defined(HAVE_AVX2)
|
||||
#if HAVE_SIMD(AVX) && HAVE_SIMD(AVX2)
|
||||
zfs_fletcher_avx_t avx[4];
|
||||
#endif
|
||||
#if defined(__x86_64) && defined(HAVE_AVX512F)
|
||||
#if defined(__x86_64) && HAVE_SIMD(AVX512F)
|
||||
zfs_fletcher_avx512_t avx512[4];
|
||||
#endif
|
||||
#if defined(__aarch64__)
|
||||
@@ -134,23 +134,23 @@ typedef struct fletcher_4_func {
|
||||
_ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_superscalar_ops;
|
||||
_ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_superscalar4_ops;
|
||||
|
||||
#if defined(HAVE_SSE2)
|
||||
#if HAVE_SIMD(SSE2)
|
||||
_ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_sse2_ops;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SSE2) && defined(HAVE_SSSE3)
|
||||
#if HAVE_SIMD(SSE2) && HAVE_SIMD(SSSE3)
|
||||
_ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_ssse3_ops;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_AVX) && defined(HAVE_AVX2)
|
||||
#if HAVE_SIMD(AVX) && HAVE_SIMD(AVX2)
|
||||
_ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_avx2_ops;
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64) && defined(HAVE_AVX512F)
|
||||
#if defined(__x86_64) && HAVE_SIMD(AVX512F)
|
||||
_ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_avx512f_ops;
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64) && defined(HAVE_AVX512BW)
|
||||
#if defined(__x86_64) && HAVE_SIMD(AVX512BW)
|
||||
_ZFS_FLETCHER_H const fletcher_4_ops_t fletcher_4_avx512bw_ops;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ if BUILD_LINUX
|
||||
libspl_la_SOURCES += \
|
||||
%D%/os/linux/getexecname.c \
|
||||
%D%/os/linux/gethostid.c \
|
||||
%D%/os/linux/getmntany.c \
|
||||
%D%/os/linux/mnttab.c \
|
||||
%D%/os/linux/zone.c
|
||||
endif
|
||||
|
||||
@@ -52,7 +52,7 @@ if BUILD_FREEBSD
|
||||
libspl_la_SOURCES += \
|
||||
%D%/os/freebsd/getexecname.c \
|
||||
%D%/os/freebsd/gethostid.c \
|
||||
%D%/os/freebsd/getmntany.c \
|
||||
%D%/os/freebsd/getextmntent.c \
|
||||
%D%/os/freebsd/mnttab.c \
|
||||
%D%/os/freebsd/zone.c
|
||||
endif
|
||||
|
||||
@@ -57,27 +57,11 @@ struct mnttab {
|
||||
char *mnt_mntopts;
|
||||
};
|
||||
|
||||
/*
|
||||
* NOTE: fields in extmnttab should match struct mnttab till new fields
|
||||
* are encountered, this allows hasmntopt to work properly when its arg is
|
||||
* a pointer to an extmnttab struct cast to a mnttab struct pointer.
|
||||
*/
|
||||
|
||||
struct extmnttab {
|
||||
char *mnt_special;
|
||||
char *mnt_mountp;
|
||||
char *mnt_fstype;
|
||||
char *mnt_mntopts;
|
||||
uint_t mnt_major;
|
||||
uint_t mnt_minor;
|
||||
};
|
||||
|
||||
struct stat64;
|
||||
struct statfs;
|
||||
|
||||
extern int getmntany(FILE *fp, struct mnttab *mp, struct mnttab *mpref);
|
||||
extern int _sol_getmntent(FILE *fp, struct mnttab *mp);
|
||||
extern int getextmntent(const char *path, struct extmnttab *entry,
|
||||
extern int getextmntent(const char *path, struct mnttab *entry,
|
||||
struct stat64 *statbuf);
|
||||
extern void statfs2mnttab(struct statfs *sfs, struct mnttab *mp);
|
||||
extern char *hasmntopt(struct mnttab *mnt, const char *opt);
|
||||
|
||||
@@ -54,26 +54,10 @@ struct mnttab {
|
||||
char *mnt_mntopts;
|
||||
};
|
||||
|
||||
/*
|
||||
* NOTE: fields in extmnttab should match struct mnttab till new fields
|
||||
* are encountered, this allows hasmntopt to work properly when its arg is
|
||||
* a pointer to an extmnttab struct cast to a mnttab struct pointer.
|
||||
*/
|
||||
|
||||
struct extmnttab {
|
||||
char *mnt_special;
|
||||
char *mnt_mountp;
|
||||
char *mnt_fstype;
|
||||
char *mnt_mntopts;
|
||||
uint_t mnt_major;
|
||||
uint_t mnt_minor;
|
||||
};
|
||||
|
||||
struct statfs;
|
||||
|
||||
extern int getmntany(FILE *fp, struct mnttab *mp, struct mnttab *mpref);
|
||||
extern int _sol_getmntent(FILE *fp, struct mnttab *mp);
|
||||
extern int getextmntent(const char *path, struct extmnttab *mp,
|
||||
extern int getextmntent(const char *path, struct mnttab *mp,
|
||||
struct stat64 *statbuf);
|
||||
static inline char *_sol_hasmntopt(struct mnttab *mnt, const char *opt)
|
||||
{
|
||||
|
||||
+2
-2
@@ -40,7 +40,7 @@
|
||||
#include <libzutil.h>
|
||||
|
||||
int
|
||||
getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
|
||||
getextmntent(const char *path, struct mnttab *entry, struct stat64 *statbuf)
|
||||
{
|
||||
struct statfs sfs;
|
||||
|
||||
@@ -60,6 +60,6 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
|
||||
zfs_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
statfs2mnttab(&sfs, (struct mnttab *)entry);
|
||||
statfs2mnttab(&sfs, entry);
|
||||
return (0);
|
||||
}
|
||||
@@ -26,8 +26,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file implements Solaris compatible getmntany() and hasmntopt()
|
||||
* functions.
|
||||
* This file implements Solaris compatible hasmntopt() functions.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@@ -176,38 +175,6 @@ fail:
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
|
||||
{
|
||||
int i, error;
|
||||
|
||||
error = statfs_init();
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
(void) pthread_rwlock_rdlock(&gsfs_lock);
|
||||
|
||||
for (i = 0; i < allfs; i++) {
|
||||
if (mrefp->mnt_special != NULL &&
|
||||
strcmp(mrefp->mnt_special, gsfs[i].f_mntfromname) != 0) {
|
||||
continue;
|
||||
}
|
||||
if (mrefp->mnt_mountp != NULL &&
|
||||
strcmp(mrefp->mnt_mountp, gsfs[i].f_mntonname) != 0) {
|
||||
continue;
|
||||
}
|
||||
if (mrefp->mnt_fstype != NULL &&
|
||||
strcmp(mrefp->mnt_fstype, gsfs[i].f_fstypename) != 0) {
|
||||
continue;
|
||||
}
|
||||
statfs2mnttab(&gsfs[i], mgetp);
|
||||
(void) pthread_rwlock_unlock(&gsfs_lock);
|
||||
return (0);
|
||||
}
|
||||
(void) pthread_rwlock_unlock(&gsfs_lock);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
getmntent(FILE *fp, struct mnttab *mp)
|
||||
{
|
||||
|
||||
+8
-30
@@ -45,23 +45,6 @@
|
||||
|
||||
static __thread char buf[BUFSIZE];
|
||||
|
||||
#define DIFF(xx) ( \
|
||||
(mrefp->xx != NULL) && \
|
||||
(mgetp->xx == NULL || strcmp(mrefp->xx, mgetp->xx) != 0))
|
||||
|
||||
int
|
||||
getmntany(FILE *fp, struct mnttab *mgetp, struct mnttab *mrefp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
while (
|
||||
((ret = _sol_getmntent(fp, mgetp)) == 0) && (
|
||||
DIFF(mnt_special) || DIFF(mnt_mountp) ||
|
||||
DIFF(mnt_fstype) || DIFF(mnt_mntopts))) { }
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
_sol_getmntent(FILE *fp, struct mnttab *mgetp)
|
||||
{
|
||||
@@ -85,7 +68,7 @@ _sol_getmntent(FILE *fp, struct mnttab *mgetp)
|
||||
}
|
||||
|
||||
static int
|
||||
getextmntent_impl(FILE *fp, struct extmnttab *mp, uint64_t *mnt_id)
|
||||
getextmntent_impl(FILE *fp, struct mnttab *mp, uint64_t *mnt_id, dev_t *dev)
|
||||
{
|
||||
int ret;
|
||||
struct stat64 st;
|
||||
@@ -101,19 +84,17 @@ getextmntent_impl(FILE *fp, struct extmnttab *mp, uint64_t *mnt_id)
|
||||
*mnt_id = stx.stx_mnt_id;
|
||||
#endif
|
||||
if (stat64(mp->mnt_mountp, &st) != 0) {
|
||||
mp->mnt_major = 0;
|
||||
mp->mnt_minor = 0;
|
||||
*dev = 0;
|
||||
return (ret);
|
||||
}
|
||||
mp->mnt_major = major(st.st_dev);
|
||||
mp->mnt_minor = minor(st.st_dev);
|
||||
*dev = st.st_dev;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
|
||||
getextmntent(const char *path, struct mnttab *entry, struct stat64 *statbuf)
|
||||
{
|
||||
struct stat64 st;
|
||||
FILE *fp;
|
||||
@@ -121,6 +102,7 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
|
||||
boolean_t have_mnt_id = B_FALSE;
|
||||
uint64_t target_mnt_id = 0;
|
||||
uint64_t entry_mnt_id;
|
||||
dev_t dev;
|
||||
#ifdef HAVE_STATX_MNT_ID
|
||||
struct statx stx;
|
||||
#endif
|
||||
@@ -160,12 +142,11 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
|
||||
*/
|
||||
|
||||
match = 0;
|
||||
while (getextmntent_impl(fp, entry, &entry_mnt_id) == 0) {
|
||||
while (getextmntent_impl(fp, entry, &entry_mnt_id, &dev) == 0) {
|
||||
if (have_mnt_id) {
|
||||
match = (entry_mnt_id == target_mnt_id);
|
||||
} else {
|
||||
match = makedev(entry->mnt_major, entry->mnt_minor) ==
|
||||
statbuf->st_dev;
|
||||
match = (dev == statbuf->st_dev);
|
||||
}
|
||||
if (match)
|
||||
break;
|
||||
@@ -178,11 +159,8 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (stat64(entry->mnt_mountp, &st) != 0) {
|
||||
entry->mnt_major = 0;
|
||||
entry->mnt_minor = 0;
|
||||
if (stat64(entry->mnt_mountp, &st) != 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -68,35 +68,23 @@ livelist_compare(const void *larg, const void *rarg)
|
||||
{
|
||||
const blkptr_t *l = larg;
|
||||
const blkptr_t *r = rarg;
|
||||
int cmp = 0;
|
||||
|
||||
/* Sort them according to dva[0] */
|
||||
uint64_t l_dva0_vdev, r_dva0_vdev;
|
||||
l_dva0_vdev = DVA_GET_VDEV(&l->blk_dva[0]);
|
||||
r_dva0_vdev = DVA_GET_VDEV(&r->blk_dva[0]);
|
||||
if (l_dva0_vdev < r_dva0_vdev)
|
||||
return (-1);
|
||||
else if (l_dva0_vdev > r_dva0_vdev)
|
||||
return (+1);
|
||||
cmp = TREE_CMP(DVA_GET_VDEV(&l->blk_dva[0]),
|
||||
DVA_GET_VDEV(&r->blk_dva[0]));
|
||||
if (cmp != 0)
|
||||
return (cmp);
|
||||
|
||||
/* if vdevs are equal, sort by offsets. */
|
||||
uint64_t l_dva0_offset;
|
||||
uint64_t r_dva0_offset;
|
||||
l_dva0_offset = DVA_GET_OFFSET(&l->blk_dva[0]);
|
||||
r_dva0_offset = DVA_GET_OFFSET(&r->blk_dva[0]);
|
||||
if (l_dva0_offset < r_dva0_offset) {
|
||||
return (-1);
|
||||
} else if (l_dva0_offset > r_dva0_offset) {
|
||||
return (+1);
|
||||
}
|
||||
cmp = TREE_CMP(DVA_GET_OFFSET(&l->blk_dva[0]),
|
||||
DVA_GET_OFFSET(&r->blk_dva[0]));
|
||||
if (cmp != 0)
|
||||
return (cmp);
|
||||
|
||||
/*
|
||||
* Since we're storing blkptrs without cancelling FREE/ALLOC pairs,
|
||||
* it's possible the offsets are equal. In that case, sort by txg
|
||||
*/
|
||||
if (BP_GET_BIRTH(l) < BP_GET_BIRTH(r)) {
|
||||
return (-1);
|
||||
} else if (BP_GET_BIRTH(l) > BP_GET_BIRTH(r)) {
|
||||
return (+1);
|
||||
}
|
||||
return (0);
|
||||
return (TREE_CMP(BP_GET_BIRTH(l), BP_GET_BIRTH(r)));
|
||||
}
|
||||
@@ -16,6 +16,7 @@ dist_libzfs_la_SOURCES = \
|
||||
%D%/libzfs_diff.c \
|
||||
%D%/libzfs_import.c \
|
||||
%D%/libzfs_iter.c \
|
||||
%D%/libzfs_mnttab.c \
|
||||
%D%/libzfs_mount.c \
|
||||
%D%/libzfs_pool.c \
|
||||
%D%/libzfs_share.c \
|
||||
|
||||
@@ -204,7 +204,6 @@
|
||||
<elf-symbol name='get_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='getexecname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='getextmntent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='getmntany' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='getprop_uint64' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='getzoneid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='is_mounted' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
@@ -356,6 +355,7 @@
|
||||
<elf-symbol name='zfs_component_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_create_ancestors' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_create_ancestors_props' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_crypto_attempt_load_keys' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_crypto_clone_check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_crypto_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
@@ -1255,7 +1255,6 @@
|
||||
<qualified-type-def type-id='a7e325e5' restrict='yes' id='4c428e67'/>
|
||||
<qualified-type-def type-id='e05e8614' restrict='yes' id='0be2e71c'/>
|
||||
<pointer-type-def type-id='29dbc0dd' size-in-bits='64' id='068c4f7e'/>
|
||||
<pointer-type-def type-id='b9eccc8f' size-in-bits='64' id='78830f38'/>
|
||||
<pointer-type-def type-id='62fab762' size-in-bits='64' id='db285b03'/>
|
||||
<qualified-type-def type-id='db285b03' restrict='yes' id='2a468b41'/>
|
||||
<qualified-type-def type-id='18c91f9e' restrict='yes' id='6e745582'/>
|
||||
@@ -1659,21 +1658,6 @@
|
||||
<parameter type-id='18c91f9e'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='mutex_init' mangled-name='mutex_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_init'>
|
||||
<parameter type-id='78830f38' name='mp'/>
|
||||
<parameter type-id='26a90f95' name='name'/>
|
||||
<parameter type-id='95e97e5e' name='type'/>
|
||||
<parameter type-id='eaa32e2f' name='cookie'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='mutex_destroy' mangled-name='mutex_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_destroy'>
|
||||
<parameter type-id='78830f38' name='mp'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='mutex_enter' mangled-name='mutex_enter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_enter'>
|
||||
<parameter type-id='78830f38' name='mp'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='mutex_enter_check_return' mangled-name='mutex_enter_check_return' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_enter_check_return'>
|
||||
<parameter type-id='78830f38' name='mp'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
@@ -1682,12 +1666,8 @@
|
||||
<parameter type-id='78830f38' name='mp'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='mutex_exit' mangled-name='mutex_exit' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_exit'>
|
||||
<parameter type-id='78830f38' name='mp'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/os/linux/getmntany.c' language='LANG_C99'>
|
||||
<abi-instr address-size='64' path='lib/libspl/os/linux/mnttab.c' language='LANG_C99'>
|
||||
<pointer-type-def type-id='56fe4a37' size-in-bits='64' id='b6b61d2f'/>
|
||||
<qualified-type-def type-id='b6b61d2f' restrict='yes' id='3cad23cd'/>
|
||||
<function-decl name='getmntent_r' visibility='default' binding='global' size-in-bits='64'>
|
||||
@@ -2343,6 +2323,15 @@
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='nvlist_t' type-id='ac266fd9' id='8e8d4be3'/>
|
||||
<class-decl name='kmutex' size-in-bits='384' is-struct='yes' visibility='default' id='f1cacfe1'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='m_lock' type-id='7a6844eb' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='320'>
|
||||
<var-decl name='m_owner' type-id='4051f5e7' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='kmutex_t' type-id='f1cacfe1' id='b9eccc8f'/>
|
||||
<enum-decl name='boolean_t' naming-typedef-id='c19b74c3' id='f58c8277'>
|
||||
<underlying-type type-id='9cac1fee'/>
|
||||
<enumerator name='B_FALSE' value='0'/>
|
||||
@@ -2402,6 +2391,7 @@
|
||||
</class-decl>
|
||||
<typedef-decl name='regex_t' type-id='19fc9a8c' id='aca3bac8'/>
|
||||
<typedef-decl name='uintptr_t' type-id='7359adad' id='e475ab95'/>
|
||||
<typedef-decl name='pthread_t' type-id='7359adad' id='4051f5e7'/>
|
||||
<union-decl name='pthread_mutex_t' size-in-bits='320' naming-typedef-id='7a6844eb' visibility='default' id='70681f9b'>
|
||||
<data-member access='public'>
|
||||
<var-decl name='__data' type-id='4c734837' visibility='default'/>
|
||||
@@ -2487,32 +2477,29 @@
|
||||
<var-decl name='libzfs_printerr' type-id='95e97e5e' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='16960'>
|
||||
<var-decl name='libzfs_mnttab_enable' type-id='c19b74c3' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='17024'>
|
||||
<var-decl name='libzfs_mnttab_cache_lock' type-id='7a6844eb' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='17344'>
|
||||
<var-decl name='libzfs_mnttab_cache' type-id='f20fbd51' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='17664'>
|
||||
<var-decl name='libzfs_pool_iter' type-id='95e97e5e' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='17696'>
|
||||
<data-member access='public' layout-offset-in-bits='16992'>
|
||||
<var-decl name='libzfs_prop_debug' type-id='c19b74c3' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='17728'>
|
||||
<data-member access='public' layout-offset-in-bits='17024'>
|
||||
<var-decl name='libzfs_urire' type-id='aca3bac8' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='18240'>
|
||||
<data-member access='public' layout-offset-in-bits='17536'>
|
||||
<var-decl name='libzfs_max_nvlist' type-id='9c313c2d' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='18304'>
|
||||
<data-member access='public' layout-offset-in-bits='17600'>
|
||||
<var-decl name='libfetch' type-id='eaa32e2f' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='18368'>
|
||||
<data-member access='public' layout-offset-in-bits='17664'>
|
||||
<var-decl name='libfetch_load_error' type-id='26a90f95' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='17728'>
|
||||
<var-decl name='zh_mnttab_lock' type-id='b9eccc8f' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='18112'>
|
||||
<var-decl name='zh_mnttab' type-id='f20fbd51' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='zfs_handle' size-in-bits='4928' is-struct='yes' visibility='default' id='f6ee4445'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
@@ -3372,7 +3359,64 @@
|
||||
<enumerator name='ZPOOL_PROP_LAST_SCRUBBED_TXG' value='39'/>
|
||||
<enumerator name='ZPOOL_PROP_DEDUPUSED' value='40'/>
|
||||
<enumerator name='ZPOOL_PROP_DEDUPSAVED' value='41'/>
|
||||
<enumerator name='ZPOOL_NUM_PROPS' value='42'/>
|
||||
<enumerator name='ZPOOL_PROP_AVAILABLE' value='42'/>
|
||||
<enumerator name='ZPOOL_PROP_USABLE' value='43'/>
|
||||
<enumerator name='ZPOOL_PROP_USED' value='44'/>
|
||||
<enumerator name='ZPOOL_PROP_NORMAL_SIZE' value='45'/>
|
||||
<enumerator name='ZPOOL_PROP_NORMAL_CAPACITY' value='46'/>
|
||||
<enumerator name='ZPOOL_PROP_NORMAL_FREE' value='47'/>
|
||||
<enumerator name='ZPOOL_PROP_NORMAL_ALLOCATED' value='48'/>
|
||||
<enumerator name='ZPOOL_PROP_NORMAL_AVAILABLE' value='49'/>
|
||||
<enumerator name='ZPOOL_PROP_NORMAL_USABLE' value='50'/>
|
||||
<enumerator name='ZPOOL_PROP_NORMAL_USED' value='51'/>
|
||||
<enumerator name='ZPOOL_PROP_NORMAL_EXPANDSZ' value='52'/>
|
||||
<enumerator name='ZPOOL_PROP_NORMAL_FRAGMENTATION' value='53'/>
|
||||
<enumerator name='ZPOOL_PROP_SPECIAL_SIZE' value='54'/>
|
||||
<enumerator name='ZPOOL_PROP_SPECIAL_CAPACITY' value='55'/>
|
||||
<enumerator name='ZPOOL_PROP_SPECIAL_FREE' value='56'/>
|
||||
<enumerator name='ZPOOL_PROP_SPECIAL_ALLOCATED' value='57'/>
|
||||
<enumerator name='ZPOOL_PROP_SPECIAL_AVAILABLE' value='58'/>
|
||||
<enumerator name='ZPOOL_PROP_SPECIAL_USABLE' value='59'/>
|
||||
<enumerator name='ZPOOL_PROP_SPECIAL_USED' value='60'/>
|
||||
<enumerator name='ZPOOL_PROP_SPECIAL_EXPANDSZ' value='61'/>
|
||||
<enumerator name='ZPOOL_PROP_SPECIAL_FRAGMENTATION' value='62'/>
|
||||
<enumerator name='ZPOOL_PROP_DEDUP_SIZE' value='63'/>
|
||||
<enumerator name='ZPOOL_PROP_DEDUP_CAPACITY' value='64'/>
|
||||
<enumerator name='ZPOOL_PROP_DEDUP_FREE' value='65'/>
|
||||
<enumerator name='ZPOOL_PROP_DEDUP_ALLOCATED' value='66'/>
|
||||
<enumerator name='ZPOOL_PROP_DEDUP_AVAILABLE' value='67'/>
|
||||
<enumerator name='ZPOOL_PROP_DEDUP_USABLE' value='68'/>
|
||||
<enumerator name='ZPOOL_PROP_DEDUP_USED' value='69'/>
|
||||
<enumerator name='ZPOOL_PROP_DEDUP_EXPANDSZ' value='70'/>
|
||||
<enumerator name='ZPOOL_PROP_DEDUP_FRAGMENTATION' value='71'/>
|
||||
<enumerator name='ZPOOL_PROP_LOG_SIZE' value='72'/>
|
||||
<enumerator name='ZPOOL_PROP_LOG_CAPACITY' value='73'/>
|
||||
<enumerator name='ZPOOL_PROP_LOG_FREE' value='74'/>
|
||||
<enumerator name='ZPOOL_PROP_LOG_ALLOCATED' value='75'/>
|
||||
<enumerator name='ZPOOL_PROP_LOG_AVAILABLE' value='76'/>
|
||||
<enumerator name='ZPOOL_PROP_LOG_USABLE' value='77'/>
|
||||
<enumerator name='ZPOOL_PROP_LOG_USED' value='78'/>
|
||||
<enumerator name='ZPOOL_PROP_LOG_EXPANDSZ' value='79'/>
|
||||
<enumerator name='ZPOOL_PROP_LOG_FRAGMENTATION' value='80'/>
|
||||
<enumerator name='ZPOOL_PROP_ELOG_SIZE' value='81'/>
|
||||
<enumerator name='ZPOOL_PROP_ELOG_CAPACITY' value='82'/>
|
||||
<enumerator name='ZPOOL_PROP_ELOG_FREE' value='83'/>
|
||||
<enumerator name='ZPOOL_PROP_ELOG_ALLOCATED' value='84'/>
|
||||
<enumerator name='ZPOOL_PROP_ELOG_AVAILABLE' value='85'/>
|
||||
<enumerator name='ZPOOL_PROP_ELOG_USABLE' value='86'/>
|
||||
<enumerator name='ZPOOL_PROP_ELOG_USED' value='87'/>
|
||||
<enumerator name='ZPOOL_PROP_ELOG_EXPANDSZ' value='88'/>
|
||||
<enumerator name='ZPOOL_PROP_ELOG_FRAGMENTATION' value='89'/>
|
||||
<enumerator name='ZPOOL_PROP_SELOG_SIZE' value='90'/>
|
||||
<enumerator name='ZPOOL_PROP_SELOG_CAPACITY' value='91'/>
|
||||
<enumerator name='ZPOOL_PROP_SELOG_FREE' value='92'/>
|
||||
<enumerator name='ZPOOL_PROP_SELOG_ALLOCATED' value='93'/>
|
||||
<enumerator name='ZPOOL_PROP_SELOG_AVAILABLE' value='94'/>
|
||||
<enumerator name='ZPOOL_PROP_SELOG_USABLE' value='95'/>
|
||||
<enumerator name='ZPOOL_PROP_SELOG_USED' value='96'/>
|
||||
<enumerator name='ZPOOL_PROP_SELOG_EXPANDSZ' value='97'/>
|
||||
<enumerator name='ZPOOL_PROP_SELOG_FRAGMENTATION' value='98'/>
|
||||
<enumerator name='ZPOOL_NUM_PROPS' value='99'/>
|
||||
</enum-decl>
|
||||
<typedef-decl name='zpool_prop_t' type-id='af1ba157' id='5d0c23fb'/>
|
||||
<typedef-decl name='regoff_t' type-id='95e97e5e' id='54a2a2a8'/>
|
||||
@@ -4055,9 +4099,6 @@
|
||||
</function-type>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libzfs/libzfs_dataset.c' language='LANG_C99'>
|
||||
<array-type-def dimensions='1' type-id='a84c031d' size-in-bits='32' id='8e0573fd'>
|
||||
<subrange length='4' type-id='7359adad' id='16fe7105'/>
|
||||
</array-type-def>
|
||||
<class-decl name='prop_changelist' is-struct='yes' visibility='default' is-declaration-only='yes' id='d86edc51'/>
|
||||
<class-decl name='zprop_list' size-in-bits='448' is-struct='yes' visibility='default' id='bd9b4291'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
@@ -4219,15 +4260,6 @@
|
||||
<var-decl name='pw_shell' type-id='26a90f95' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<union-decl name='pthread_mutexattr_t' size-in-bits='32' naming-typedef-id='8afd6070' visibility='default' id='7300eb00'>
|
||||
<data-member access='public'>
|
||||
<var-decl name='__size' type-id='8e0573fd' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public'>
|
||||
<var-decl name='__align' type-id='95e97e5e' visibility='default'/>
|
||||
</data-member>
|
||||
</union-decl>
|
||||
<typedef-decl name='pthread_mutexattr_t' type-id='7300eb00' id='8afd6070'/>
|
||||
<typedef-decl name='int64_t' type-id='0c9942d2' id='9da381c4'/>
|
||||
<typedef-decl name='__int64_t' type-id='bd54fe1a' id='0c9942d2'/>
|
||||
<typedef-decl name='__gid_t' type-id='f0981eeb' id='d94ec6d9'/>
|
||||
@@ -4273,8 +4305,6 @@
|
||||
<qualified-type-def type-id='26a90f95' restrict='yes' id='266fe297'/>
|
||||
<qualified-type-def type-id='56fe4a37' const='yes' id='a75125ce'/>
|
||||
<pointer-type-def type-id='a75125ce' size-in-bits='64' id='48bea5ec'/>
|
||||
<qualified-type-def type-id='8afd6070' const='yes' id='1d853360'/>
|
||||
<pointer-type-def type-id='1d853360' size-in-bits='64' id='c2afbd7e'/>
|
||||
<qualified-type-def type-id='c9d12d66' const='yes' id='588b3216'/>
|
||||
<pointer-type-def type-id='588b3216' size-in-bits='64' id='9f201474'/>
|
||||
<qualified-type-def type-id='9f201474' restrict='yes' id='d6e2847c'/>
|
||||
@@ -4304,6 +4334,12 @@
|
||||
<pointer-type-def type-id='bdb8ac4f' size-in-bits='64' id='3a9b2288'/>
|
||||
<pointer-type-def type-id='3a9b2288' size-in-bits='64' id='e4378506'/>
|
||||
<class-decl name='prop_changelist' is-struct='yes' visibility='default' is-declaration-only='yes' id='d86edc51'/>
|
||||
<function-decl name='libzfs_mnttab_find' mangled-name='libzfs_mnttab_find' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_find'>
|
||||
<parameter type-id='b0382bb3'/>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<parameter type-id='9d424d31'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_open' mangled-name='zpool_open' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_open'>
|
||||
<parameter type-id='b0382bb3'/>
|
||||
<parameter type-id='80f4b756'/>
|
||||
@@ -4471,15 +4507,6 @@
|
||||
<parameter type-id='b59d7dce'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='avl_add' mangled-name='avl_add' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_add'>
|
||||
<parameter type-id='a3681dea'/>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='avl_numnodes' mangled-name='avl_numnodes' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_numnodes'>
|
||||
<parameter type-id='a3681dea'/>
|
||||
<return type-id='ee1f298e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_prop_readonly' mangled-name='zfs_prop_readonly' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_readonly'>
|
||||
<parameter type-id='58603c44'/>
|
||||
<return type-id='c19b74c3'/>
|
||||
@@ -4683,17 +4710,6 @@
|
||||
<parameter type-id='58603c44'/>
|
||||
<return type-id='31429eff'/>
|
||||
</function-decl>
|
||||
<function-decl name='getmntany' mangled-name='getmntany' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getmntany'>
|
||||
<parameter type-id='822cd80b'/>
|
||||
<parameter type-id='9d424d31'/>
|
||||
<parameter type-id='9d424d31'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='_sol_getmntent' mangled-name='_sol_getmntent' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_sol_getmntent'>
|
||||
<parameter type-id='822cd80b'/>
|
||||
<parameter type-id='9d424d31'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='getgrnam_r' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='c878edd6'/>
|
||||
@@ -4707,15 +4723,6 @@
|
||||
<parameter type-id='80f4b756'/>
|
||||
<return type-id='26a90f95'/>
|
||||
</function-decl>
|
||||
<function-decl name='pthread_mutex_init' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='18c91f9e'/>
|
||||
<parameter type-id='c2afbd7e'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='pthread_mutex_destroy' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='18c91f9e'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='getpwnam_r' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='33518961'/>
|
||||
@@ -4795,37 +4802,6 @@
|
||||
<parameter type-id='80f4b756' name='path'/>
|
||||
<return type-id='c19b74c3'/>
|
||||
</function-decl>
|
||||
<function-decl name='libzfs_mnttab_init' mangled-name='libzfs_mnttab_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_init'>
|
||||
<parameter type-id='b0382bb3' name='hdl'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='libzfs_mnttab_fini' mangled-name='libzfs_mnttab_fini' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_fini'>
|
||||
<parameter type-id='b0382bb3' name='hdl'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='libzfs_mnttab_cache' mangled-name='libzfs_mnttab_cache' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_cache'>
|
||||
<parameter type-id='b0382bb3' name='hdl'/>
|
||||
<parameter type-id='c19b74c3' name='enable'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='libzfs_mnttab_find' mangled-name='libzfs_mnttab_find' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_find'>
|
||||
<parameter type-id='b0382bb3' name='hdl'/>
|
||||
<parameter type-id='80f4b756' name='fsname'/>
|
||||
<parameter type-id='9d424d31' name='entry'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='libzfs_mnttab_add' mangled-name='libzfs_mnttab_add' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_add'>
|
||||
<parameter type-id='b0382bb3' name='hdl'/>
|
||||
<parameter type-id='80f4b756' name='special'/>
|
||||
<parameter type-id='80f4b756' name='mountp'/>
|
||||
<parameter type-id='80f4b756' name='mntopts'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='libzfs_mnttab_remove' mangled-name='libzfs_mnttab_remove' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_remove'>
|
||||
<parameter type-id='b0382bb3' name='hdl'/>
|
||||
<parameter type-id='80f4b756' name='fsname'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_spa_version' mangled-name='zfs_spa_version' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_spa_version'>
|
||||
<parameter type-id='9200a744' name='zhp'/>
|
||||
<parameter type-id='7292109c' name='spa_version'/>
|
||||
@@ -5202,7 +5178,6 @@
|
||||
<array-type-def dimensions='1' type-id='a84c031d' size-in-bits='448' id='6093ff7c'>
|
||||
<subrange length='56' type-id='7359adad' id='f8137894'/>
|
||||
</array-type-def>
|
||||
<typedef-decl name='pthread_t' type-id='7359adad' id='4051f5e7'/>
|
||||
<union-decl name='pthread_attr_t' size-in-bits='448' visibility='default' id='b63afacd'>
|
||||
<data-member access='public'>
|
||||
<var-decl name='__size' type-id='6093ff7c' visibility='default'/>
|
||||
@@ -5507,6 +5482,16 @@
|
||||
</function-type>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libzfs/libzfs_iter.c' language='LANG_C99'>
|
||||
<function-decl name='avl_add' mangled-name='avl_add' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_add'>
|
||||
<parameter type-id='a3681dea'/>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='_sol_getmntent' mangled-name='_sol_getmntent' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_sol_getmntent'>
|
||||
<parameter type-id='822cd80b'/>
|
||||
<parameter type-id='9d424d31'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='make_dataset_handle_zc' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='b0382bb3'/>
|
||||
<parameter type-id='e4ec4540'/>
|
||||
@@ -5590,6 +5575,57 @@
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libzfs/libzfs_mnttab.c' language='LANG_C99'>
|
||||
<pointer-type-def type-id='b9eccc8f' size-in-bits='64' id='78830f38'/>
|
||||
<function-decl name='avl_numnodes' mangled-name='avl_numnodes' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_numnodes'>
|
||||
<parameter type-id='a3681dea'/>
|
||||
<return type-id='ee1f298e'/>
|
||||
</function-decl>
|
||||
<function-decl name='mutex_init' mangled-name='mutex_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_init'>
|
||||
<parameter type-id='78830f38'/>
|
||||
<parameter type-id='26a90f95'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='mutex_destroy' mangled-name='mutex_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_destroy'>
|
||||
<parameter type-id='78830f38'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='mutex_enter' mangled-name='mutex_enter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_enter'>
|
||||
<parameter type-id='78830f38'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='mutex_exit' mangled-name='mutex_exit' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_exit'>
|
||||
<parameter type-id='78830f38'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='libzfs_mnttab_init' mangled-name='libzfs_mnttab_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_init'>
|
||||
<parameter type-id='b0382bb3' name='hdl'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='libzfs_mnttab_fini' mangled-name='libzfs_mnttab_fini' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_fini'>
|
||||
<parameter type-id='b0382bb3' name='hdl'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='libzfs_mnttab_cache' mangled-name='libzfs_mnttab_cache' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_cache'>
|
||||
<parameter type-id='b0382bb3' name='hdl'/>
|
||||
<parameter type-id='c19b74c3' name='enable'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='libzfs_mnttab_add' mangled-name='libzfs_mnttab_add' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_add'>
|
||||
<parameter type-id='b0382bb3' name='hdl'/>
|
||||
<parameter type-id='80f4b756' name='special'/>
|
||||
<parameter type-id='80f4b756' name='mountp'/>
|
||||
<parameter type-id='80f4b756' name='mntopts'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='libzfs_mnttab_remove' mangled-name='libzfs_mnttab_remove' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_remove'>
|
||||
<parameter type-id='b0382bb3' name='hdl'/>
|
||||
<parameter type-id='80f4b756' name='fsname'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libzfs/libzfs_mount.c' language='LANG_C99'>
|
||||
<array-type-def dimensions='1' type-id='6028cbfe' size-in-bits='256' id='b39b9aa7'>
|
||||
<subrange length='4' type-id='7359adad' id='16fe7105'/>
|
||||
@@ -5624,15 +5660,6 @@
|
||||
</class-decl>
|
||||
<typedef-decl name='get_all_cb_t' type-id='803dac95' id='9b293607'/>
|
||||
<typedef-decl name='kcondvar_t' type-id='62fab762' id='29dbc0dd'/>
|
||||
<class-decl name='kmutex' size-in-bits='384' is-struct='yes' visibility='default' id='f1cacfe1'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='m_lock' type-id='7a6844eb' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='320'>
|
||||
<var-decl name='m_owner' type-id='4051f5e7' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='kmutex_t' type-id='f1cacfe1' id='b9eccc8f'/>
|
||||
<class-decl name='krwlock' size-in-bits='576' is-struct='yes' visibility='default' id='4361e3b2'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='rw_lock' type-id='3f680bc6' visibility='default'/>
|
||||
@@ -6557,6 +6584,11 @@
|
||||
<pointer-type-def type-id='35acf840' size-in-bits='64' id='17f3480d'/>
|
||||
<pointer-type-def type-id='688c495b' size-in-bits='64' id='cec6f2e4'/>
|
||||
<pointer-type-def type-id='d11b7617' size-in-bits='64' id='23432aaa'/>
|
||||
<function-decl name='dump_nvlist' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='5ce45b60'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_get_handle' mangled-name='zpool_get_handle' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_handle'>
|
||||
<parameter type-id='4c81de99'/>
|
||||
<return type-id='b0382bb3'/>
|
||||
@@ -7410,7 +7442,7 @@
|
||||
<array-type-def dimensions='1' type-id='eaa32e2f' size-in-bits='256' id='209ef23f'>
|
||||
<subrange length='4' type-id='7359adad' id='16fe7105'/>
|
||||
</array-type-def>
|
||||
<class-decl name='sendflags' size-in-bits='576' is-struct='yes' visibility='default' id='f6aa15be'>
|
||||
<class-decl name='sendflags' size-in-bits='608' is-struct='yes' visibility='default' id='f6aa15be'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='verbosity' type-id='95e97e5e' visibility='default'/>
|
||||
</data-member>
|
||||
@@ -7465,6 +7497,9 @@
|
||||
<data-member access='public' layout-offset-in-bits='544'>
|
||||
<var-decl name='saved' type-id='c19b74c3' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='576'>
|
||||
<var-decl name='no_preserve_encryption' type-id='c19b74c3' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='sendflags_t' type-id='f6aa15be' id='945467e6'/>
|
||||
<typedef-decl name='snapfilter_cb_t' type-id='d2a5e211' id='3d3ffb69'/>
|
||||
@@ -8146,6 +8181,13 @@
|
||||
<parameter type-id='5d6479ae'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='lzc_send_progress' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='5d6479ae'/>
|
||||
<parameter type-id='5d6479ae'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='lzc_rename' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<parameter type-id='80f4b756'/>
|
||||
@@ -8561,26 +8603,6 @@
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='zprop_desc_t' type-id='bbff5e4b' id='ffa52b96'/>
|
||||
<class-decl name='extmnttab' size-in-bits='320' is-struct='yes' visibility='default' id='0c544dc0'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='mnt_special' type-id='26a90f95' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='mnt_mountp' type-id='26a90f95' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<var-decl name='mnt_fstype' type-id='26a90f95' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='192'>
|
||||
<var-decl name='mnt_mntopts' type-id='26a90f95' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='256'>
|
||||
<var-decl name='mnt_major' type-id='3502e3ff' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='288'>
|
||||
<var-decl name='mnt_minor' type-id='3502e3ff' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<pointer-type-def type-id='d5027220' size-in-bits='64' id='b7f2d5e6'/>
|
||||
<qualified-type-def type-id='26a90f95' const='yes' id='57de658a'/>
|
||||
<pointer-type-def type-id='57de658a' size-in-bits='64' id='f319fae0'/>
|
||||
@@ -8590,7 +8612,6 @@
|
||||
<pointer-type-def type-id='a0de50cd' size-in-bits='64' id='24f95ba5'/>
|
||||
<qualified-type-def type-id='64636ce3' const='yes' id='072f7953'/>
|
||||
<pointer-type-def type-id='072f7953' size-in-bits='64' id='c8bc397b'/>
|
||||
<pointer-type-def type-id='0c544dc0' size-in-bits='64' id='394fc496'/>
|
||||
<pointer-type-def type-id='aca3bac8' size-in-bits='64' id='d33f11cb'/>
|
||||
<qualified-type-def type-id='d33f11cb' restrict='yes' id='5c53ba29'/>
|
||||
<pointer-type-def type-id='ffa52b96' size-in-bits='64' id='76c8174b'/>
|
||||
@@ -8686,7 +8707,7 @@
|
||||
</function-decl>
|
||||
<function-decl name='getextmntent' mangled-name='getextmntent' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getextmntent'>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<parameter type-id='394fc496'/>
|
||||
<parameter type-id='9d424d31'/>
|
||||
<parameter type-id='62f7a03d'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
@@ -9580,6 +9601,9 @@
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libzutil/zutil_import.c' language='LANG_C99'>
|
||||
<array-type-def dimensions='1' type-id='a84c031d' size-in-bits='32' id='8e0573fd'>
|
||||
<subrange length='4' type-id='7359adad' id='16fe7105'/>
|
||||
</array-type-def>
|
||||
<class-decl name='importargs' size-in-bits='512' is-struct='yes' visibility='default' id='7ac83801'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='path' type-id='9b23c9ad' visibility='default'/>
|
||||
@@ -9678,6 +9702,15 @@
|
||||
<var-decl name='__glibc_reserved' type-id='16dc656a' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<union-decl name='pthread_mutexattr_t' size-in-bits='32' naming-typedef-id='8afd6070' visibility='default' id='7300eb00'>
|
||||
<data-member access='public'>
|
||||
<var-decl name='__size' type-id='8e0573fd' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public'>
|
||||
<var-decl name='__align' type-id='95e97e5e' visibility='default'/>
|
||||
</data-member>
|
||||
</union-decl>
|
||||
<typedef-decl name='pthread_mutexattr_t' type-id='7300eb00' id='8afd6070'/>
|
||||
<pointer-type-def type-id='e4957c49' size-in-bits='64' id='924bbc81'/>
|
||||
<qualified-type-def type-id='924bbc81' const='yes' id='5499dcde'/>
|
||||
<pointer-type-def type-id='5499dcde' size-in-bits='64' id='2236d41c'/>
|
||||
@@ -9685,6 +9718,8 @@
|
||||
<pointer-type-def type-id='a3681dea' size-in-bits='64' id='fce6d540'/>
|
||||
<qualified-type-def type-id='e4957c49' const='yes' id='fced9da2'/>
|
||||
<pointer-type-def type-id='fced9da2' size-in-bits='64' id='b20efd18'/>
|
||||
<qualified-type-def type-id='8afd6070' const='yes' id='1d853360'/>
|
||||
<pointer-type-def type-id='1d853360' size-in-bits='64' id='c2afbd7e'/>
|
||||
<pointer-type-def type-id='7a842a6b' size-in-bits='64' id='07ee4a58'/>
|
||||
<pointer-type-def type-id='8a70a786' size-in-bits='64' id='5507783b'/>
|
||||
<pointer-type-def type-id='b1e62775' size-in-bits='64' id='f095e320'/>
|
||||
@@ -9701,10 +9736,13 @@
|
||||
<function-decl name='spl_pagesize' mangled-name='spl_pagesize' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='spl_pagesize'>
|
||||
<return type-id='b59d7dce'/>
|
||||
</function-decl>
|
||||
<function-decl name='posix_memalign' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='63e171df'/>
|
||||
<parameter type-id='b59d7dce'/>
|
||||
<parameter type-id='b59d7dce'/>
|
||||
<function-decl name='pthread_mutex_init' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='18c91f9e'/>
|
||||
<parameter type-id='c2afbd7e'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='pthread_mutex_destroy' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='18c91f9e'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='sysconf' visibility='default' binding='global' size-in-bits='64'>
|
||||
@@ -9833,6 +9871,7 @@
|
||||
<function-decl name='zpool_dump_ddt' mangled-name='zpool_dump_ddt' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_dump_ddt'>
|
||||
<parameter type-id='dfe59052' name='dds_total'/>
|
||||
<parameter type-id='932720f8' name='ddh'/>
|
||||
<parameter type-id='c19b74c3' name='parsable'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='fsleep' mangled-name='fsleep' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fsleep'>
|
||||
@@ -10641,4 +10680,238 @@
|
||||
<return type-id='24f95ba5'/>
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='module/zfs/btree.c' language='LANG_C99'>
|
||||
<typedef-decl name='kmem_cache_t' type-id='2a49bcee' id='5cd0fe54'/>
|
||||
<typedef-decl name='umem_constructor_t' type-id='7e872986' id='da6072ac'/>
|
||||
<typedef-decl name='umem_destructor_t' type-id='c039af2e' id='19c23f45'/>
|
||||
<typedef-decl name='umem_reclaim_t' type-id='c5c76c9c' id='f1a257c7'/>
|
||||
<class-decl name='umem_cache' size-in-bits='768' is-struct='yes' visibility='default' id='e066f130'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='cache_name' type-id='16dc656a' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='256'>
|
||||
<var-decl name='cache_bufsize' type-id='b59d7dce' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='320'>
|
||||
<var-decl name='cache_align' type-id='b59d7dce' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='384'>
|
||||
<var-decl name='cache_constructor' type-id='91f51f89' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='448'>
|
||||
<var-decl name='cache_destructor' type-id='9cb5182c' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='512'>
|
||||
<var-decl name='cache_reclaim' type-id='fbdc58f8' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='576'>
|
||||
<var-decl name='cache_private' type-id='eaa32e2f' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='640'>
|
||||
<var-decl name='cache_arena' type-id='eaa32e2f' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='704'>
|
||||
<var-decl name='cache_cflags' type-id='95e97e5e' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='umem_cache_t' type-id='e066f130' id='2a49bcee'/>
|
||||
<pointer-type-def type-id='5cd0fe54' size-in-bits='64' id='23bd1729'/>
|
||||
<pointer-type-def type-id='da6072ac' size-in-bits='64' id='91f51f89'/>
|
||||
<pointer-type-def type-id='19c23f45' size-in-bits='64' id='9cb5182c'/>
|
||||
<pointer-type-def type-id='f1a257c7' size-in-bits='64' id='fbdc58f8'/>
|
||||
<var-decl name='zfs_btree_leaf_cache' type-id='23bd1729' visibility='default'/>
|
||||
<function-decl name='posix_memalign' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='63e171df'/>
|
||||
<parameter type-id='b59d7dce'/>
|
||||
<parameter type-id='b59d7dce'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-type size-in-bits='64' id='7e872986'>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-type>
|
||||
<function-type size-in-bits='64' id='c039af2e'>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-type>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='module/zfs/range_tree.c' language='LANG_C99'>
|
||||
<array-type-def dimensions='1' type-id='b96825af' size-in-bits='infinite' id='048fe7bc'>
|
||||
<subrange length='infinite' type-id='7359adad' id='031f2035'/>
|
||||
</array-type-def>
|
||||
<array-type-def dimensions='1' type-id='4dc107b1' size-in-bits='8128' id='017d5779'>
|
||||
<subrange length='127' type-id='7359adad' id='5ed08de5'/>
|
||||
</array-type-def>
|
||||
<class-decl name='zfs_btree_hdr' size-in-bits='128' is-struct='yes' visibility='default' id='fc907d62'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='bth_parent' type-id='0cafbda7' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='bth_first' type-id='8f92235e' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='96'>
|
||||
<var-decl name='bth_count' type-id='8f92235e' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='zfs_btree_hdr_t' type-id='fc907d62' id='336228ae'/>
|
||||
<class-decl name='zfs_btree_core' size-in-bits='8256' is-struct='yes' visibility='default' id='c2a40bdf'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='btc_hdr' type-id='336228ae' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<var-decl name='btc_children' type-id='017d5779' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='8256'>
|
||||
<var-decl name='btc_elems' type-id='048fe7bc' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='zfs_btree_leaf' size-in-bits='128' is-struct='yes' visibility='default' id='15b0aea0'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='btl_hdr' type-id='336228ae' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<var-decl name='btl_elems' type-id='048fe7bc' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='zfs_btree_leaf_t' type-id='15b0aea0' id='b685aaea'/>
|
||||
<class-decl name='zfs_btree_index' size-in-bits='128' is-struct='yes' visibility='default' id='378b800c'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='bti_node' type-id='4dc107b1' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='bti_offset' type-id='8f92235e' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='96'>
|
||||
<var-decl name='bti_before' type-id='c19b74c3' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='zfs_btree_index_t' type-id='378b800c' id='a481467c'/>
|
||||
<typedef-decl name='zfs_btree_t' type-id='a0c8756d' id='aa8d6647'/>
|
||||
<typedef-decl name='bt_find_in_buf_f' type-id='d12cb521' id='f3d91629'/>
|
||||
<class-decl name='btree' size-in-bits='576' is-struct='yes' visibility='default' id='a0c8756d'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='bt_compar' type-id='585e1de9' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='bt_find_in_buf' type-id='f3d91629' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<var-decl name='bt_elem_size' type-id='b59d7dce' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='192'>
|
||||
<var-decl name='bt_leaf_size' type-id='b59d7dce' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='256'>
|
||||
<var-decl name='bt_leaf_cap' type-id='8f92235e' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='288'>
|
||||
<var-decl name='bt_height' type-id='3ff5601b' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='320'>
|
||||
<var-decl name='bt_num_elems' type-id='9c313c2d' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='384'>
|
||||
<var-decl name='bt_num_nodes' type-id='9c313c2d' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='448'>
|
||||
<var-decl name='bt_root' type-id='4dc107b1' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='512'>
|
||||
<var-decl name='bt_bulk' type-id='a37f572b' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<qualified-type-def type-id='a481467c' const='yes' id='2e014c8c'/>
|
||||
<pointer-type-def type-id='2e014c8c' size-in-bits='64' id='120ba952'/>
|
||||
<pointer-type-def type-id='2273bcd5' size-in-bits='64' id='d12cb521'/>
|
||||
<pointer-type-def type-id='c2a40bdf' size-in-bits='64' id='0cafbda7'/>
|
||||
<pointer-type-def type-id='336228ae' size-in-bits='64' id='4dc107b1'/>
|
||||
<pointer-type-def type-id='a481467c' size-in-bits='64' id='b79742cf'/>
|
||||
<pointer-type-def type-id='b79742cf' size-in-bits='64' id='e81e4e7f'/>
|
||||
<pointer-type-def type-id='b685aaea' size-in-bits='64' id='a37f572b'/>
|
||||
<pointer-type-def type-id='aa8d6647' size-in-bits='64' id='5c16a66a'/>
|
||||
<function-decl name='zfs_btree_create' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='5c16a66a'/>
|
||||
<parameter type-id='585e1de9'/>
|
||||
<parameter type-id='f3d91629'/>
|
||||
<parameter type-id='b59d7dce'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_btree_find' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='5c16a66a'/>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<parameter type-id='b79742cf'/>
|
||||
<return type-id='eaa32e2f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_btree_add_idx' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='5c16a66a'/>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<parameter type-id='120ba952'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_btree_first' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='5c16a66a'/>
|
||||
<parameter type-id='b79742cf'/>
|
||||
<return type-id='eaa32e2f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_btree_last' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='5c16a66a'/>
|
||||
<parameter type-id='b79742cf'/>
|
||||
<return type-id='eaa32e2f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_btree_next' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='5c16a66a'/>
|
||||
<parameter type-id='120ba952'/>
|
||||
<parameter type-id='b79742cf'/>
|
||||
<return type-id='eaa32e2f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_btree_prev' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='5c16a66a'/>
|
||||
<parameter type-id='120ba952'/>
|
||||
<parameter type-id='b79742cf'/>
|
||||
<return type-id='eaa32e2f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_btree_add' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='5c16a66a'/>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_btree_remove' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='5c16a66a'/>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_btree_remove_idx' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='5c16a66a'/>
|
||||
<parameter type-id='b79742cf'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_btree_numnodes' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='5c16a66a'/>
|
||||
<return type-id='ee1f298e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_btree_destroy_nodes' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='5c16a66a'/>
|
||||
<parameter type-id='e81e4e7f'/>
|
||||
<return type-id='eaa32e2f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_btree_clear' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='5c16a66a'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_btree_destroy' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='5c16a66a'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-type size-in-bits='64' id='2273bcd5'>
|
||||
<parameter type-id='5c16a66a'/>
|
||||
<parameter type-id='ae3e8ca6'/>
|
||||
<parameter type-id='8f92235e'/>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<parameter type-id='b79742cf'/>
|
||||
<return type-id='eaa32e2f'/>
|
||||
</function-type>
|
||||
</abi-instr>
|
||||
</abi-corpus>
|
||||
@@ -806,190 +806,6 @@ zfs_close(zfs_handle_t *zhp)
|
||||
free(zhp);
|
||||
}
|
||||
|
||||
typedef struct mnttab_node {
|
||||
struct mnttab mtn_mt;
|
||||
avl_node_t mtn_node;
|
||||
} mnttab_node_t;
|
||||
|
||||
static int
|
||||
libzfs_mnttab_cache_compare(const void *arg1, const void *arg2)
|
||||
{
|
||||
const mnttab_node_t *mtn1 = (const mnttab_node_t *)arg1;
|
||||
const mnttab_node_t *mtn2 = (const mnttab_node_t *)arg2;
|
||||
int rv;
|
||||
|
||||
rv = strcmp(mtn1->mtn_mt.mnt_special, mtn2->mtn_mt.mnt_special);
|
||||
|
||||
return (TREE_ISIGN(rv));
|
||||
}
|
||||
|
||||
void
|
||||
libzfs_mnttab_init(libzfs_handle_t *hdl)
|
||||
{
|
||||
pthread_mutex_init(&hdl->libzfs_mnttab_cache_lock, NULL);
|
||||
assert(avl_numnodes(&hdl->libzfs_mnttab_cache) == 0);
|
||||
avl_create(&hdl->libzfs_mnttab_cache, libzfs_mnttab_cache_compare,
|
||||
sizeof (mnttab_node_t), offsetof(mnttab_node_t, mtn_node));
|
||||
}
|
||||
|
||||
static int
|
||||
libzfs_mnttab_update(libzfs_handle_t *hdl)
|
||||
{
|
||||
FILE *mnttab;
|
||||
struct mnttab entry;
|
||||
|
||||
if ((mnttab = fopen(MNTTAB, "re")) == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
while (getmntent(mnttab, &entry) == 0) {
|
||||
mnttab_node_t *mtn;
|
||||
avl_index_t where;
|
||||
|
||||
if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
|
||||
continue;
|
||||
|
||||
mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
|
||||
mtn->mtn_mt.mnt_special = zfs_strdup(hdl, entry.mnt_special);
|
||||
mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, entry.mnt_mountp);
|
||||
mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, entry.mnt_fstype);
|
||||
mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, entry.mnt_mntopts);
|
||||
|
||||
/* Exclude duplicate mounts */
|
||||
if (avl_find(&hdl->libzfs_mnttab_cache, mtn, &where) != NULL) {
|
||||
free(mtn->mtn_mt.mnt_special);
|
||||
free(mtn->mtn_mt.mnt_mountp);
|
||||
free(mtn->mtn_mt.mnt_fstype);
|
||||
free(mtn->mtn_mt.mnt_mntopts);
|
||||
free(mtn);
|
||||
continue;
|
||||
}
|
||||
|
||||
avl_add(&hdl->libzfs_mnttab_cache, mtn);
|
||||
}
|
||||
|
||||
(void) fclose(mnttab);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
libzfs_mnttab_fini(libzfs_handle_t *hdl)
|
||||
{
|
||||
void *cookie = NULL;
|
||||
mnttab_node_t *mtn;
|
||||
|
||||
while ((mtn = avl_destroy_nodes(&hdl->libzfs_mnttab_cache, &cookie))
|
||||
!= NULL) {
|
||||
free(mtn->mtn_mt.mnt_special);
|
||||
free(mtn->mtn_mt.mnt_mountp);
|
||||
free(mtn->mtn_mt.mnt_fstype);
|
||||
free(mtn->mtn_mt.mnt_mntopts);
|
||||
free(mtn);
|
||||
}
|
||||
avl_destroy(&hdl->libzfs_mnttab_cache);
|
||||
(void) pthread_mutex_destroy(&hdl->libzfs_mnttab_cache_lock);
|
||||
}
|
||||
|
||||
void
|
||||
libzfs_mnttab_cache(libzfs_handle_t *hdl, boolean_t enable)
|
||||
{
|
||||
hdl->libzfs_mnttab_enable = enable;
|
||||
}
|
||||
|
||||
int
|
||||
libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname,
|
||||
struct mnttab *entry)
|
||||
{
|
||||
FILE *mnttab;
|
||||
mnttab_node_t find;
|
||||
mnttab_node_t *mtn;
|
||||
int ret = ENOENT;
|
||||
|
||||
if (!hdl->libzfs_mnttab_enable) {
|
||||
struct mnttab srch = { 0 };
|
||||
|
||||
if (avl_numnodes(&hdl->libzfs_mnttab_cache))
|
||||
libzfs_mnttab_fini(hdl);
|
||||
|
||||
if ((mnttab = fopen(MNTTAB, "re")) == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
srch.mnt_special = (char *)fsname;
|
||||
srch.mnt_fstype = (char *)MNTTYPE_ZFS;
|
||||
ret = getmntany(mnttab, entry, &srch) ? ENOENT : 0;
|
||||
(void) fclose(mnttab);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&hdl->libzfs_mnttab_cache_lock);
|
||||
if (avl_numnodes(&hdl->libzfs_mnttab_cache) == 0) {
|
||||
int error;
|
||||
|
||||
if ((error = libzfs_mnttab_update(hdl)) != 0) {
|
||||
pthread_mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
|
||||
find.mtn_mt.mnt_special = (char *)fsname;
|
||||
mtn = avl_find(&hdl->libzfs_mnttab_cache, &find, NULL);
|
||||
if (mtn) {
|
||||
*entry = mtn->mtn_mt;
|
||||
ret = 0;
|
||||
}
|
||||
pthread_mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
libzfs_mnttab_add(libzfs_handle_t *hdl, const char *special,
|
||||
const char *mountp, const char *mntopts)
|
||||
{
|
||||
mnttab_node_t *mtn;
|
||||
|
||||
pthread_mutex_lock(&hdl->libzfs_mnttab_cache_lock);
|
||||
if (avl_numnodes(&hdl->libzfs_mnttab_cache) != 0) {
|
||||
mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
|
||||
mtn->mtn_mt.mnt_special = zfs_strdup(hdl, special);
|
||||
mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, mountp);
|
||||
mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, MNTTYPE_ZFS);
|
||||
mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, mntopts);
|
||||
/*
|
||||
* Another thread may have already added this entry
|
||||
* via libzfs_mnttab_update. If so we should skip it.
|
||||
*/
|
||||
if (avl_find(&hdl->libzfs_mnttab_cache, mtn, NULL) != NULL) {
|
||||
free(mtn->mtn_mt.mnt_special);
|
||||
free(mtn->mtn_mt.mnt_mountp);
|
||||
free(mtn->mtn_mt.mnt_fstype);
|
||||
free(mtn->mtn_mt.mnt_mntopts);
|
||||
free(mtn);
|
||||
} else {
|
||||
avl_add(&hdl->libzfs_mnttab_cache, mtn);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
|
||||
}
|
||||
|
||||
void
|
||||
libzfs_mnttab_remove(libzfs_handle_t *hdl, const char *fsname)
|
||||
{
|
||||
mnttab_node_t find;
|
||||
mnttab_node_t *ret;
|
||||
|
||||
pthread_mutex_lock(&hdl->libzfs_mnttab_cache_lock);
|
||||
find.mtn_mt.mnt_special = (char *)fsname;
|
||||
if ((ret = avl_find(&hdl->libzfs_mnttab_cache, (void *)&find, NULL))
|
||||
!= NULL) {
|
||||
avl_remove(&hdl->libzfs_mnttab_cache, ret);
|
||||
free(ret->mtn_mt.mnt_special);
|
||||
free(ret->mtn_mt.mnt_mountp);
|
||||
free(ret->mtn_mt.mnt_fstype);
|
||||
free(ret->mtn_mt.mnt_mntopts);
|
||||
free(ret);
|
||||
}
|
||||
pthread_mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
|
||||
}
|
||||
|
||||
int
|
||||
zfs_spa_version(zfs_handle_t *zhp, int *spa_version)
|
||||
{
|
||||
@@ -1701,26 +1517,6 @@ zfs_fix_auto_resv(zfs_handle_t *zhp, nvlist_t *nvl)
|
||||
return (1);
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
zfs_is_namespace_prop(zfs_prop_t prop)
|
||||
{
|
||||
switch (prop) {
|
||||
|
||||
case ZFS_PROP_ATIME:
|
||||
case ZFS_PROP_RELATIME:
|
||||
case ZFS_PROP_DEVICES:
|
||||
case ZFS_PROP_EXEC:
|
||||
case ZFS_PROP_SETUID:
|
||||
case ZFS_PROP_READONLY:
|
||||
case ZFS_PROP_XATTR:
|
||||
case ZFS_PROP_NBMAND:
|
||||
return (B_TRUE);
|
||||
|
||||
default:
|
||||
return (B_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a property name and value, set the property for the given dataset.
|
||||
*/
|
||||
@@ -1778,7 +1574,7 @@ zfs_prop_set_list_flags(zfs_handle_t *zhp, nvlist_t *props, int flags)
|
||||
int nvl_len = 0;
|
||||
int added_resv = 0;
|
||||
zfs_prop_t prop;
|
||||
boolean_t nsprop = B_FALSE;
|
||||
uint32_t nspflags = 0;
|
||||
nvpair_t *elem;
|
||||
|
||||
(void) snprintf(errbuf, sizeof (errbuf),
|
||||
@@ -1825,7 +1621,7 @@ zfs_prop_set_list_flags(zfs_handle_t *zhp, nvlist_t *props, int flags)
|
||||
elem = nvlist_next_nvpair(nvl, elem)) {
|
||||
|
||||
prop = zfs_name_to_prop(nvpair_name(elem));
|
||||
nsprop |= zfs_is_namespace_prop(prop);
|
||||
nspflags |= zfs_namespace_prop_flag(prop);
|
||||
|
||||
assert(cl_idx < nvl_len);
|
||||
/*
|
||||
@@ -1926,8 +1722,8 @@ zfs_prop_set_list_flags(zfs_handle_t *zhp, nvlist_t *props, int flags)
|
||||
* if one of the options handled by the generic
|
||||
* Linux namespace layer has been modified.
|
||||
*/
|
||||
if (nsprop && zfs_is_mounted(zhp, NULL))
|
||||
ret = zfs_mount(zhp, MNTOPT_REMOUNT, 0);
|
||||
if (nspflags && zfs_is_mounted(zhp, NULL))
|
||||
ret = zfs_mount_setattr(zhp, nspflags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2049,7 +1845,8 @@ zfs_prop_inherit(zfs_handle_t *zhp, const char *propname, boolean_t received)
|
||||
*/
|
||||
if (zfs_is_namespace_prop(prop) &&
|
||||
zfs_is_mounted(zhp, NULL))
|
||||
ret = zfs_mount(zhp, MNTOPT_REMOUNT, 0);
|
||||
ret = zfs_mount_setattr(zhp,
|
||||
zfs_namespace_prop_flag(prop));
|
||||
}
|
||||
|
||||
error:
|
||||
@@ -3600,7 +3397,8 @@ zfs_dataset_exists(libzfs_handle_t *hdl, const char *path, zfs_type_t types)
|
||||
* Fail if the initial prefixlen-ancestor does not already exist.
|
||||
*/
|
||||
int
|
||||
create_parents(libzfs_handle_t *hdl, char *target, int prefixlen)
|
||||
create_parents(libzfs_handle_t *hdl, char *target, int prefixlen,
|
||||
nvlist_t *props)
|
||||
{
|
||||
zfs_handle_t *h;
|
||||
char *cp;
|
||||
@@ -3636,8 +3434,7 @@ create_parents(libzfs_handle_t *hdl, char *target, int prefixlen)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (zfs_create(hdl, target, ZFS_TYPE_FILESYSTEM,
|
||||
NULL) != 0) {
|
||||
if (zfs_create(hdl, target, ZFS_TYPE_FILESYSTEM, props) != 0) {
|
||||
opname = dgettext(TEXT_DOMAIN, "create");
|
||||
goto ancestorerr;
|
||||
}
|
||||
@@ -3675,6 +3472,17 @@ ancestorerr:
|
||||
*/
|
||||
int
|
||||
zfs_create_ancestors(libzfs_handle_t *hdl, const char *path)
|
||||
{
|
||||
return (zfs_create_ancestors_props(hdl, path, NULL));
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates non-existing ancestors of the given path, applying extra
|
||||
* properties provided in an nvlist.
|
||||
*/
|
||||
int
|
||||
zfs_create_ancestors_props(libzfs_handle_t *hdl, const char *path,
|
||||
nvlist_t *props)
|
||||
{
|
||||
int prefix;
|
||||
char *path_copy;
|
||||
@@ -3698,7 +3506,7 @@ zfs_create_ancestors(libzfs_handle_t *hdl, const char *path)
|
||||
return (-1);
|
||||
|
||||
if ((path_copy = strdup(path)) != NULL) {
|
||||
rc = create_parents(hdl, path_copy, prefix);
|
||||
rc = create_parents(hdl, path_copy, prefix, props);
|
||||
free(path_copy);
|
||||
}
|
||||
if (path_copy == NULL || rc != 0)
|
||||
|
||||
@@ -821,10 +821,10 @@ zfs_show_diffs(zfs_handle_t *zhp, int outfd, const char *fromsnap,
|
||||
(void) close(pipefd[1]);
|
||||
(void) pthread_join(tid, NULL);
|
||||
|
||||
teardown_differ_info(&di);
|
||||
if (di.zerr != 0) {
|
||||
zfs_error_aux(zhp->zfs_hdl, "%s", zfs_strerror(di.zerr));
|
||||
return (zfs_error(zhp->zfs_hdl, EZFS_DIFF, di.errbuf));
|
||||
}
|
||||
teardown_differ_info(&di);
|
||||
return (0);
|
||||
}
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <sys/nvpair.h>
|
||||
#include <sys/dmu.h>
|
||||
#include <sys/zfs_ioctl.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <regex.h>
|
||||
|
||||
#include <libzfs.h>
|
||||
@@ -57,21 +58,14 @@ struct libzfs_handle {
|
||||
char libzfs_action[1024];
|
||||
char libzfs_desc[1024];
|
||||
int libzfs_printerr;
|
||||
boolean_t libzfs_mnttab_enable;
|
||||
/*
|
||||
* We need a lock to handle the case where parallel mount
|
||||
* threads are populating the mnttab cache simultaneously. The
|
||||
* lock only protects the integrity of the avl tree, and does
|
||||
* not protect the contents of the mnttab entries themselves.
|
||||
*/
|
||||
pthread_mutex_t libzfs_mnttab_cache_lock;
|
||||
avl_tree_t libzfs_mnttab_cache;
|
||||
int libzfs_pool_iter;
|
||||
boolean_t libzfs_prop_debug;
|
||||
regex_t libzfs_urire;
|
||||
uint64_t libzfs_max_nvlist;
|
||||
void *libfetch;
|
||||
char *libfetch_load_error;
|
||||
kmutex_t zh_mnttab_lock;
|
||||
avl_tree_t zh_mnttab;
|
||||
};
|
||||
|
||||
struct zfs_handle {
|
||||
@@ -89,6 +83,19 @@ struct zfs_handle {
|
||||
uint8_t *zfs_props_table;
|
||||
};
|
||||
|
||||
/*
|
||||
* Internal namespace property flags for selective remount via
|
||||
* mount_setattr(2). Passed to zfs_mount_setattr().
|
||||
*/
|
||||
#define ZFS_MNT_PROP_ATIME (1U << 0)
|
||||
#define ZFS_MNT_PROP_RELATIME (1U << 1)
|
||||
#define ZFS_MNT_PROP_DEVICES (1U << 2)
|
||||
#define ZFS_MNT_PROP_EXEC (1U << 3)
|
||||
#define ZFS_MNT_PROP_SETUID (1U << 4)
|
||||
#define ZFS_MNT_PROP_READONLY (1U << 5)
|
||||
#define ZFS_MNT_PROP_XATTR (1U << 6)
|
||||
#define ZFS_MNT_PROP_NBMAND (1U << 7)
|
||||
|
||||
/*
|
||||
* This is different from checking zfs_type, because it will also catch
|
||||
* snapshots of volumes.
|
||||
@@ -181,8 +188,12 @@ extern prop_changelist_t *changelist_gather(zfs_handle_t *, zfs_prop_t, int,
|
||||
extern int changelist_unshare(prop_changelist_t *, const enum sa_protocol *);
|
||||
extern int changelist_haszonedchild(prop_changelist_t *);
|
||||
|
||||
extern boolean_t zfs_is_namespace_prop(zfs_prop_t);
|
||||
extern uint32_t zfs_namespace_prop_flag(zfs_prop_t);
|
||||
extern boolean_t zfs_is_mountable_internal(zfs_handle_t *);
|
||||
extern int zfs_mount_setattr(zfs_handle_t *, uint32_t);
|
||||
extern void remove_mountpoint(zfs_handle_t *);
|
||||
extern int create_parents(libzfs_handle_t *, char *, int);
|
||||
extern int create_parents(libzfs_handle_t *, char *, int, nvlist_t *);
|
||||
|
||||
extern zfs_handle_t *make_dataset_handle(libzfs_handle_t *, const char *);
|
||||
extern zfs_handle_t *make_bookmark_handle(zfs_handle_t *, const char *,
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2019 Joyent, Inc.
|
||||
* Copyright (c) 2011, 2020 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
||||
* Copyright (c) 2013 Martin Matuska. All rights reserved.
|
||||
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
||||
* Copyright 2017 Nexenta Systems, Inc.
|
||||
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
|
||||
* Copyright 2017-2018 RackTop Systems.
|
||||
* Copyright (c) 2019 Datto Inc.
|
||||
* Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>
|
||||
* Copyright (c) 2021 Matt Fiddaman
|
||||
* Copyright (c) 2026, TrueNAS.
|
||||
*/
|
||||
|
||||
#include <sys/mntent.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <libzfs.h>
|
||||
#include "libzfs_impl.h"
|
||||
|
||||
typedef struct mnttab_node {
|
||||
struct mnttab mtn_mt;
|
||||
avl_node_t mtn_node;
|
||||
} mnttab_node_t;
|
||||
|
||||
static mnttab_node_t *
|
||||
mnttab_node_alloc(libzfs_handle_t *hdl, const char *special,
|
||||
const char *mountp, const char *mntopts)
|
||||
{
|
||||
mnttab_node_t *mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
|
||||
mtn->mtn_mt.mnt_special = zfs_strdup(hdl, special);
|
||||
mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, mountp);
|
||||
mtn->mtn_mt.mnt_fstype = (char *)MNTTYPE_ZFS;
|
||||
mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, mntopts);
|
||||
return (mtn);
|
||||
}
|
||||
|
||||
static void
|
||||
mnttab_node_free(libzfs_handle_t *hdl, mnttab_node_t *mtn)
|
||||
{
|
||||
(void) hdl;
|
||||
free(mtn->mtn_mt.mnt_special);
|
||||
free(mtn->mtn_mt.mnt_mountp);
|
||||
free(mtn->mtn_mt.mnt_mntopts);
|
||||
free(mtn);
|
||||
}
|
||||
|
||||
static int
|
||||
mnttab_compare(const void *arg1, const void *arg2)
|
||||
{
|
||||
const mnttab_node_t *mtn1 = (const mnttab_node_t *)arg1;
|
||||
const mnttab_node_t *mtn2 = (const mnttab_node_t *)arg2;
|
||||
int rv;
|
||||
|
||||
rv = strcmp(mtn1->mtn_mt.mnt_special, mtn2->mtn_mt.mnt_special);
|
||||
|
||||
return (TREE_ISIGN(rv));
|
||||
}
|
||||
|
||||
void
|
||||
libzfs_mnttab_init(libzfs_handle_t *hdl)
|
||||
{
|
||||
mutex_init(&hdl->zh_mnttab_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||
assert(avl_numnodes(&hdl->zh_mnttab) == 0);
|
||||
avl_create(&hdl->zh_mnttab, mnttab_compare,
|
||||
sizeof (mnttab_node_t), offsetof(mnttab_node_t, mtn_node));
|
||||
}
|
||||
|
||||
void
|
||||
libzfs_mnttab_fini(libzfs_handle_t *hdl)
|
||||
{
|
||||
void *cookie = NULL;
|
||||
mnttab_node_t *mtn;
|
||||
|
||||
while ((mtn = avl_destroy_nodes(&hdl->zh_mnttab, &cookie))
|
||||
!= NULL)
|
||||
mnttab_node_free(hdl, mtn);
|
||||
|
||||
avl_destroy(&hdl->zh_mnttab);
|
||||
(void) mutex_destroy(&hdl->zh_mnttab_lock);
|
||||
}
|
||||
|
||||
void
|
||||
libzfs_mnttab_cache(libzfs_handle_t *hdl, boolean_t enable)
|
||||
{
|
||||
/* This is a no-op to preserve ABI backward compatibility. */
|
||||
(void) hdl, (void) enable;
|
||||
}
|
||||
|
||||
static int
|
||||
mnttab_update(libzfs_handle_t *hdl)
|
||||
{
|
||||
FILE *mnttab;
|
||||
struct mnttab entry;
|
||||
|
||||
ASSERT(MUTEX_HELD(&hdl->zh_mnttab_lock));
|
||||
|
||||
if ((mnttab = fopen(MNTTAB, "re")) == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
while (getmntent(mnttab, &entry) == 0) {
|
||||
mnttab_node_t *mtn;
|
||||
avl_index_t where;
|
||||
|
||||
if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
|
||||
continue;
|
||||
|
||||
mtn = mnttab_node_alloc(hdl, entry.mnt_special,
|
||||
entry.mnt_mountp, entry.mnt_mntopts);
|
||||
|
||||
/* Exclude duplicate mounts */
|
||||
if (avl_find(&hdl->zh_mnttab, mtn, &where) != NULL) {
|
||||
mnttab_node_free(hdl, mtn);
|
||||
continue;
|
||||
}
|
||||
|
||||
avl_add(&hdl->zh_mnttab, mtn);
|
||||
}
|
||||
|
||||
(void) fclose(mnttab);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname,
|
||||
struct mnttab *entry)
|
||||
{
|
||||
mnttab_node_t find;
|
||||
mnttab_node_t *mtn;
|
||||
int ret = ENOENT;
|
||||
|
||||
mutex_enter(&hdl->zh_mnttab_lock);
|
||||
if (avl_numnodes(&hdl->zh_mnttab) == 0) {
|
||||
int error;
|
||||
|
||||
if ((error = mnttab_update(hdl)) != 0) {
|
||||
mutex_exit(&hdl->zh_mnttab_lock);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
|
||||
find.mtn_mt.mnt_special = (char *)fsname;
|
||||
mtn = avl_find(&hdl->zh_mnttab, &find, NULL);
|
||||
if (mtn) {
|
||||
*entry = mtn->mtn_mt;
|
||||
ret = 0;
|
||||
}
|
||||
mutex_exit(&hdl->zh_mnttab_lock);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
libzfs_mnttab_add(libzfs_handle_t *hdl, const char *special,
|
||||
const char *mountp, const char *mntopts)
|
||||
{
|
||||
mnttab_node_t *mtn;
|
||||
|
||||
mutex_enter(&hdl->zh_mnttab_lock);
|
||||
|
||||
mtn = mnttab_node_alloc(hdl, special, mountp, mntopts);
|
||||
|
||||
/*
|
||||
* Another thread may have already added this entry
|
||||
* via mnttab_update. If so we should skip it.
|
||||
*/
|
||||
if (avl_find(&hdl->zh_mnttab, mtn, NULL) != NULL)
|
||||
mnttab_node_free(hdl, mtn);
|
||||
else
|
||||
avl_add(&hdl->zh_mnttab, mtn);
|
||||
|
||||
mutex_exit(&hdl->zh_mnttab_lock);
|
||||
}
|
||||
|
||||
void
|
||||
libzfs_mnttab_remove(libzfs_handle_t *hdl, const char *fsname)
|
||||
{
|
||||
mnttab_node_t find;
|
||||
mnttab_node_t *ret;
|
||||
|
||||
mutex_enter(&hdl->zh_mnttab_lock);
|
||||
find.mtn_mt.mnt_special = (char *)fsname;
|
||||
if ((ret = avl_find(&hdl->zh_mnttab, (void *)&find, NULL)) != NULL) {
|
||||
avl_remove(&hdl->zh_mnttab, ret);
|
||||
mnttab_node_free(hdl, ret);
|
||||
}
|
||||
mutex_exit(&hdl->zh_mnttab_lock);
|
||||
}
|
||||
@@ -103,6 +103,47 @@ zfs_share_protocol_name(enum sa_protocol protocol)
|
||||
return (sa_protocol_names[protocol]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns B_TRUE if the property is a namespace property that requires
|
||||
* a remount to take effect.
|
||||
*/
|
||||
boolean_t
|
||||
zfs_is_namespace_prop(zfs_prop_t prop)
|
||||
{
|
||||
switch (prop) {
|
||||
case ZFS_PROP_ATIME:
|
||||
case ZFS_PROP_RELATIME:
|
||||
case ZFS_PROP_DEVICES:
|
||||
case ZFS_PROP_EXEC:
|
||||
case ZFS_PROP_SETUID:
|
||||
case ZFS_PROP_READONLY:
|
||||
case ZFS_PROP_XATTR:
|
||||
case ZFS_PROP_NBMAND:
|
||||
return (B_TRUE);
|
||||
default:
|
||||
return (B_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the ZFS_MNT_PROP_* flag for a namespace property.
|
||||
*/
|
||||
uint32_t
|
||||
zfs_namespace_prop_flag(zfs_prop_t prop)
|
||||
{
|
||||
switch (prop) {
|
||||
case ZFS_PROP_ATIME: return (ZFS_MNT_PROP_ATIME);
|
||||
case ZFS_PROP_RELATIME: return (ZFS_MNT_PROP_RELATIME);
|
||||
case ZFS_PROP_DEVICES: return (ZFS_MNT_PROP_DEVICES);
|
||||
case ZFS_PROP_EXEC: return (ZFS_MNT_PROP_EXEC);
|
||||
case ZFS_PROP_SETUID: return (ZFS_MNT_PROP_SETUID);
|
||||
case ZFS_PROP_READONLY: return (ZFS_MNT_PROP_READONLY);
|
||||
case ZFS_PROP_XATTR: return (ZFS_MNT_PROP_XATTR);
|
||||
case ZFS_PROP_NBMAND: return (ZFS_MNT_PROP_NBMAND);
|
||||
default: return (0);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
dir_is_empty_stat(const char *dirname)
|
||||
{
|
||||
@@ -225,7 +266,7 @@ zfs_is_mounted(zfs_handle_t *zhp, char **where)
|
||||
* that the caller has verified the sanity of mounting the dataset at
|
||||
* its mountpoint to the extent the caller wants.
|
||||
*/
|
||||
static boolean_t
|
||||
boolean_t
|
||||
zfs_is_mountable_internal(zfs_handle_t *zhp)
|
||||
{
|
||||
if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED) &&
|
||||
|
||||
@@ -370,8 +370,47 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf,
|
||||
zfs_fallthrough;
|
||||
|
||||
case ZPOOL_PROP_SIZE:
|
||||
case ZPOOL_PROP_NORMAL_SIZE:
|
||||
case ZPOOL_PROP_SPECIAL_SIZE:
|
||||
case ZPOOL_PROP_DEDUP_SIZE:
|
||||
case ZPOOL_PROP_LOG_SIZE:
|
||||
case ZPOOL_PROP_ELOG_SIZE:
|
||||
case ZPOOL_PROP_SELOG_SIZE:
|
||||
case ZPOOL_PROP_ALLOCATED:
|
||||
case ZPOOL_PROP_NORMAL_ALLOCATED:
|
||||
case ZPOOL_PROP_SPECIAL_ALLOCATED:
|
||||
case ZPOOL_PROP_DEDUP_ALLOCATED:
|
||||
case ZPOOL_PROP_LOG_ALLOCATED:
|
||||
case ZPOOL_PROP_ELOG_ALLOCATED:
|
||||
case ZPOOL_PROP_SELOG_ALLOCATED:
|
||||
case ZPOOL_PROP_AVAILABLE:
|
||||
case ZPOOL_PROP_NORMAL_AVAILABLE:
|
||||
case ZPOOL_PROP_SPECIAL_AVAILABLE:
|
||||
case ZPOOL_PROP_DEDUP_AVAILABLE:
|
||||
case ZPOOL_PROP_LOG_AVAILABLE:
|
||||
case ZPOOL_PROP_ELOG_AVAILABLE:
|
||||
case ZPOOL_PROP_SELOG_AVAILABLE:
|
||||
case ZPOOL_PROP_FREE:
|
||||
case ZPOOL_PROP_NORMAL_FREE:
|
||||
case ZPOOL_PROP_SPECIAL_FREE:
|
||||
case ZPOOL_PROP_DEDUP_FREE:
|
||||
case ZPOOL_PROP_LOG_FREE:
|
||||
case ZPOOL_PROP_ELOG_FREE:
|
||||
case ZPOOL_PROP_SELOG_FREE:
|
||||
case ZPOOL_PROP_USABLE:
|
||||
case ZPOOL_PROP_NORMAL_USABLE:
|
||||
case ZPOOL_PROP_SPECIAL_USABLE:
|
||||
case ZPOOL_PROP_DEDUP_USABLE:
|
||||
case ZPOOL_PROP_LOG_USABLE:
|
||||
case ZPOOL_PROP_ELOG_USABLE:
|
||||
case ZPOOL_PROP_SELOG_USABLE:
|
||||
case ZPOOL_PROP_USED:
|
||||
case ZPOOL_PROP_NORMAL_USED:
|
||||
case ZPOOL_PROP_SPECIAL_USED:
|
||||
case ZPOOL_PROP_DEDUP_USED:
|
||||
case ZPOOL_PROP_LOG_USED:
|
||||
case ZPOOL_PROP_ELOG_USED:
|
||||
case ZPOOL_PROP_SELOG_USED:
|
||||
case ZPOOL_PROP_FREEING:
|
||||
case ZPOOL_PROP_LEAKED:
|
||||
case ZPOOL_PROP_ASHIFT:
|
||||
@@ -391,6 +430,12 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf,
|
||||
break;
|
||||
|
||||
case ZPOOL_PROP_EXPANDSZ:
|
||||
case ZPOOL_PROP_NORMAL_EXPANDSZ:
|
||||
case ZPOOL_PROP_SPECIAL_EXPANDSZ:
|
||||
case ZPOOL_PROP_DEDUP_EXPANDSZ:
|
||||
case ZPOOL_PROP_LOG_EXPANDSZ:
|
||||
case ZPOOL_PROP_ELOG_EXPANDSZ:
|
||||
case ZPOOL_PROP_SELOG_EXPANDSZ:
|
||||
case ZPOOL_PROP_CHECKPOINT:
|
||||
if (intval == 0) {
|
||||
(void) strlcpy(buf, "-", len);
|
||||
@@ -403,6 +448,12 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf,
|
||||
break;
|
||||
|
||||
case ZPOOL_PROP_CAPACITY:
|
||||
case ZPOOL_PROP_NORMAL_CAPACITY:
|
||||
case ZPOOL_PROP_SPECIAL_CAPACITY:
|
||||
case ZPOOL_PROP_DEDUP_CAPACITY:
|
||||
case ZPOOL_PROP_LOG_CAPACITY:
|
||||
case ZPOOL_PROP_ELOG_CAPACITY:
|
||||
case ZPOOL_PROP_SELOG_CAPACITY:
|
||||
if (literal) {
|
||||
(void) snprintf(buf, len, "%llu",
|
||||
(u_longlong_t)intval);
|
||||
@@ -413,7 +464,13 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf,
|
||||
break;
|
||||
|
||||
case ZPOOL_PROP_FRAGMENTATION:
|
||||
if (intval == UINT64_MAX) {
|
||||
case ZPOOL_PROP_NORMAL_FRAGMENTATION:
|
||||
case ZPOOL_PROP_SPECIAL_FRAGMENTATION:
|
||||
case ZPOOL_PROP_DEDUP_FRAGMENTATION:
|
||||
case ZPOOL_PROP_LOG_FRAGMENTATION:
|
||||
case ZPOOL_PROP_ELOG_FRAGMENTATION:
|
||||
case ZPOOL_PROP_SELOG_FRAGMENTATION:
|
||||
if (intval == ZFS_FRAG_INVALID) {
|
||||
(void) strlcpy(buf, "-", len);
|
||||
} else if (literal) {
|
||||
(void) snprintf(buf, len, "%llu",
|
||||
@@ -1639,6 +1696,11 @@ zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
|
||||
"one or more devices could not be opened"));
|
||||
return (zfs_error(hdl, EZFS_BADDEV, errbuf));
|
||||
|
||||
case EDOM:
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"block size out of range or does not match"));
|
||||
return (zfs_error(hdl, EZFS_BADDEV, errbuf));
|
||||
|
||||
default:
|
||||
return (zpool_standard_error(hdl, errno, errbuf));
|
||||
}
|
||||
@@ -2806,8 +2868,11 @@ zpool_scan_range(zpool_handle_t *zhp, pool_scan_func_t func,
|
||||
nvlist_t *args = fnvlist_alloc();
|
||||
fnvlist_add_uint64(args, "scan_type", (uint64_t)func);
|
||||
fnvlist_add_uint64(args, "scan_command", (uint64_t)cmd);
|
||||
fnvlist_add_uint64(args, "scan_date_start", (uint64_t)date_start);
|
||||
fnvlist_add_uint64(args, "scan_date_end", (uint64_t)date_end);
|
||||
if (date_start != 0 || date_end != 0) {
|
||||
fnvlist_add_uint64(args, "scan_date_start",
|
||||
(uint64_t)date_start);
|
||||
fnvlist_add_uint64(args, "scan_date_end", (uint64_t)date_end);
|
||||
}
|
||||
|
||||
err = lzc_scrub(ZFS_IOC_POOL_SCRUB, zhp->zpool_name, args, NULL);
|
||||
fnvlist_free(args);
|
||||
@@ -4350,7 +4415,8 @@ zpool_clear(zpool_handle_t *zhp, const char *path, nvlist_t *rewindnvl)
|
||||
zc.zc_cookie = policy.zlp_rewind;
|
||||
|
||||
zcmd_alloc_dst_nvlist(hdl, &zc, zhp->zpool_config_size * 2);
|
||||
zcmd_write_src_nvlist(hdl, &zc, rewindnvl);
|
||||
if (rewindnvl != NULL)
|
||||
zcmd_write_src_nvlist(hdl, &zc, rewindnvl);
|
||||
|
||||
while ((error = zfs_ioctl(hdl, ZFS_IOC_CLEAR, &zc)) != 0 &&
|
||||
errno == ENOMEM)
|
||||
|
||||
@@ -258,7 +258,10 @@ typedef struct send_data {
|
||||
boolean_t seento;
|
||||
boolean_t holds; /* were holds requested with send -h */
|
||||
boolean_t props;
|
||||
boolean_t no_preserve_encryption;
|
||||
|
||||
snapfilter_cb_t *filter_cb;
|
||||
void *filter_cb_arg;
|
||||
/*
|
||||
* The header nvlist is of the following format:
|
||||
* {
|
||||
@@ -511,6 +514,10 @@ send_iterate_fs(zfs_handle_t *zhp, void *arg)
|
||||
uint64_t fromsnap_txg_save = sd->fromsnap_txg;
|
||||
uint64_t tosnap_txg_save = sd->tosnap_txg;
|
||||
|
||||
if (sd->filter_cb &&
|
||||
(sd->filter_cb(zhp, sd->filter_cb_arg) == 0))
|
||||
return (0);
|
||||
|
||||
fromsnap_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name, sd->fromsnap);
|
||||
if (fromsnap_txg != 0)
|
||||
sd->fromsnap_txg = fromsnap_txg;
|
||||
@@ -587,20 +594,32 @@ send_iterate_fs(zfs_handle_t *zhp, void *arg)
|
||||
fnvlist_add_boolean(nvfs, "is_encroot");
|
||||
|
||||
/*
|
||||
* Encrypted datasets can only be sent with properties if
|
||||
* the raw flag is specified because the receive side doesn't
|
||||
* currently have a mechanism for recursively asking the user
|
||||
* for new encryption parameters.
|
||||
* Encrypted datasets can only be sent with properties if the
|
||||
* raw flag or the no-preserve-encryption flag are specified
|
||||
* because the receive side doesn't currently have a mechanism
|
||||
* for recursively asking the user for new encryption
|
||||
* parameters.
|
||||
* We allow sending the dataset unencrypted only if the user
|
||||
* explicitly sets the no-preserve-encryption flag.
|
||||
*/
|
||||
if (!sd->raw) {
|
||||
if (!sd->raw && !sd->no_preserve_encryption) {
|
||||
(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
|
||||
"cannot send %s@%s: encrypted dataset %s may not "
|
||||
"be sent with properties without the raw flag\n"),
|
||||
"be sent with properties without the raw flag or "
|
||||
"no-preserve-encryption flag\n"),
|
||||
sd->fsname, sd->tosnap, zhp->zfs_name);
|
||||
rv = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* If no-preserve-encryption flag is set, warn the user again */
|
||||
if (!sd->raw && sd->no_preserve_encryption) {
|
||||
(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
|
||||
"WARNING: no-preserve-encryption flag set, sending "
|
||||
"dataset %s without encryption\n"),
|
||||
zhp->zfs_name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -683,8 +702,9 @@ static int
|
||||
gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
|
||||
const char *tosnap, boolean_t recursive, boolean_t raw, boolean_t doall,
|
||||
boolean_t replicate, boolean_t skipmissing, boolean_t verbose,
|
||||
boolean_t backup, boolean_t holds, boolean_t props, nvlist_t **nvlp,
|
||||
avl_tree_t **avlp)
|
||||
boolean_t backup, boolean_t holds, boolean_t props,
|
||||
boolean_t no_preserve_encryption, nvlist_t **nvlp, avl_tree_t **avlp,
|
||||
snapfilter_cb_t *filter_cb, void *filter_cb_arg)
|
||||
{
|
||||
zfs_handle_t *zhp;
|
||||
send_data_t sd = { 0 };
|
||||
@@ -707,6 +727,9 @@ gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
|
||||
sd.backup = backup;
|
||||
sd.holds = holds;
|
||||
sd.props = props;
|
||||
sd.no_preserve_encryption = no_preserve_encryption;
|
||||
sd.filter_cb = filter_cb;
|
||||
sd.filter_cb_arg = filter_cb_arg;
|
||||
|
||||
if ((error = send_iterate_fs(zhp, &sd)) != 0) {
|
||||
fnvlist_free(sd.fss);
|
||||
@@ -913,21 +936,8 @@ int
|
||||
zfs_send_progress(zfs_handle_t *zhp, int fd, uint64_t *bytes_written,
|
||||
uint64_t *blocks_visited)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
|
||||
if (bytes_written != NULL)
|
||||
*bytes_written = 0;
|
||||
if (blocks_visited != NULL)
|
||||
*blocks_visited = 0;
|
||||
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
|
||||
zc.zc_cookie = fd;
|
||||
if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND_PROGRESS, &zc) != 0)
|
||||
return (errno);
|
||||
if (bytes_written != NULL)
|
||||
*bytes_written = zc.zc_cookie;
|
||||
if (blocks_visited != NULL)
|
||||
*blocks_visited = zc.zc_objset_type;
|
||||
return (0);
|
||||
return (lzc_send_progress(zhp->zfs_name, fd, bytes_written,
|
||||
blocks_visited));
|
||||
}
|
||||
|
||||
static volatile boolean_t send_progress_thread_signal_duetotimer;
|
||||
@@ -2199,7 +2209,8 @@ send_prelim_records(zfs_handle_t *zhp, const char *from, int fd,
|
||||
boolean_t gather_props, boolean_t recursive, boolean_t verbose,
|
||||
boolean_t dryrun, boolean_t raw, boolean_t replicate, boolean_t skipmissing,
|
||||
boolean_t backup, boolean_t holds, boolean_t props, boolean_t doall,
|
||||
nvlist_t **fssp, avl_tree_t **fsavlp)
|
||||
boolean_t no_preserve_encryption, nvlist_t **fssp, avl_tree_t **fsavlp,
|
||||
snapfilter_cb_t filter_func, void *cb_arg)
|
||||
{
|
||||
int err = 0;
|
||||
char *packbuf = NULL;
|
||||
@@ -2245,7 +2256,8 @@ send_prelim_records(zfs_handle_t *zhp, const char *from, int fd,
|
||||
|
||||
if (gather_nvlist(zhp->zfs_hdl, tofs,
|
||||
from, tosnap, recursive, raw, doall, replicate, skipmissing,
|
||||
verbose, backup, holds, props, &fss, fsavlp) != 0) {
|
||||
verbose, backup, holds, props, no_preserve_encryption,
|
||||
&fss, fsavlp, filter_func, cb_arg) != 0) {
|
||||
return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
|
||||
errbuf));
|
||||
}
|
||||
@@ -2392,7 +2404,8 @@ zfs_send_cb_impl(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
|
||||
flags->replicate, flags->verbosity > 0, flags->dryrun,
|
||||
flags->raw, flags->replicate, flags->skipmissing,
|
||||
flags->backup, flags->holds, flags->props, flags->doall,
|
||||
&fss, &fsavl);
|
||||
flags->no_preserve_encryption, &fss, &fsavl,
|
||||
filter_func, cb_arg);
|
||||
zfs_close(tosnap);
|
||||
if (err != 0)
|
||||
goto err_out;
|
||||
@@ -2735,7 +2748,8 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd,
|
||||
err = send_prelim_records(zhp, NULL, fd, B_TRUE, B_FALSE,
|
||||
flags->verbosity > 0, flags->dryrun, flags->raw,
|
||||
flags->replicate, B_FALSE, flags->backup, flags->holds,
|
||||
flags->props, flags->doall, NULL, NULL);
|
||||
flags->props, flags->doall, flags->no_preserve_encryption,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (err != 0)
|
||||
return (err);
|
||||
}
|
||||
@@ -3392,7 +3406,8 @@ recv_fix_encryption_hierarchy(libzfs_handle_t *hdl, const char *top_zfs,
|
||||
/* Using top_zfs, gather the nvlists for all local filesystems. */
|
||||
if ((err = gather_nvlist(hdl, top_zfs, NULL, NULL,
|
||||
recursive, B_TRUE, B_FALSE, recursive, B_FALSE, B_FALSE, B_FALSE,
|
||||
B_FALSE, B_TRUE, &local_nv, &local_avl)) != 0)
|
||||
B_FALSE, B_TRUE, B_FALSE, &local_nv, &local_avl,
|
||||
NULL, NULL)) != 0)
|
||||
return (err);
|
||||
|
||||
/*
|
||||
@@ -3547,7 +3562,8 @@ again:
|
||||
|
||||
if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL,
|
||||
recursive, B_TRUE, B_FALSE, recursive, B_FALSE, B_FALSE, B_FALSE,
|
||||
B_FALSE, B_TRUE, &local_nv, &local_avl)) != 0)
|
||||
B_FALSE, B_TRUE, B_FALSE, &local_nv, &local_avl,
|
||||
NULL, NULL)) != 0)
|
||||
return (error);
|
||||
|
||||
/*
|
||||
@@ -4944,7 +4960,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
||||
*cp = '\0';
|
||||
|
||||
if (flags->isprefix && !flags->istail && !flags->dryrun &&
|
||||
create_parents(hdl, destsnap, strlen(tosnap)) != 0) {
|
||||
create_parents(hdl, destsnap, strlen(tosnap), NULL) != 0) {
|
||||
err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
|
||||
goto out;
|
||||
}
|
||||
@@ -5138,7 +5154,8 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
||||
*cp = '\0';
|
||||
if (gather_nvlist(hdl, destsnap, NULL, NULL, B_FALSE, B_TRUE,
|
||||
B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE,
|
||||
B_TRUE, &local_nv, &local_avl) == 0) {
|
||||
B_TRUE, B_FALSE, &local_nv, &local_avl,
|
||||
NULL, NULL) == 0) {
|
||||
*cp = '@';
|
||||
fs = fsavl_find(local_avl, drrb->drr_toguid, NULL);
|
||||
fsavl_destroy(local_avl);
|
||||
|
||||
@@ -1171,7 +1171,7 @@ zfs_handle_t *
|
||||
zfs_path_to_zhandle(libzfs_handle_t *hdl, const char *path, zfs_type_t argtype)
|
||||
{
|
||||
struct stat64 statbuf;
|
||||
struct extmnttab entry;
|
||||
struct mnttab entry;
|
||||
|
||||
if (path[0] != '/' && strncmp(path, "./", strlen("./")) != 0) {
|
||||
/*
|
||||
|
||||
@@ -116,6 +116,17 @@ do_unmount(zfs_handle_t *zhp, const char *mntpt, int flags)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* FreeBSD does not support mount_setattr(2). Fall back to a full
|
||||
* remount so that the updated namespace property takes effect.
|
||||
*/
|
||||
int
|
||||
zfs_mount_setattr(zfs_handle_t *zhp, uint32_t nspflags)
|
||||
{
|
||||
(void) nspflags;
|
||||
return (zfs_mount(zhp, MNTOPT_REMOUNT, 0));
|
||||
}
|
||||
|
||||
int
|
||||
zfs_mount_delegation_check(void)
|
||||
{
|
||||
|
||||
@@ -409,6 +409,149 @@ do_unmount(zfs_handle_t *zhp, const char *mntpt, int flags)
|
||||
return (rc ? EINVAL : 0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_MOUNT_SETATTR
|
||||
/*
|
||||
* Build a struct mount_attr for the changed namespace properties.
|
||||
* Parallel to zfs_add_options() but produces mount_setattr(2) input
|
||||
* instead of a mount options string.
|
||||
*/
|
||||
static void
|
||||
zfs_add_options_setattr(zfs_handle_t *zhp, struct mount_attr *attr,
|
||||
uint32_t nspflags)
|
||||
{
|
||||
const char *source;
|
||||
|
||||
if (nspflags & ZFS_MNT_PROP_READONLY) {
|
||||
if (getprop_uint64(zhp, ZFS_PROP_READONLY, &source))
|
||||
attr->attr_set |= MOUNT_ATTR_RDONLY;
|
||||
else
|
||||
attr->attr_clr |= MOUNT_ATTR_RDONLY;
|
||||
}
|
||||
if (nspflags & ZFS_MNT_PROP_EXEC) {
|
||||
if (getprop_uint64(zhp, ZFS_PROP_EXEC, &source))
|
||||
attr->attr_clr |= MOUNT_ATTR_NOEXEC;
|
||||
else
|
||||
attr->attr_set |= MOUNT_ATTR_NOEXEC;
|
||||
}
|
||||
if (nspflags & ZFS_MNT_PROP_SETUID) {
|
||||
if (getprop_uint64(zhp, ZFS_PROP_SETUID, &source))
|
||||
attr->attr_clr |= MOUNT_ATTR_NOSUID;
|
||||
else
|
||||
attr->attr_set |= MOUNT_ATTR_NOSUID;
|
||||
}
|
||||
if (nspflags & ZFS_MNT_PROP_DEVICES) {
|
||||
if (getprop_uint64(zhp, ZFS_PROP_DEVICES, &source))
|
||||
attr->attr_clr |= MOUNT_ATTR_NODEV;
|
||||
else
|
||||
attr->attr_set |= MOUNT_ATTR_NODEV;
|
||||
}
|
||||
if (nspflags & (ZFS_MNT_PROP_ATIME | ZFS_MNT_PROP_RELATIME)) {
|
||||
uint64_t atime = getprop_uint64(zhp, ZFS_PROP_ATIME, &source);
|
||||
uint64_t relatime = getprop_uint64(zhp,
|
||||
ZFS_PROP_RELATIME, &source);
|
||||
|
||||
attr->attr_clr |= MOUNT_ATTR__ATIME;
|
||||
if (!atime)
|
||||
attr->attr_set |= MOUNT_ATTR_NOATIME;
|
||||
else if (relatime)
|
||||
attr->attr_set |= MOUNT_ATTR_RELATIME;
|
||||
else
|
||||
attr->attr_set |= MOUNT_ATTR_STRICTATIME;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_MOUNT_SETATTR */
|
||||
|
||||
/*
|
||||
* Selectively update per-mount VFS flags for the changed namespace
|
||||
* properties using mount_setattr(2). Unlike a full remount via mount(2),
|
||||
* this only modifies the specified flags without resetting others --
|
||||
* avoiding clobbering temporary mount flags set by the administrator.
|
||||
*
|
||||
* For non-legacy datasets, the single known mountpoint is used.
|
||||
* For legacy datasets, /proc/mounts is iterated since legacy datasets
|
||||
* can be mounted at multiple locations.
|
||||
*
|
||||
* Falls back to a full remount via zfs_mount() when mount_setattr(2)
|
||||
* is not available (ENOSYS), except for legacy mounts where a full
|
||||
* remount would clobber temporary flags.
|
||||
*/
|
||||
int
|
||||
zfs_mount_setattr(zfs_handle_t *zhp, uint32_t nspflags)
|
||||
{
|
||||
#ifdef HAVE_MOUNT_SETATTR
|
||||
struct mount_attr attr = { 0 };
|
||||
char mntpt_prop[ZFS_MAXPROPLEN];
|
||||
boolean_t legacy = B_FALSE;
|
||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||
FILE *mnttab;
|
||||
struct mnttab entry;
|
||||
int ret = 0;
|
||||
|
||||
if (!zfs_is_mountable_internal(zhp))
|
||||
return (0);
|
||||
|
||||
zfs_add_options_setattr(zhp, &attr, nspflags);
|
||||
if (attr.attr_set == 0 && attr.attr_clr == 0)
|
||||
return (0);
|
||||
|
||||
if (zfs_prop_valid_for_type(ZFS_PROP_MOUNTPOINT, zhp->zfs_type,
|
||||
B_FALSE)) {
|
||||
verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mntpt_prop,
|
||||
sizeof (mntpt_prop), NULL, NULL, 0, B_FALSE) == 0);
|
||||
legacy = (strcmp(mntpt_prop, ZFS_MOUNTPOINT_LEGACY) == 0);
|
||||
}
|
||||
|
||||
if (!legacy) {
|
||||
char *mntpt = NULL;
|
||||
|
||||
if (!zfs_is_mounted(zhp, &mntpt))
|
||||
return (0);
|
||||
|
||||
ret = mount_setattr(AT_FDCWD, mntpt, 0,
|
||||
&attr, sizeof (attr));
|
||||
free(mntpt);
|
||||
if (ret != 0) {
|
||||
if (errno == ENOSYS)
|
||||
return (zfs_mount(zhp, MNTOPT_REMOUNT, 0));
|
||||
return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
|
||||
dgettext(TEXT_DOMAIN, "cannot set mount "
|
||||
"attributes for '%s'"), zhp->zfs_name));
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Legacy: iterate /proc/mounts for all mountpoints. */
|
||||
if ((mnttab = fopen(MNTTAB, "re")) == NULL)
|
||||
return (0);
|
||||
|
||||
while (getmntent(mnttab, &entry) == 0) {
|
||||
if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
|
||||
continue;
|
||||
if (strcmp(entry.mnt_special, zhp->zfs_name) != 0)
|
||||
continue;
|
||||
|
||||
ret = mount_setattr(AT_FDCWD, entry.mnt_mountp, 0,
|
||||
&attr, sizeof (attr));
|
||||
if (ret != 0) {
|
||||
if (errno == ENOSYS) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
ret = zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
|
||||
dgettext(TEXT_DOMAIN, "cannot set mount "
|
||||
"attributes for '%s'"), zhp->zfs_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
(void) fclose(mnttab);
|
||||
return (ret);
|
||||
#else
|
||||
(void) nspflags;
|
||||
return (zfs_mount(zhp, MNTOPT_REMOUNT, 0));
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
zfs_mount_delegation_check(void)
|
||||
{
|
||||
|
||||
@@ -147,7 +147,6 @@
|
||||
<elf-symbol name='get_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='getexecname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='getextmntent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='getmntany' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='getzoneid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='kmem_asprintf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='kmem_cache_reap_active' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
@@ -224,6 +223,7 @@
|
||||
<elf-symbol name='lzc_rollback_to' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='lzc_scrub' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='lzc_send' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='lzc_send_progress' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='lzc_send_redacted' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='lzc_send_resume' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='lzc_send_resume_redacted' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
@@ -1488,7 +1488,7 @@
|
||||
<return type-id='7359adad'/>
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/os/linux/getmntany.c' language='LANG_C99'>
|
||||
<abi-instr address-size='64' path='lib/libspl/os/linux/mnttab.c' language='LANG_C99'>
|
||||
<class-decl name='mnttab' size-in-bits='256' is-struct='yes' visibility='default' id='1b055409'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='mnt_special' type-id='26a90f95' visibility='default'/>
|
||||
@@ -1503,26 +1503,6 @@
|
||||
<var-decl name='mnt_mntopts' type-id='26a90f95' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='extmnttab' size-in-bits='320' is-struct='yes' visibility='default' id='0c544dc0'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='mnt_special' type-id='26a90f95' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='mnt_mountp' type-id='26a90f95' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<var-decl name='mnt_fstype' type-id='26a90f95' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='192'>
|
||||
<var-decl name='mnt_mntopts' type-id='26a90f95' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='256'>
|
||||
<var-decl name='mnt_major' type-id='3502e3ff' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='288'>
|
||||
<var-decl name='mnt_minor' type-id='3502e3ff' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='mntent' size-in-bits='320' is-struct='yes' visibility='default' id='56fe4a37'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='mnt_fsname' type-id='26a90f95' visibility='default'/>
|
||||
@@ -1592,7 +1572,6 @@
|
||||
</class-decl>
|
||||
<typedef-decl name='__ino64_t' type-id='7359adad' id='71288a47'/>
|
||||
<typedef-decl name='__blkcnt64_t' type-id='bd54fe1a' id='4e711bf1'/>
|
||||
<pointer-type-def type-id='0c544dc0' size-in-bits='64' id='394fc496'/>
|
||||
<pointer-type-def type-id='56fe4a37' size-in-bits='64' id='b6b61d2f'/>
|
||||
<qualified-type-def type-id='b6b61d2f' restrict='yes' id='3cad23cd'/>
|
||||
<pointer-type-def type-id='1b055409' size-in-bits='64' id='9d424d31'/>
|
||||
@@ -1618,12 +1597,6 @@
|
||||
<parameter type-id='f1cadedf'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='getmntany' mangled-name='getmntany' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getmntany'>
|
||||
<parameter type-id='822cd80b' name='fp'/>
|
||||
<parameter type-id='9d424d31' name='mgetp'/>
|
||||
<parameter type-id='9d424d31' name='mrefp'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='_sol_getmntent' mangled-name='_sol_getmntent' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_sol_getmntent'>
|
||||
<parameter type-id='822cd80b' name='fp'/>
|
||||
<parameter type-id='9d424d31' name='mgetp'/>
|
||||
@@ -1631,7 +1604,7 @@
|
||||
</function-decl>
|
||||
<function-decl name='getextmntent' mangled-name='getextmntent' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getextmntent'>
|
||||
<parameter type-id='80f4b756' name='path'/>
|
||||
<parameter type-id='394fc496' name='entry'/>
|
||||
<parameter type-id='9d424d31' name='entry'/>
|
||||
<parameter type-id='62f7a03d' name='statbuf'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
@@ -4004,6 +3977,13 @@
|
||||
<parameter type-id='5d6479ae' name='spacep'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='lzc_send_progress' mangled-name='lzc_send_progress' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzc_send_progress'>
|
||||
<parameter type-id='80f4b756' name='snapname'/>
|
||||
<parameter type-id='95e97e5e' name='fd'/>
|
||||
<parameter type-id='5d6479ae' name='bytes_written'/>
|
||||
<parameter type-id='5d6479ae' name='blocks_visited'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='lzc_receive' mangled-name='lzc_receive' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzc_receive'>
|
||||
<parameter type-id='80f4b756' name='snapname'/>
|
||||
<parameter type-id='5ce45b60' name='props'/>
|
||||
|
||||
@@ -1016,6 +1016,39 @@ lzc_send_space(const char *snapname, const char *from,
|
||||
NULL, -1, spacep));
|
||||
}
|
||||
|
||||
/*
|
||||
* Query the progress of a send stream identified by the snapshot name and
|
||||
* the file descriptor the stream is being written to.
|
||||
*
|
||||
* snapname name of the snapshot being sent
|
||||
* fd file descriptor of the active send stream
|
||||
* bytes_written on success, set to the number of bytes sent so far
|
||||
* blocks_visited on success, set to the number of logical blocks traversed
|
||||
*
|
||||
* Returns 0 on success. Returns ENOENT if no send stream matching the
|
||||
* snapshot name and file descriptor was found in the current process.
|
||||
*/
|
||||
int
|
||||
lzc_send_progress(const char *snapname, int fd, uint64_t *bytes_written,
|
||||
uint64_t *blocks_visited)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
|
||||
if (bytes_written != NULL)
|
||||
*bytes_written = 0;
|
||||
if (blocks_visited != NULL)
|
||||
*blocks_visited = 0;
|
||||
(void) strlcpy(zc.zc_name, snapname, sizeof (zc.zc_name));
|
||||
zc.zc_cookie = fd;
|
||||
if (lzc_ioctl_fd(g_fd, ZFS_IOC_SEND_PROGRESS, &zc) != 0)
|
||||
return (errno);
|
||||
if (bytes_written != NULL)
|
||||
*bytes_written = zc.zc_cookie;
|
||||
if (blocks_visited != NULL)
|
||||
*blocks_visited = zc.zc_objset_type;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
recv_read(int fd, void *buf, int ilen)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ dist_libzpool_la_SOURCES = \
|
||||
%D%/kernel.c \
|
||||
%D%/util.c \
|
||||
%D%/vdev_label_os.c \
|
||||
%D%/zfs_file_os.c \
|
||||
%D%/zfs_racct.c \
|
||||
%D%/zfs_debug.c
|
||||
|
||||
|
||||
@@ -62,9 +62,6 @@
|
||||
|
||||
uint32_t hostid;
|
||||
|
||||
/* If set, all blocks read will be copied to the specified directory. */
|
||||
char *vn_dumpdir = NULL;
|
||||
|
||||
uint32_t
|
||||
zone_get_hostid(void *zonep)
|
||||
{
|
||||
@@ -495,391 +492,6 @@ zvol_rename_minors(spa_t *spa, const char *oldname, const char *newname,
|
||||
(void) spa, (void) oldname, (void) newname, (void) async;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open file
|
||||
*
|
||||
* path - fully qualified path to file
|
||||
* flags - file attributes O_READ / O_WRITE / O_EXCL
|
||||
* fpp - pointer to return file pointer
|
||||
*
|
||||
* Returns 0 on success underlying error on failure.
|
||||
*/
|
||||
int
|
||||
zfs_file_open(const char *path, int flags, int mode, zfs_file_t **fpp)
|
||||
{
|
||||
int fd;
|
||||
int dump_fd;
|
||||
int err;
|
||||
int old_umask = 0;
|
||||
zfs_file_t *fp;
|
||||
struct stat64 st;
|
||||
|
||||
if (!(flags & O_CREAT) && stat64(path, &st) == -1)
|
||||
return (errno);
|
||||
|
||||
if (!(flags & O_CREAT) && S_ISBLK(st.st_mode))
|
||||
flags |= O_DIRECT;
|
||||
|
||||
if (flags & O_CREAT)
|
||||
old_umask = umask(0);
|
||||
|
||||
fd = open64(path, flags, mode);
|
||||
if (fd == -1)
|
||||
return (errno);
|
||||
|
||||
if (flags & O_CREAT)
|
||||
(void) umask(old_umask);
|
||||
|
||||
if (vn_dumpdir != NULL) {
|
||||
char *dumppath = umem_zalloc(MAXPATHLEN, UMEM_NOFAIL);
|
||||
const char *inpath = zfs_basename(path);
|
||||
|
||||
(void) snprintf(dumppath, MAXPATHLEN,
|
||||
"%s/%s", vn_dumpdir, inpath);
|
||||
dump_fd = open64(dumppath, O_CREAT | O_WRONLY, 0666);
|
||||
umem_free(dumppath, MAXPATHLEN);
|
||||
if (dump_fd == -1) {
|
||||
err = errno;
|
||||
close(fd);
|
||||
return (err);
|
||||
}
|
||||
} else {
|
||||
dump_fd = -1;
|
||||
}
|
||||
|
||||
(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
fp = umem_zalloc(sizeof (zfs_file_t), UMEM_NOFAIL);
|
||||
fp->f_fd = fd;
|
||||
fp->f_dump_fd = dump_fd;
|
||||
*fpp = fp;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
zfs_file_close(zfs_file_t *fp)
|
||||
{
|
||||
close(fp->f_fd);
|
||||
if (fp->f_dump_fd != -1)
|
||||
close(fp->f_dump_fd);
|
||||
|
||||
umem_free(fp, sizeof (zfs_file_t));
|
||||
}
|
||||
|
||||
/*
|
||||
* Stateful write - use os internal file pointer to determine where to
|
||||
* write and update on successful completion.
|
||||
*
|
||||
* fp - pointer to file (pipe, socket, etc) to write to
|
||||
* buf - buffer to write
|
||||
* count - # of bytes to write
|
||||
* resid - pointer to count of unwritten bytes (if short write)
|
||||
*
|
||||
* Returns 0 on success errno on failure.
|
||||
*/
|
||||
int
|
||||
zfs_file_write(zfs_file_t *fp, const void *buf, size_t count, ssize_t *resid)
|
||||
{
|
||||
ssize_t rc;
|
||||
|
||||
rc = write(fp->f_fd, buf, count);
|
||||
if (rc < 0)
|
||||
return (errno);
|
||||
|
||||
if (resid) {
|
||||
*resid = count - rc;
|
||||
} else if (rc != count) {
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stateless write - os internal file pointer is not updated.
|
||||
*
|
||||
* fp - pointer to file (pipe, socket, etc) to write to
|
||||
* buf - buffer to write
|
||||
* count - # of bytes to write
|
||||
* off - file offset to write to (only valid for seekable types)
|
||||
* resid - pointer to count of unwritten bytes
|
||||
*
|
||||
* Returns 0 on success errno on failure.
|
||||
*/
|
||||
int
|
||||
zfs_file_pwrite(zfs_file_t *fp, const void *buf,
|
||||
size_t count, loff_t pos, uint8_t ashift, ssize_t *resid)
|
||||
{
|
||||
ssize_t rc, split, done;
|
||||
int sectors;
|
||||
|
||||
/*
|
||||
* To simulate partial disk writes, we split writes into two
|
||||
* system calls so that the process can be killed in between.
|
||||
* This is used by ztest to simulate realistic failure modes.
|
||||
*/
|
||||
sectors = count >> ashift;
|
||||
split = (sectors > 0 ? rand() % sectors : 0) << ashift;
|
||||
rc = pwrite64(fp->f_fd, buf, split, pos);
|
||||
if (rc != -1) {
|
||||
done = rc;
|
||||
rc = pwrite64(fp->f_fd, (char *)buf + split,
|
||||
count - split, pos + split);
|
||||
}
|
||||
#ifdef __linux__
|
||||
if (rc == -1 && errno == EINVAL) {
|
||||
/*
|
||||
* Under Linux, this most likely means an alignment issue
|
||||
* (memory or disk) due to O_DIRECT, so we abort() in order
|
||||
* to catch the offender.
|
||||
*/
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rc < 0)
|
||||
return (errno);
|
||||
|
||||
done += rc;
|
||||
|
||||
if (resid) {
|
||||
*resid = count - done;
|
||||
} else if (done != count) {
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stateful read - use os internal file pointer to determine where to
|
||||
* read and update on successful completion.
|
||||
*
|
||||
* fp - pointer to file (pipe, socket, etc) to read from
|
||||
* buf - buffer to write
|
||||
* count - # of bytes to read
|
||||
* resid - pointer to count of unread bytes (if short read)
|
||||
*
|
||||
* Returns 0 on success errno on failure.
|
||||
*/
|
||||
int
|
||||
zfs_file_read(zfs_file_t *fp, void *buf, size_t count, ssize_t *resid)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = read(fp->f_fd, buf, count);
|
||||
if (rc < 0)
|
||||
return (errno);
|
||||
|
||||
if (resid) {
|
||||
*resid = count - rc;
|
||||
} else if (rc != count) {
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stateless read - os internal file pointer is not updated.
|
||||
*
|
||||
* fp - pointer to file (pipe, socket, etc) to read from
|
||||
* buf - buffer to write
|
||||
* count - # of bytes to write
|
||||
* off - file offset to read from (only valid for seekable types)
|
||||
* resid - pointer to count of unwritten bytes (if short write)
|
||||
*
|
||||
* Returns 0 on success errno on failure.
|
||||
*/
|
||||
int
|
||||
zfs_file_pread(zfs_file_t *fp, void *buf, size_t count, loff_t off,
|
||||
ssize_t *resid)
|
||||
{
|
||||
ssize_t rc;
|
||||
|
||||
rc = pread64(fp->f_fd, buf, count, off);
|
||||
if (rc < 0) {
|
||||
#ifdef __linux__
|
||||
/*
|
||||
* Under Linux, this most likely means an alignment issue
|
||||
* (memory or disk) due to O_DIRECT, so we abort() in order to
|
||||
* catch the offender.
|
||||
*/
|
||||
if (errno == EINVAL)
|
||||
abort();
|
||||
#endif
|
||||
return (errno);
|
||||
}
|
||||
|
||||
if (fp->f_dump_fd != -1) {
|
||||
int status;
|
||||
|
||||
status = pwrite64(fp->f_dump_fd, buf, rc, off);
|
||||
ASSERT(status != -1);
|
||||
}
|
||||
|
||||
if (resid) {
|
||||
*resid = count - rc;
|
||||
} else if (rc != count) {
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* lseek - set / get file pointer
|
||||
*
|
||||
* fp - pointer to file (pipe, socket, etc) to read from
|
||||
* offp - value to seek to, returns current value plus passed offset
|
||||
* whence - see man pages for standard lseek whence values
|
||||
*
|
||||
* Returns 0 on success errno on failure (ESPIPE for non seekable types)
|
||||
*/
|
||||
int
|
||||
zfs_file_seek(zfs_file_t *fp, loff_t *offp, int whence)
|
||||
{
|
||||
loff_t rc;
|
||||
|
||||
rc = lseek(fp->f_fd, *offp, whence);
|
||||
if (rc < 0)
|
||||
return (errno);
|
||||
|
||||
*offp = rc;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get file attributes
|
||||
*
|
||||
* filp - file pointer
|
||||
* zfattr - pointer to file attr structure
|
||||
*
|
||||
* Currently only used for fetching size and file mode
|
||||
*
|
||||
* Returns 0 on success or error code of underlying getattr call on failure.
|
||||
*/
|
||||
int
|
||||
zfs_file_getattr(zfs_file_t *fp, zfs_file_attr_t *zfattr)
|
||||
{
|
||||
struct stat64 st;
|
||||
|
||||
if (fstat64_blk(fp->f_fd, &st) == -1)
|
||||
return (errno);
|
||||
|
||||
zfattr->zfa_size = st.st_size;
|
||||
zfattr->zfa_mode = st.st_mode;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sync file to disk
|
||||
*
|
||||
* filp - file pointer
|
||||
* flags - O_SYNC and or O_DSYNC
|
||||
*
|
||||
* Returns 0 on success or error code of underlying sync call on failure.
|
||||
*/
|
||||
int
|
||||
zfs_file_fsync(zfs_file_t *fp, int flags)
|
||||
{
|
||||
(void) flags;
|
||||
|
||||
if (fsync(fp->f_fd) < 0)
|
||||
return (errno);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* deallocate - zero and/or deallocate file storage
|
||||
*
|
||||
* fp - file pointer
|
||||
* offset - offset to start zeroing or deallocating
|
||||
* len - length to zero or deallocate
|
||||
*/
|
||||
int
|
||||
zfs_file_deallocate(zfs_file_t *fp, loff_t offset, loff_t len)
|
||||
{
|
||||
int rc;
|
||||
#if defined(__linux__)
|
||||
rc = fallocate(fp->f_fd,
|
||||
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, offset, len);
|
||||
#elif defined(__FreeBSD__) && (__FreeBSD_version >= 1400029)
|
||||
struct spacectl_range rqsr = {
|
||||
.r_offset = offset,
|
||||
.r_len = len,
|
||||
};
|
||||
rc = fspacectl(fp->f_fd, SPACECTL_DEALLOC, &rqsr, 0, &rqsr);
|
||||
#else
|
||||
(void) fp, (void) offset, (void) len;
|
||||
rc = EOPNOTSUPP;
|
||||
#endif
|
||||
if (rc)
|
||||
return (SET_ERROR(rc));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Request current file pointer offset
|
||||
*
|
||||
* fp - pointer to file
|
||||
*
|
||||
* Returns current file offset.
|
||||
*/
|
||||
loff_t
|
||||
zfs_file_off(zfs_file_t *fp)
|
||||
{
|
||||
return (lseek(fp->f_fd, SEEK_CUR, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* unlink file
|
||||
*
|
||||
* path - fully qualified file path
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*
|
||||
* OPTIONAL
|
||||
*/
|
||||
int
|
||||
zfs_file_unlink(const char *path)
|
||||
{
|
||||
return (remove(path));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get reference to file pointer
|
||||
*
|
||||
* fd - input file descriptor
|
||||
*
|
||||
* Returns pointer to file struct or NULL.
|
||||
* Unsupported in user space.
|
||||
*/
|
||||
zfs_file_t *
|
||||
zfs_file_get(int fd)
|
||||
{
|
||||
(void) fd;
|
||||
abort();
|
||||
return (NULL);
|
||||
}
|
||||
/*
|
||||
* Drop reference to file pointer
|
||||
*
|
||||
* fp - pointer to file struct
|
||||
*
|
||||
* Unsupported in user space.
|
||||
*/
|
||||
void
|
||||
zfs_file_put(zfs_file_t *fp)
|
||||
{
|
||||
abort();
|
||||
(void) fp;
|
||||
}
|
||||
|
||||
void
|
||||
zfsvfs_update_fromname(const char *oldname, const char *newname)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,420 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||
* Copyright (c) 2025, Klara, Inc.
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/zfs_file.h>
|
||||
#include <libzpool.h>
|
||||
#include <libzutil.h>
|
||||
|
||||
/* If set, all blocks read will be copied to the specified directory. */
|
||||
char *vn_dumpdir = NULL;
|
||||
|
||||
/*
|
||||
* Open file
|
||||
*
|
||||
* path - fully qualified path to file
|
||||
* flags - file attributes O_READ / O_WRITE / O_EXCL
|
||||
* fpp - pointer to return file pointer
|
||||
*
|
||||
* Returns 0 on success underlying error on failure.
|
||||
*/
|
||||
int
|
||||
zfs_file_open(const char *path, int flags, int mode, zfs_file_t **fpp)
|
||||
{
|
||||
int fd;
|
||||
int dump_fd;
|
||||
int err;
|
||||
int old_umask = 0;
|
||||
zfs_file_t *fp;
|
||||
struct stat64 st;
|
||||
|
||||
if (!(flags & O_CREAT) && stat64(path, &st) == -1)
|
||||
return (errno);
|
||||
|
||||
if (!(flags & O_CREAT) && S_ISBLK(st.st_mode))
|
||||
flags |= O_DIRECT;
|
||||
|
||||
if (flags & O_CREAT)
|
||||
old_umask = umask(0);
|
||||
|
||||
fd = open64(path, flags, mode);
|
||||
if (fd == -1)
|
||||
return (errno);
|
||||
|
||||
if (flags & O_CREAT)
|
||||
(void) umask(old_umask);
|
||||
|
||||
if (vn_dumpdir != NULL) {
|
||||
char *dumppath = umem_zalloc(MAXPATHLEN, UMEM_NOFAIL);
|
||||
const char *inpath = zfs_basename(path);
|
||||
|
||||
(void) snprintf(dumppath, MAXPATHLEN,
|
||||
"%s/%s", vn_dumpdir, inpath);
|
||||
dump_fd = open64(dumppath, O_CREAT | O_WRONLY, 0666);
|
||||
umem_free(dumppath, MAXPATHLEN);
|
||||
if (dump_fd == -1) {
|
||||
err = errno;
|
||||
close(fd);
|
||||
return (err);
|
||||
}
|
||||
} else {
|
||||
dump_fd = -1;
|
||||
}
|
||||
|
||||
(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
fp = umem_zalloc(sizeof (zfs_file_t), UMEM_NOFAIL);
|
||||
fp->f_fd = fd;
|
||||
fp->f_dump_fd = dump_fd;
|
||||
*fpp = fp;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
zfs_file_close(zfs_file_t *fp)
|
||||
{
|
||||
close(fp->f_fd);
|
||||
if (fp->f_dump_fd != -1)
|
||||
close(fp->f_dump_fd);
|
||||
|
||||
umem_free(fp, sizeof (zfs_file_t));
|
||||
}
|
||||
|
||||
/*
|
||||
* Stateful write - use os internal file pointer to determine where to
|
||||
* write and update on successful completion.
|
||||
*
|
||||
* fp - pointer to file (pipe, socket, etc) to write to
|
||||
* buf - buffer to write
|
||||
* count - # of bytes to write
|
||||
* resid - pointer to count of unwritten bytes (if short write)
|
||||
*
|
||||
* Returns 0 on success errno on failure.
|
||||
*/
|
||||
int
|
||||
zfs_file_write(zfs_file_t *fp, const void *buf, size_t count, ssize_t *resid)
|
||||
{
|
||||
ssize_t rc;
|
||||
|
||||
rc = write(fp->f_fd, buf, count);
|
||||
if (rc < 0)
|
||||
return (errno);
|
||||
|
||||
if (resid) {
|
||||
*resid = count - rc;
|
||||
} else if (rc != count) {
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stateless write - os internal file pointer is not updated.
|
||||
*
|
||||
* fp - pointer to file (pipe, socket, etc) to write to
|
||||
* buf - buffer to write
|
||||
* count - # of bytes to write
|
||||
* off - file offset to write to (only valid for seekable types)
|
||||
* resid - pointer to count of unwritten bytes
|
||||
*
|
||||
* Returns 0 on success errno on failure.
|
||||
*/
|
||||
int
|
||||
zfs_file_pwrite(zfs_file_t *fp, const void *buf,
|
||||
size_t count, loff_t pos, uint8_t ashift, ssize_t *resid)
|
||||
{
|
||||
ssize_t rc, split, done;
|
||||
int sectors;
|
||||
|
||||
/*
|
||||
* To simulate partial disk writes, we split writes into two
|
||||
* system calls so that the process can be killed in between.
|
||||
* This is used by ztest to simulate realistic failure modes.
|
||||
*/
|
||||
sectors = count >> ashift;
|
||||
split = (sectors > 0 ? rand() % sectors : 0) << ashift;
|
||||
rc = pwrite64(fp->f_fd, buf, split, pos);
|
||||
if (rc != -1) {
|
||||
done = rc;
|
||||
rc = pwrite64(fp->f_fd, (char *)buf + split,
|
||||
count - split, pos + split);
|
||||
}
|
||||
#ifdef __linux__
|
||||
if (rc == -1 && errno == EINVAL) {
|
||||
/*
|
||||
* Under Linux, this most likely means an alignment issue
|
||||
* (memory or disk) due to O_DIRECT, so we abort() in order
|
||||
* to catch the offender.
|
||||
*/
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rc < 0)
|
||||
return (errno);
|
||||
|
||||
done += rc;
|
||||
|
||||
if (resid) {
|
||||
*resid = count - done;
|
||||
} else if (done != count) {
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stateful read - use os internal file pointer to determine where to
|
||||
* read and update on successful completion.
|
||||
*
|
||||
* fp - pointer to file (pipe, socket, etc) to read from
|
||||
* buf - buffer to write
|
||||
* count - # of bytes to read
|
||||
* resid - pointer to count of unread bytes (if short read)
|
||||
*
|
||||
* Returns 0 on success errno on failure.
|
||||
*/
|
||||
int
|
||||
zfs_file_read(zfs_file_t *fp, void *buf, size_t count, ssize_t *resid)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = read(fp->f_fd, buf, count);
|
||||
if (rc < 0)
|
||||
return (errno);
|
||||
|
||||
if (resid) {
|
||||
*resid = count - rc;
|
||||
} else if (rc != count) {
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stateless read - os internal file pointer is not updated.
|
||||
*
|
||||
* fp - pointer to file (pipe, socket, etc) to read from
|
||||
* buf - buffer to write
|
||||
* count - # of bytes to write
|
||||
* off - file offset to read from (only valid for seekable types)
|
||||
* resid - pointer to count of unwritten bytes (if short write)
|
||||
*
|
||||
* Returns 0 on success errno on failure.
|
||||
*/
|
||||
int
|
||||
zfs_file_pread(zfs_file_t *fp, void *buf, size_t count, loff_t off,
|
||||
ssize_t *resid)
|
||||
{
|
||||
ssize_t rc;
|
||||
|
||||
rc = pread64(fp->f_fd, buf, count, off);
|
||||
if (rc < 0) {
|
||||
#ifdef __linux__
|
||||
/*
|
||||
* Under Linux, this most likely means an alignment issue
|
||||
* (memory or disk) due to O_DIRECT, so we abort() in order to
|
||||
* catch the offender.
|
||||
*/
|
||||
if (errno == EINVAL)
|
||||
abort();
|
||||
#endif
|
||||
return (errno);
|
||||
}
|
||||
|
||||
if (fp->f_dump_fd != -1) {
|
||||
int status;
|
||||
|
||||
status = pwrite64(fp->f_dump_fd, buf, rc, off);
|
||||
ASSERT(status != -1);
|
||||
}
|
||||
|
||||
if (resid) {
|
||||
*resid = count - rc;
|
||||
} else if (rc != count) {
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* lseek - set / get file pointer
|
||||
*
|
||||
* fp - pointer to file (pipe, socket, etc) to read from
|
||||
* offp - value to seek to, returns current value plus passed offset
|
||||
* whence - see man pages for standard lseek whence values
|
||||
*
|
||||
* Returns 0 on success errno on failure (ESPIPE for non seekable types)
|
||||
*/
|
||||
int
|
||||
zfs_file_seek(zfs_file_t *fp, loff_t *offp, int whence)
|
||||
{
|
||||
loff_t rc;
|
||||
|
||||
rc = lseek(fp->f_fd, *offp, whence);
|
||||
if (rc < 0)
|
||||
return (errno);
|
||||
|
||||
*offp = rc;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get file attributes
|
||||
*
|
||||
* filp - file pointer
|
||||
* zfattr - pointer to file attr structure
|
||||
*
|
||||
* Currently only used for fetching size and file mode
|
||||
*
|
||||
* Returns 0 on success or error code of underlying getattr call on failure.
|
||||
*/
|
||||
int
|
||||
zfs_file_getattr(zfs_file_t *fp, zfs_file_attr_t *zfattr)
|
||||
{
|
||||
struct stat64 st;
|
||||
|
||||
if (fstat64_blk(fp->f_fd, &st) == -1)
|
||||
return (errno);
|
||||
|
||||
zfattr->zfa_size = st.st_size;
|
||||
zfattr->zfa_mode = st.st_mode;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sync file to disk
|
||||
*
|
||||
* filp - file pointer
|
||||
* flags - O_SYNC and or O_DSYNC
|
||||
*
|
||||
* Returns 0 on success or error code of underlying sync call on failure.
|
||||
*/
|
||||
int
|
||||
zfs_file_fsync(zfs_file_t *fp, int flags)
|
||||
{
|
||||
(void) flags;
|
||||
|
||||
if (fsync(fp->f_fd) < 0)
|
||||
return (errno);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* deallocate - zero and/or deallocate file storage
|
||||
*
|
||||
* fp - file pointer
|
||||
* offset - offset to start zeroing or deallocating
|
||||
* len - length to zero or deallocate
|
||||
*/
|
||||
int
|
||||
zfs_file_deallocate(zfs_file_t *fp, loff_t offset, loff_t len)
|
||||
{
|
||||
int rc;
|
||||
#if defined(__linux__)
|
||||
rc = fallocate(fp->f_fd,
|
||||
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, offset, len);
|
||||
#elif defined(__FreeBSD__) && (__FreeBSD_version >= 1400029)
|
||||
struct spacectl_range rqsr = {
|
||||
.r_offset = offset,
|
||||
.r_len = len,
|
||||
};
|
||||
rc = fspacectl(fp->f_fd, SPACECTL_DEALLOC, &rqsr, 0, &rqsr);
|
||||
#else
|
||||
(void) fp, (void) offset, (void) len;
|
||||
rc = EOPNOTSUPP;
|
||||
#endif
|
||||
if (rc)
|
||||
return (SET_ERROR(rc));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Request current file pointer offset
|
||||
*
|
||||
* fp - pointer to file
|
||||
*
|
||||
* Returns current file offset.
|
||||
*/
|
||||
loff_t
|
||||
zfs_file_off(zfs_file_t *fp)
|
||||
{
|
||||
return (lseek(fp->f_fd, SEEK_CUR, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* unlink file
|
||||
*
|
||||
* path - fully qualified file path
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*
|
||||
* OPTIONAL
|
||||
*/
|
||||
int
|
||||
zfs_file_unlink(const char *path)
|
||||
{
|
||||
return (remove(path));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get reference to file pointer
|
||||
*
|
||||
* fd - input file descriptor
|
||||
*
|
||||
* Returns pointer to file struct or NULL.
|
||||
* Unsupported in user space.
|
||||
*/
|
||||
zfs_file_t *
|
||||
zfs_file_get(int fd)
|
||||
{
|
||||
(void) fd;
|
||||
abort();
|
||||
return (NULL);
|
||||
}
|
||||
/*
|
||||
* Drop reference to file pointer
|
||||
*
|
||||
* fp - pointer to file struct
|
||||
*
|
||||
* Unsupported in user space.
|
||||
*/
|
||||
void
|
||||
zfs_file_put(zfs_file_t *fp)
|
||||
{
|
||||
abort();
|
||||
(void) fp;
|
||||
}
|
||||
@@ -34,11 +34,16 @@
|
||||
#include <libzutil.h>
|
||||
|
||||
static void
|
||||
dump_ddt_stat(const ddt_stat_t *dds, int h)
|
||||
dump_ddt_stat(const ddt_stat_t *dds, int h, boolean_t parsable)
|
||||
{
|
||||
char refcnt[6];
|
||||
char blocks[6], lsize[6], psize[6], dsize[6];
|
||||
char ref_blocks[6], ref_lsize[6], ref_psize[6], ref_dsize[6];
|
||||
char refcnt[32];
|
||||
char blocks[32], lsize[32], psize[32], dsize[32];
|
||||
char ref_blocks[32], ref_lsize[32], ref_psize[32], ref_dsize[32];
|
||||
|
||||
enum zfs_nicenum_format count_format = parsable ?
|
||||
ZFS_NICENUM_RAW : ZFS_NICENUM_1024;
|
||||
enum zfs_nicenum_format byte_format = parsable ?
|
||||
ZFS_NICENUM_RAW : ZFS_NICENUM_BYTES;
|
||||
|
||||
if (dds == NULL || dds->dds_blocks == 0)
|
||||
return;
|
||||
@@ -46,16 +51,26 @@ dump_ddt_stat(const ddt_stat_t *dds, int h)
|
||||
if (h == -1)
|
||||
(void) strcpy(refcnt, "Total");
|
||||
else
|
||||
zfs_nicenum(1ULL << h, refcnt, sizeof (refcnt));
|
||||
zfs_nicenum_format(1ULL << h, refcnt, sizeof (refcnt),
|
||||
count_format);
|
||||
|
||||
zfs_nicenum(dds->dds_blocks, blocks, sizeof (blocks));
|
||||
zfs_nicebytes(dds->dds_lsize, lsize, sizeof (lsize));
|
||||
zfs_nicebytes(dds->dds_psize, psize, sizeof (psize));
|
||||
zfs_nicebytes(dds->dds_dsize, dsize, sizeof (dsize));
|
||||
zfs_nicenum(dds->dds_ref_blocks, ref_blocks, sizeof (ref_blocks));
|
||||
zfs_nicebytes(dds->dds_ref_lsize, ref_lsize, sizeof (ref_lsize));
|
||||
zfs_nicebytes(dds->dds_ref_psize, ref_psize, sizeof (ref_psize));
|
||||
zfs_nicebytes(dds->dds_ref_dsize, ref_dsize, sizeof (ref_dsize));
|
||||
|
||||
zfs_nicenum_format(dds->dds_blocks, blocks, sizeof (blocks),
|
||||
count_format);
|
||||
zfs_nicenum_format(dds->dds_lsize, lsize, sizeof (lsize),
|
||||
byte_format);
|
||||
zfs_nicenum_format(dds->dds_psize, psize, sizeof (psize),
|
||||
byte_format);
|
||||
zfs_nicenum_format(dds->dds_dsize, dsize, sizeof (dsize),
|
||||
byte_format);
|
||||
zfs_nicenum_format(dds->dds_ref_blocks, ref_blocks,
|
||||
sizeof (ref_blocks), count_format);
|
||||
zfs_nicenum_format(dds->dds_ref_lsize, ref_lsize,
|
||||
sizeof (ref_lsize), byte_format);
|
||||
zfs_nicenum_format(dds->dds_ref_psize, ref_psize,
|
||||
sizeof (ref_psize), byte_format);
|
||||
zfs_nicenum_format(dds->dds_ref_dsize, ref_dsize,
|
||||
sizeof (ref_dsize), byte_format);
|
||||
|
||||
(void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n",
|
||||
refcnt,
|
||||
@@ -67,7 +82,8 @@ dump_ddt_stat(const ddt_stat_t *dds, int h)
|
||||
* Print the DDT histogram and the column totals.
|
||||
*/
|
||||
void
|
||||
zpool_dump_ddt(const ddt_stat_t *dds_total, const ddt_histogram_t *ddh)
|
||||
zpool_dump_ddt(const ddt_stat_t *dds_total, const ddt_histogram_t *ddh,
|
||||
boolean_t parsable)
|
||||
{
|
||||
int h;
|
||||
|
||||
@@ -91,9 +107,9 @@ zpool_dump_ddt(const ddt_stat_t *dds_total, const ddt_histogram_t *ddh)
|
||||
"------", "-----", "-----", "-----");
|
||||
|
||||
for (h = 0; h < 64; h++)
|
||||
dump_ddt_stat(&ddh->ddh_stat[h], h);
|
||||
dump_ddt_stat(&ddh->ddh_stat[h], h, parsable);
|
||||
|
||||
dump_ddt_stat(dds_total, -1);
|
||||
dump_ddt_stat(dds_total, -1, parsable);
|
||||
|
||||
(void) printf("\n");
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ dist_noinst_man_MANS = \
|
||||
%D%/man1/cstyle.1
|
||||
|
||||
dist_man_MANS = \
|
||||
%D%/man1/zilstat.1 \
|
||||
%D%/man1/zarcsummary.1 \
|
||||
%D%/man1/zarcstat.1 \
|
||||
%D%/man1/raidz_test.1 \
|
||||
%D%/man1/test-runner.1 \
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
.\" SPDX-License-Identifier: CDDL-1.0
|
||||
.\"
|
||||
.\" This file and its contents are supplied under the terms of the
|
||||
.\" Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
.\" You may only use this file in accordance with the terms of version
|
||||
.\" 1.0 of the CDDL.
|
||||
.\"
|
||||
.\" A full copy of the text of the CDDL should have accompanied this
|
||||
.\" source. A copy of the CDDL is also available via the Internet at
|
||||
.\" http://www.illumos.org/license/CDDL.
|
||||
.\"
|
||||
.\" Copyright (c) 2026 Christos Longros. All rights reserved.
|
||||
.\"
|
||||
.Dd March 14, 2026
|
||||
.Dt ZARCSUMMARY 1
|
||||
.Os
|
||||
.
|
||||
.Sh NAME
|
||||
.Nm zarcsummary
|
||||
.Nd print ZFS ARC and subsystem statistics
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl adghr
|
||||
.Op Fl p Ar page
|
||||
.Op Fl s Ar section
|
||||
.
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
collects statistics from the running kernel and prints a human-readable
|
||||
report on the state of the ZFS Adaptive Replacement Cache
|
||||
.Pq ARC
|
||||
and several related subsystems.
|
||||
The output is a snapshot; for periodic sampling, use
|
||||
.Xr zarcstat 1
|
||||
instead.
|
||||
.Pp
|
||||
When invoked without arguments,
|
||||
.Nm
|
||||
prints all sections in sequence.
|
||||
A single section may be selected with the
|
||||
.Fl s
|
||||
option.
|
||||
.Pp
|
||||
The report is organized into the following sections:
|
||||
.Bl -tag -offset Ds -width "tunables"
|
||||
.It Sy arc
|
||||
Current and target ARC sizes, the split between the Most Recently Used
|
||||
.Pq MRU
|
||||
and Most Frequently Used
|
||||
.Pq MFU
|
||||
lists, overall hit and miss ratios, compression savings, and whether the
|
||||
ARC is experiencing memory pressure.
|
||||
.It Sy archits
|
||||
Breakdown of ARC hits and misses by demand reads versus prefetches
|
||||
and data versus metadata.
|
||||
.It Sy dmu
|
||||
Data Management Unit predictive prefetcher statistics, including stream
|
||||
hits, misses, and I/O issued ahead of and behind the current stream.
|
||||
.It Sy l2arc
|
||||
Level-2 ARC statistics for any cache devices attached to imported pools.
|
||||
This section only appears when an L2ARC device is present and covers
|
||||
bytes read and written, hit rates, and eviction activity.
|
||||
.It Sy spl
|
||||
Solaris Porting Layer memory allocator statistics.
|
||||
This section is only available on Linux.
|
||||
.It Sy tunables
|
||||
Current values of kernel tunables that govern ARC behavior, including
|
||||
.Va zfs_arc_max
|
||||
and
|
||||
.Va zfs_arc_min .
|
||||
Combining this section with
|
||||
.Fl d
|
||||
adds a brief explanation of each tunable.
|
||||
.It Sy zil
|
||||
ZFS Intent Log statistics: committed transaction counts, flush requests
|
||||
to stable storage, and the byte-level split between normal vdevs and
|
||||
any separate log
|
||||
.Pq SLOG
|
||||
device.
|
||||
.El
|
||||
.
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -width "-s"
|
||||
.It Fl a , -alternate
|
||||
Use an alternate layout for the tunables and SPL sections.
|
||||
.It Fl d , -description
|
||||
Print a short description next to each tunable and SPL entry.
|
||||
.It Fl h , -help
|
||||
Display a help message.
|
||||
.It Fl g , -graph
|
||||
Print an ASCII graph of current ARC use and exit.
|
||||
.It Fl p Ar page , Fl -page Ar page
|
||||
Print a section by its legacy page number.
|
||||
.Sy Deprecated ;
|
||||
use
|
||||
.Fl s
|
||||
instead.
|
||||
.It Fl r , -raw
|
||||
Dump all available data with minimal formatting.
|
||||
.It Fl s Ar section , Fl -section Ar section
|
||||
Print only the named section.
|
||||
See
|
||||
.Sx DESCRIPTION
|
||||
for the list of valid section names.
|
||||
.El
|
||||
.
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width "FreeBSD"
|
||||
.It Sy Linux
|
||||
Statistics are read from
|
||||
.Pa /proc/spl/kstat/zfs/ .
|
||||
.It Fx
|
||||
Statistics are read via
|
||||
.Xr sysctl 3
|
||||
from the
|
||||
.Va vfs.zfs
|
||||
and
|
||||
.Va kstat.zfs.misc
|
||||
trees.
|
||||
The
|
||||
.Pa py-sysctl
|
||||
package must be installed for
|
||||
.Nm
|
||||
to function.
|
||||
.El
|
||||
.
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std
|
||||
.
|
||||
.Sh EXAMPLES
|
||||
Print the full report:
|
||||
.Dl # zarcsummary
|
||||
.Pp
|
||||
Display only ARC size and hit rate information:
|
||||
.Dl # zarcsummary -s arc
|
||||
.Pp
|
||||
Show a visual overview of ARC health:
|
||||
.Dl # zarcsummary -g
|
||||
.Pp
|
||||
Search for all statistics containing
|
||||
.Dq hit :
|
||||
.Dl # zarcsummary -r | grep hit
|
||||
.Pp
|
||||
Review all tunables with their descriptions:
|
||||
.Dl # zarcsummary -d -s tunables
|
||||
.
|
||||
.Sh SEE ALSO
|
||||
.Xr zarcstat 1 ,
|
||||
.Xr zpool-status 8
|
||||
.
|
||||
.Sh HISTORY
|
||||
.Nm
|
||||
originated as a Perl script called
|
||||
.Nm arc_summary ,
|
||||
written by
|
||||
.An Ben Rockwood
|
||||
in 2008 for Solaris.
|
||||
.An Martin Matuska
|
||||
ported it to
|
||||
.Fx
|
||||
in 2010, and
|
||||
.An Jason J. Hellenthal
|
||||
took over maintenance.
|
||||
.An Scot W. Stevenson
|
||||
contributed a full rewrite in Python 3 in 2017, introducing the
|
||||
.Fl g ,
|
||||
.Fl r ,
|
||||
and
|
||||
.Fl s
|
||||
options along with the section-based output layout.
|
||||
The tool was renamed from
|
||||
.Nm arc_summary
|
||||
to
|
||||
.Nm zarcsummary
|
||||
in 2025 to align with the OpenZFS command naming convention.
|
||||
.
|
||||
.Sh AUTHORS
|
||||
This manual page was written by
|
||||
.An Christos Longros Aq Mt [email protected] .
|
||||
@@ -0,0 +1,191 @@
|
||||
.\" SPDX-License-Identifier: CDDL-1.0
|
||||
.\"
|
||||
.\" CDDL HEADER START
|
||||
.\"
|
||||
.\" The contents of this file are subject to the terms of the
|
||||
.\" Common Development and Distribution License, Version 1.0 only
|
||||
.\" (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) 2026 Christos Longros. All rights reserved.
|
||||
.\"
|
||||
.Dd March 9, 2026
|
||||
.Dt ZILSTAT 1
|
||||
.Os
|
||||
.
|
||||
.Sh NAME
|
||||
.Nm zilstat
|
||||
.Nd report ZFS Intent Log statistics
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl v
|
||||
.Op Fl a Ns | Ns Fl p Ar pool Ns | Ns Fl d Ar dataset Ns Op , Ns Ar dataset Ns …
|
||||
.Op Fl f Ar field Ns Op , Ns Ar field Ns …
|
||||
.Op Fl s Ar separator
|
||||
.Op Fl i Ar interval
|
||||
.
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
prints statistics about the ZFS Intent Log (ZIL).
|
||||
The ZIL is used to log synchronous write operations and is replayed on
|
||||
pool import if the system crashes before those writes are committed to
|
||||
the main pool.
|
||||
.Pp
|
||||
By default, global ZIL statistics are displayed.
|
||||
When a pool or dataset is specified, per-dataset statistics are shown
|
||||
instead.
|
||||
.Pp
|
||||
If an
|
||||
.Ar interval
|
||||
is specified, the output is repeated every
|
||||
.Ar interval
|
||||
seconds showing the change in values since the previous sample.
|
||||
Without an interval, cumulative values are displayed.
|
||||
.Pp
|
||||
The following fields are available:
|
||||
.Bl -tag -compact -offset Ds -width "imnw"
|
||||
.It Sy time
|
||||
Current time
|
||||
.It Sy pool
|
||||
Pool name
|
||||
.It Sy ds
|
||||
Dataset name
|
||||
.It Sy obj
|
||||
Objset ID
|
||||
.It Sy cc
|
||||
Commit count
|
||||
.It Sy cwc
|
||||
Commit writer count
|
||||
.It Sy cec
|
||||
Commit error count
|
||||
.It Sy csc
|
||||
Commit stall count
|
||||
.It Sy cSc
|
||||
Commit suspend count
|
||||
.It Sy cCc
|
||||
Commit crash count
|
||||
.It Sy ic
|
||||
In-transaction count
|
||||
.It Sy iic
|
||||
Indirect in-transaction count
|
||||
.It Sy iib
|
||||
Indirect in-transaction bytes
|
||||
.It Sy icc
|
||||
Copied in-transaction count
|
||||
.It Sy icb
|
||||
Copied in-transaction bytes
|
||||
.It Sy inc
|
||||
Needcopy in-transaction count
|
||||
.It Sy inb
|
||||
Needcopy in-transaction bytes
|
||||
.It Sy idc
|
||||
Direct (copied + needcopy) count
|
||||
.It Sy idb
|
||||
Direct (copied + needcopy) bytes
|
||||
.It Sy iwc
|
||||
Total write (indirect + direct) count
|
||||
.It Sy iwb
|
||||
Total write (indirect + direct) bytes
|
||||
.It Sy imnc
|
||||
Normal metaslab count
|
||||
.It Sy imnb
|
||||
Normal metaslab bytes
|
||||
.It Sy imnw
|
||||
Normal metaslab write bytes
|
||||
.It Sy imna
|
||||
Normal metaslab alloc bytes
|
||||
.It Sy imsc
|
||||
SLOG metaslab count
|
||||
.It Sy imsb
|
||||
SLOG metaslab bytes
|
||||
.It Sy imsw
|
||||
SLOG metaslab write bytes
|
||||
.It Sy imsa
|
||||
SLOG metaslab alloc bytes
|
||||
.It Sy imc
|
||||
Total metaslab (normal + SLOG) count
|
||||
.It Sy imb
|
||||
Total metaslab (normal + SLOG) bytes
|
||||
.It Sy imw
|
||||
Total metaslab (normal + SLOG) write bytes
|
||||
.It Sy ima
|
||||
Total metaslab (normal + SLOG) alloc bytes
|
||||
.It Sy se%
|
||||
Space efficiency percentage (bytes / alloc)
|
||||
.It Sy sen%
|
||||
Normal space efficiency percentage
|
||||
.It Sy ses%
|
||||
SLOG space efficiency percentage
|
||||
.It Sy te%
|
||||
Total efficiency percentage (bytes / write)
|
||||
.It Sy ten%
|
||||
Normal total efficiency percentage
|
||||
.It Sy tes%
|
||||
SLOG total efficiency percentage
|
||||
.El
|
||||
.
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -width "-s"
|
||||
.It Fl h
|
||||
Display a help message.
|
||||
.It Fl a
|
||||
Print statistics for all datasets across all pools.
|
||||
.It Fl d Ar dataset
|
||||
Print statistics for the specified dataset(s).
|
||||
Multiple datasets may be given as a comma-separated list.
|
||||
.It Fl f Ar field
|
||||
Display only the specified fields.
|
||||
Multiple fields may be given as a comma-separated list.
|
||||
See
|
||||
.Sx DESCRIPTION
|
||||
for available fields.
|
||||
.It Fl i Ar interval
|
||||
Print statistics every
|
||||
.Ar interval
|
||||
seconds.
|
||||
Values are reported as rates per second.
|
||||
.It Fl p Ar pool
|
||||
Print statistics for all datasets in the specified pool.
|
||||
.It Fl s Ar separator
|
||||
Override the default field separator
|
||||
.Pq two spaces
|
||||
with a custom string.
|
||||
.It Fl v
|
||||
List all available field headers and their definitions.
|
||||
.El
|
||||
.
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width "Linux"
|
||||
.It Sy Linux
|
||||
Statistics are read from
|
||||
.Pa /proc/spl/kstat/zfs/zil
|
||||
for global stats and from per-pool objset files under
|
||||
.Pa /proc/spl/kstat/zfs/ Ns Ar pool Ns Pa / .
|
||||
.It Sy FreeBSD
|
||||
Statistics are read via
|
||||
.Xr sysctl 8
|
||||
from the
|
||||
.Sy kstat.zfs
|
||||
tree.
|
||||
.El
|
||||
.
|
||||
.Sh SEE ALSO
|
||||
.Xr zarcstat 1 ,
|
||||
.Xr zpool-status 8
|
||||
.
|
||||
.Sh AUTHORS
|
||||
This manual page was written by
|
||||
.An Christos Longros Aq Mt [email protected] .
|
||||
@@ -108,12 +108,14 @@ and only applicable in related situations.
|
||||
Seconds between L2ARC writing.
|
||||
.
|
||||
.It Sy l2arc_headroom Ns = Ns Sy 8 Pq u64
|
||||
How far through the ARC lists to search for L2ARC cacheable content,
|
||||
How far through the ARC lists to search for L2ARC cacheable content per cycle,
|
||||
expressed as a multiplier of the effective write size.
|
||||
ARC persistence across reboots can be achieved with persistent L2ARC
|
||||
by setting this parameter to
|
||||
.Sy 0 ,
|
||||
allowing the full length of ARC lists to be searched for cacheable content.
|
||||
Setting to
|
||||
.Sy 0
|
||||
disables the per-cycle headroom limit.
|
||||
Scan depth is also bounded by
|
||||
.Sy l2arc_ext_headroom_pct
|
||||
when persistent markers are active.
|
||||
.
|
||||
.It Sy l2arc_headroom_boost Ns = Ns Sy 200 Ns % Pq u64
|
||||
Scales
|
||||
@@ -227,6 +229,19 @@ to enable caching/reading prefetches to/from L2ARC.
|
||||
.It Sy l2arc_norw Ns = Ns Sy 0 Ns | Ns 1 Pq int
|
||||
No reads during writes.
|
||||
.
|
||||
.It Sy l2arc_ext_headroom_pct Ns = Ns Sy 25 Pq u64
|
||||
Percentage of each ARC state's size that a pass may scan before
|
||||
resetting its markers to the tail.
|
||||
Lower values keep the marker closer to the tail under active workloads.
|
||||
Set to 0 to disable the depth cap.
|
||||
.
|
||||
.It Sy l2arc_meta_cycles Ns = Ns Sy 2 Pq u64
|
||||
How many consecutive cycles metadata may monopolize the write budget
|
||||
before being skipped to let data run.
|
||||
The default of 2 gives metadata roughly 67% and data 33% of L2ARC
|
||||
write bandwidth under sustained load.
|
||||
Higher values favor metadata; set to 0 to disable.
|
||||
.
|
||||
.It Sy l2arc_write_max Ns = Ns Sy 33554432 Ns B Po 32 MiB Pc Pq u64
|
||||
Maximum write rate in bytes per second for each L2ARC device.
|
||||
Used directly during initial fill, when DWPD limiting is disabled,
|
||||
|
||||
@@ -430,19 +430,15 @@ is updated even if no metadata structures are written.
|
||||
L2ARC operates in one of two modes depending on total cache capacity.
|
||||
When total L2ARC capacity is less than twice
|
||||
.Sy arc_c_max ,
|
||||
L2ARC uses exclusive caching,
|
||||
writing buffers to cache as they are evicted from ARC.
|
||||
L2ARC writes buffers to cache as they are evicted from ARC.
|
||||
When total capacity is at least twice
|
||||
.Sy arc_c_max ,
|
||||
L2ARC switches to inclusive caching with persistent markers
|
||||
that track scan positions,
|
||||
attempting to duplicate ARC contents as much as write throughput allows.
|
||||
Setting
|
||||
.Sy l2arc_headroom Ns = Ns Sy 0
|
||||
will result in scanning the full-length ARC lists for cacheable content to be
|
||||
written in L2ARC (persistent ARC).
|
||||
In inclusive mode, markers progress toward the head across iterations,
|
||||
naturally covering the full list.
|
||||
L2ARC uses persistent markers that track scan positions across iterations,
|
||||
writing cacheable content as write throughput allows.
|
||||
A depth cap
|
||||
.Pq Sy l2arc_ext_headroom_pct
|
||||
limits how far markers advance from the tail, keeping them focused on
|
||||
buffers soon to be evicted where caching adds the most value.
|
||||
.Pp
|
||||
If a cache device is added with
|
||||
.Nm zpool Cm add ,
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
.\" Copyright 2017 Nexenta Systems, Inc.
|
||||
.\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
|
||||
.\" Copyright (c) 2021, Colm Buckley <[email protected]>
|
||||
.\" Copyright (c) 2023, Klara Inc.
|
||||
.\" Copyright (c) 2023, 2026, Klara Inc.
|
||||
.\"
|
||||
.Dd December 4, 2024
|
||||
.Dd March 2, 2026
|
||||
.Dt ZPOOLPROPS 7
|
||||
.Os
|
||||
.
|
||||
@@ -49,7 +49,7 @@ For more information about user properties, see the
|
||||
section.
|
||||
.Pp
|
||||
The following are read-only properties:
|
||||
.Bl -tag -width "unsupported@guid"
|
||||
.Bl -tag -width "last_scrubbed_txg"
|
||||
.It Sy allocated
|
||||
Amount of storage used within the pool.
|
||||
See
|
||||
@@ -57,6 +57,21 @@ See
|
||||
and
|
||||
.Sy free
|
||||
for more information.
|
||||
.It Sy available
|
||||
The amount of free space available in the pool, adjusted for raidz parity
|
||||
overhead.
|
||||
The
|
||||
.Sy available
|
||||
property is calculated as:
|
||||
.Pp
|
||||
.Sy usable - used
|
||||
.Pp
|
||||
See
|
||||
.Sy usable ,
|
||||
.Sy used ,
|
||||
and
|
||||
.Sy free
|
||||
for more information.
|
||||
.It Sy bcloneratio
|
||||
The ratio of the total amount of storage that would be required to store all
|
||||
the cloned blocks without cloning to the actual storage used.
|
||||
@@ -184,6 +199,21 @@ Information about unsupported features that are enabled on the pool.
|
||||
See
|
||||
.Xr zpool-features 7
|
||||
for details.
|
||||
.It Sy usable
|
||||
Estimate of total storage pool size, adjusted for raidz parity overhead.
|
||||
The adjustment assumes a fixed 128KiB record size to compute a data-to-parity
|
||||
ratio.
|
||||
.Sy usable
|
||||
is a heuristic for allocation and should not be interpreted as an exact measure
|
||||
of usable space.
|
||||
.It Sy used
|
||||
Estimate of storage used within the storage pool, adjusted for raidz parity
|
||||
overhead.
|
||||
The adjustment assumes a fixed 128KiB record size to compute a data-to-parity
|
||||
ratio.
|
||||
.Sy used
|
||||
is a heuristic for allocation and should not be interpreted as an exact measure
|
||||
of used space.
|
||||
.El
|
||||
.Pp
|
||||
The space usage properties report actual physical space available to the
|
||||
@@ -201,6 +231,121 @@ For non-full pools of a reasonable size, these effects should be invisible.
|
||||
For small pools, or pools that are close to being completely full, these
|
||||
discrepancies may become more noticeable.
|
||||
.Pp
|
||||
The following properties are read-only metrics for allocation classes:
|
||||
.Bl -ohang
|
||||
.It Xo Sy class_dedup_allocated , class_dedup_available , class_dedup_capacity ,
|
||||
.Sy class_dedup_expandsize , class_dedup_fragmentation , class_dedup_free ,
|
||||
.Sy class_dedup_size , class_dedup_usable , class_dedup_used
|
||||
.Xc
|
||||
.Bd -ragged -offset Ds -compact
|
||||
Space usage properties of the pool's
|
||||
.Sy dedup
|
||||
metaslab allocator class.
|
||||
.Ed
|
||||
.It Xo Sy class_elog_allocated , class_elog_available , class_elog_capacity ,
|
||||
.Sy class_elog_expandsize , class_elog_fragmentation , class_elog_free ,
|
||||
.Sy class_elog_size , class_elog_usable , class_elog_used
|
||||
.Xc
|
||||
.Bd -ragged -offset Ds -compact
|
||||
Space usage properties of the pool's
|
||||
.Sy embedded_log
|
||||
metaslab allocator class.
|
||||
.Ed
|
||||
.It Xo Sy class_log_allocated , class_log_available , class_log_capacity ,
|
||||
.Sy class_log_expandsize , class_log_fragmentation , class_log_free ,
|
||||
.Sy class_log_size , class_log_usable , class_log_used
|
||||
.Xc
|
||||
.Bd -ragged -offset Ds -compact
|
||||
Space usage properties of the pool's
|
||||
.Sy log
|
||||
metaslab allocator class.
|
||||
.Ed
|
||||
.It Xo Sy class_normal_allocated , class_normal_available ,
|
||||
.Sy class_normal_capacity , class_normal_expandsize ,
|
||||
.Sy class_normal_fragmentation , class_normal_free , class_normal_size ,
|
||||
.Sy class_normal_usable , class_normal_used
|
||||
.Xc
|
||||
.Bd -ragged -offset Ds -compact
|
||||
Space usage properties of the pool's
|
||||
.Sy normal
|
||||
metaslab allocator class.
|
||||
.Ed
|
||||
.It Xo Sy class_special_allocated , class_special_available ,
|
||||
.Sy class_special_capacity , class_special_expandsize ,
|
||||
.Sy class_special_fragmentation , class_special_free , class_special_size ,
|
||||
.Sy class_special_usable , class_special_used
|
||||
.Xc
|
||||
.Bd -ragged -offset Ds -compact
|
||||
Space usage properties of the pool's
|
||||
.Sy special
|
||||
metaslab allocator class.
|
||||
.Ed
|
||||
.It Xo Sy class_special_elog_allocated , class_special_elog_available ,
|
||||
.Sy class_special_elog_capacity , class_special_elog_expandsize ,
|
||||
.Sy class_special_elog_fragmentation , class_special_elog_free ,
|
||||
.Sy class_special_elog_size , class_special_elog_usable ,
|
||||
.Sy class_special_elog_used
|
||||
.Xc
|
||||
.Bd -ragged -offset Ds -compact
|
||||
Space usage properties of the pool's
|
||||
.Sy special_embedded_log
|
||||
metaslab allocator class.
|
||||
.Ed
|
||||
.El
|
||||
.Pp
|
||||
Each allocation class is described by these values:
|
||||
.Bl -tag -width "fragmentation"
|
||||
.It Sy allocated
|
||||
Amount of storage used within the allocation class.
|
||||
.It Sy available
|
||||
Estimate of free space available in the allocation class, adjusted for raidz
|
||||
parity overhead.
|
||||
The adjustment assumes a fixed 128KiB record size to compute a data-to-parity
|
||||
ratio.
|
||||
.Sy available
|
||||
is a heuristic for allocation and should not be interpreted as an exact measure
|
||||
of usable space.
|
||||
Actual usable space depends on a variety of factors such as dataset record size
|
||||
and compression.
|
||||
.It Sy capacity
|
||||
Percentage of allocation class space used.
|
||||
.It Sy expandsize
|
||||
Amount of uninitialized space within the allocation class that can be used to
|
||||
increase the capacity of the allocator.
|
||||
See the pool-wide
|
||||
.Sy expandsize
|
||||
property.
|
||||
.It Sy fragmentation
|
||||
The amount of free space fragmentation in the allocation class.
|
||||
See the pool-wide
|
||||
.Sy fragmentation
|
||||
property.
|
||||
.It Sy free
|
||||
The amount of free space available in the allocation class.
|
||||
This value is not adjusted for factors such as dataset record size, compression,
|
||||
or raidz parity overhead.
|
||||
See the pool-wide
|
||||
.Sy free
|
||||
property.
|
||||
.It Sy size
|
||||
Total size of the allocation class.
|
||||
.It Sy usable
|
||||
Estimate of total allocation class size, adjusted for raidz parity overhead.
|
||||
The adjustment assumes a fixed 128KiB record size to compute a data-to-parity
|
||||
ratio.
|
||||
.Sy usable
|
||||
is a heuristic for allocation and should not be interpreted as an exact measure
|
||||
of usable space.
|
||||
.It Sy used
|
||||
Estimate of storage used within the allocation class, adjusted for raidz parity
|
||||
overhead.
|
||||
The adjustment assumes a fixed 128KiB record size to compute a data-to-parity
|
||||
ratio.
|
||||
.Sy used
|
||||
is a heuristic for allocation and should not be interpreted as an exact measure
|
||||
of used space.
|
||||
.El
|
||||
.Pp
|
||||
The following property can be set at creation time and import time:
|
||||
.Bl -tag -width Ds
|
||||
.It Sy altroot
|
||||
|
||||
@@ -282,6 +282,13 @@ Also dump the contents of the deduplication tables describing unique blocks.
|
||||
Decode and display block from an embedded block pointer specified by the
|
||||
.Ar word
|
||||
arguments.
|
||||
.It Fl f , -file-layout
|
||||
Display the file layout of an object for the disks of a raidz vdev.
|
||||
With
|
||||
.Fl H ,
|
||||
the output is in scripted mode for easy parsing, with all values
|
||||
being presented as 512 byte blocks.
|
||||
Only a single top-level raidz vdev is supported.
|
||||
.It Fl h , -history
|
||||
Display pool history similar to
|
||||
.Nm zpool Cm history ,
|
||||
|
||||
@@ -62,6 +62,10 @@ Creates all the non-existing parent datasets.
|
||||
Datasets created in this manner are automatically mounted according to the
|
||||
.Sy mountpoint
|
||||
property inherited from their parent.
|
||||
If the
|
||||
.Fl p
|
||||
option is specified multiple times, parent datasets are created with
|
||||
.Sy canmount Ns = Ns Ar off .
|
||||
If the target filesystem or volume already exists, the operation completes
|
||||
successfully.
|
||||
.It Fl u
|
||||
|
||||
@@ -85,6 +85,10 @@ property inherited from their parent.
|
||||
Any property specified on the command line using the
|
||||
.Fl o
|
||||
option is ignored.
|
||||
If the
|
||||
.Fl p
|
||||
option is specified multiple times, parent datasets are created with
|
||||
.Sy canmount Ns = Ns Ar off .
|
||||
If the target filesystem already exists, the operation completes successfully.
|
||||
.It Fl n
|
||||
Do a dry-run
|
||||
@@ -177,6 +181,10 @@ property inherited from their parent.
|
||||
Any property specified on the command line using the
|
||||
.Fl o
|
||||
option is ignored.
|
||||
If the
|
||||
.Fl p
|
||||
option is specified multiple times, parent datasets are created with
|
||||
.Sy canmount Ns = Ns Ar off .
|
||||
If the target filesystem already exists, the operation completes successfully.
|
||||
.It Fl s
|
||||
Creates a sparse volume with no reservation.
|
||||
|
||||
@@ -103,6 +103,10 @@ Creates all the non-existing parent datasets.
|
||||
Datasets created in this manner are automatically mounted according to the
|
||||
.Sy mountpoint
|
||||
property inherited from their parent.
|
||||
Alernatively, if the
|
||||
.Fl p
|
||||
option is specified multiple times, parent datasets are created with
|
||||
.Sy canmount Ns = Ns Ar off .
|
||||
.It Fl u
|
||||
Do not remount file systems during rename.
|
||||
If a file system's
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
.\" Copyright 2019 Joyent, Inc.
|
||||
.\" Copyright (c) 2024, Klara, Inc.
|
||||
.\"
|
||||
.Dd August 29, 2025
|
||||
.Dd February 20, 2026
|
||||
.Dt ZFS-SEND 8
|
||||
.Os
|
||||
.
|
||||
@@ -41,13 +41,13 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm zfs
|
||||
.Cm send
|
||||
.Op Fl DLPVbcehnpsvw
|
||||
.Op Fl DLPUVbcehnpsvw
|
||||
.Op Fl R Op Fl X Ar dataset Ns Oo , Ns Ar dataset Oc Ns …
|
||||
.Op Oo Fl I Ns | Ns Fl i Oc Ar snapshot
|
||||
.Ar snapshot
|
||||
.Nm zfs
|
||||
.Cm send
|
||||
.Op Fl DLPVcensvw
|
||||
.Op Fl DLPUVcensvw
|
||||
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
|
||||
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
|
||||
.Nm zfs
|
||||
@@ -75,7 +75,7 @@
|
||||
.It Xo
|
||||
.Nm zfs
|
||||
.Cm send
|
||||
.Op Fl DLPVbcehnpsvw
|
||||
.Op Fl DLPUVbcehnpsvw
|
||||
.Op Fl R Op Fl X Ar dataset Ns Oo , Ns Ar dataset Oc Ns …
|
||||
.Op Oo Fl I Ns | Ns Fl i Oc Ar snapshot
|
||||
.Ar snapshot
|
||||
@@ -146,6 +146,8 @@ If the
|
||||
.Fl R
|
||||
flag is used to send encrypted datasets, then
|
||||
.Fl w
|
||||
or
|
||||
.Fl U
|
||||
must also be specified.
|
||||
.It Fl V , -proctitle
|
||||
Set the process title to a per-second report of how much data has been sent.
|
||||
@@ -293,6 +295,8 @@ is specified.
|
||||
The receiving system must also support this feature.
|
||||
Sends of encrypted datasets must use
|
||||
.Fl w
|
||||
or
|
||||
.Fl U
|
||||
when using this flag.
|
||||
.It Fl s , -skip-missing
|
||||
Allows sending a replication stream even when there are snapshots missing in the
|
||||
@@ -303,6 +307,11 @@ belongs
|
||||
and its descendants are skipped.
|
||||
This flag can only be used in conjunction with
|
||||
.Fl R .
|
||||
.It Fl U , -no-preserve-encryption
|
||||
Allow sending an encrypted dataset with properties, but without keeping
|
||||
encryption.
|
||||
When this flag is specified, encrypted datasets that would otherwise be blocked
|
||||
from sending are sent as unencrypted data.
|
||||
.It Fl v , -verbose
|
||||
Print verbose information about the stream package generated.
|
||||
This information includes a per-second report of how much data has been sent.
|
||||
|
||||
@@ -67,8 +67,8 @@ If
|
||||
is specified, the command exits after
|
||||
.Ar count
|
||||
reports are printed.
|
||||
The first report printed is always the statistics since boot regardless of
|
||||
whether
|
||||
The first report printed is always the average per-second
|
||||
statistics since boot regardless of whether
|
||||
.Ar interval
|
||||
and
|
||||
.Ar count
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2020 by Delphix. All rights reserved.
|
||||
.\"
|
||||
.Dd November 10, 2022
|
||||
.Dd February 20, 2026
|
||||
.Dt ZSTREAM 8
|
||||
.Os
|
||||
.
|
||||
@@ -38,6 +38,10 @@
|
||||
.Op Fl v
|
||||
.Op Ar object Ns Sy \&, Ns Ar offset Ns Op Sy \&, Ns Ar type Ns ...
|
||||
.Nm
|
||||
.Cm drop_record
|
||||
.Op Fl v
|
||||
.Op Ar object Ns Sy \&, Ns Ar offset Ns Op Sy \& Ns ...
|
||||
.Nm
|
||||
.Cm redup
|
||||
.Op Fl v
|
||||
.Ar file
|
||||
@@ -127,6 +131,21 @@ Print summary of decompressed records.
|
||||
.El
|
||||
.It Xo
|
||||
.Nm
|
||||
.Cm drop_record
|
||||
.Op Fl v
|
||||
.Op Ar object Ns Sy \&, Ns Ar offset Ns Op Sy \& ...
|
||||
.Xc
|
||||
Drop selected records from a ZFS send stream provided on standard input,
|
||||
specified by object number and byte offset.
|
||||
Only WRITE and WRITE_EMBEDDED are records are supported, currently.
|
||||
The repaired stream will be written to standard output.
|
||||
.Bl -tag -width "-v"
|
||||
.It Fl v
|
||||
Verbose.
|
||||
Print summary of dropped records.
|
||||
.El
|
||||
.It Xo
|
||||
.Nm
|
||||
.Cm redup
|
||||
.Op Fl v
|
||||
.Ar file
|
||||
@@ -178,7 +197,7 @@ non-default level is desired).
|
||||
.El
|
||||
.
|
||||
.Sh EXAMPLES
|
||||
Heal a dataset that was corrupted due to OpenZFS bug #12762.
|
||||
.Ss Recovering from OpenZFS bug #12762
|
||||
First, determine which records are corrupt.
|
||||
That cannot be done automatically; it requires information beyond ZFS's
|
||||
metadata.
|
||||
@@ -193,8 +212,24 @@ then run this command:
|
||||
.No # Nm zfs Ar send Fl c Ar … | Nm zstream decompress Ar 128,0,lz4 | \
|
||||
Nm zfs recv Ar …
|
||||
.Ed
|
||||
.
|
||||
.Ss Recovering from OpenZFS bug #18239
|
||||
The bogus records typically have an absurdly large offset, and can be seen with
|
||||
a command like
|
||||
.Nm zdb Fl ddddd Ar dataset Ar object
|
||||
or
|
||||
.Nm zstream Ar dump Fl v .
|
||||
To recover, send the dataset and use
|
||||
.Nm zstream
|
||||
to drop the bogus record, then receive into a new dataset.
|
||||
.Bd -literal
|
||||
.No # Nm zfs Ar send Ar ... | Nm zstream drop_record Ar 3545761,18446744073709486080 | \
|
||||
Nm zfs recv Ar ...
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr zdb 8 ,
|
||||
.Xr zfs 8 ,
|
||||
.Xr zfs-receive 8 ,
|
||||
.Xr zfs-send 8 ,
|
||||
.Lk https://github.com/openzfs/zfs/issues/12762
|
||||
.Lk https://github.com/openzfs/zfs/issues/18239
|
||||
@@ -11,6 +11,7 @@ zfs_include = @abs_top_srcdir@/include
|
||||
icp_include = @abs_srcdir@/icp/include
|
||||
zstd_include = @abs_srcdir@/zstd/include
|
||||
ZFS_MODULE_CFLAGS += -include @abs_top_builddir@/zfs_config.h
|
||||
ZFS_MODULE_CFLAGS += -include $(zfs_include)/sys/simd_config.h
|
||||
ZFS_MODULE_CFLAGS += -I@abs_top_builddir@/include
|
||||
src = @abs_srcdir@
|
||||
obj = @abs_builddir@
|
||||
@@ -19,6 +20,7 @@ zfs_include = $(srctree)/include/zfs
|
||||
icp_include = $(src)/icp/include
|
||||
zstd_include = $(src)/zstd/include
|
||||
ZFS_MODULE_CFLAGS += -include $(zfs_include)/zfs_config.h
|
||||
ZFS_MODULE_CFLAGS += -include $(zfs_include)/sys/simd_config.h
|
||||
endif
|
||||
|
||||
ZFS_MODULE_CFLAGS += -I$(zfs_include)/os/linux/kernel
|
||||
|
||||
@@ -38,6 +38,7 @@ CFLAGS+= -I${INCDIR}/os/freebsd
|
||||
CFLAGS+= -I${INCDIR}/os/freebsd/spl
|
||||
CFLAGS+= -I${INCDIR}/os/freebsd/zfs
|
||||
CFLAGS+= -I${SRCDIR}/zstd/include
|
||||
CFLAGS+= -include ${INCDIR}/sys/simd_config.h
|
||||
CFLAGS+= -include ${INCDIR}/os/freebsd/spl/sys/ccompile.h
|
||||
CFLAGS+= -I${.CURDIR}
|
||||
|
||||
@@ -46,8 +47,10 @@ CFLAGS+= -D__KERNEL__ -DFREEBSD_NAMECACHE -DBUILDING_ZFS -D__BSD_VISIBLE=1 \
|
||||
-D_SYS_VMEM_H_ -DKDTRACE_HOOKS -DCOMPAT_FREEBSD11
|
||||
|
||||
.if ${MACHINE_ARCH} == "amd64"
|
||||
CFLAGS+= -D__x86_64 -DHAVE_SSE2 -DHAVE_SSSE3 -DHAVE_SSE4_1 -DHAVE_SSE4_2 \
|
||||
-DHAVE_AVX -DHAVE_AVX2 -DHAVE_AVX512F -DHAVE_AVX512VL -DHAVE_AVX512BW
|
||||
CFLAGS+= -D__x86_64 -DHAVE_TOOLCHAIN_SSE2 -DHAVE_TOOLCHAIN_SSSE3 \
|
||||
-DHAVE_TOOLCHAIN_SSE4_1 -DHAVE_TOOLCHAIN_AVX -DHAVE_TOOLCHAIN_AVX2 \
|
||||
-DHAVE_TOOLCHAIN_AVX512F -DHAVE_TOOLCHAIN_AVX512VL \
|
||||
-DHAVE_TOOLCHAIN_AVX512BW
|
||||
.endif
|
||||
|
||||
.if defined(WITH_DEBUG) && ${WITH_DEBUG} == "true"
|
||||
|
||||
@@ -231,7 +231,7 @@ static const aes_impl_ops_t *aes_all_impl[] = {
|
||||
#if defined(__x86_64)
|
||||
&aes_x86_64_impl,
|
||||
#endif
|
||||
#if defined(__x86_64) && defined(HAVE_AES)
|
||||
#if defined(__x86_64) && HAVE_SIMD(AES)
|
||||
&aes_aesni_impl,
|
||||
#endif
|
||||
};
|
||||
@@ -315,7 +315,7 @@ aes_impl_init(void)
|
||||
* hardware accelerated version is the fastest.
|
||||
*/
|
||||
#if defined(__x86_64)
|
||||
#if defined(HAVE_AES)
|
||||
#if HAVE_SIMD(AES)
|
||||
if (aes_aesni_impl.is_supported()) {
|
||||
memcpy(&aes_fastest_impl, &aes_aesni_impl,
|
||||
sizeof (aes_fastest_impl));
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
#if defined(__x86_64) && defined(HAVE_AES)
|
||||
#if defined(__x86_64) && HAVE_SIMD(AES)
|
||||
|
||||
#include <sys/simd.h>
|
||||
#include <sys/types.h>
|
||||
@@ -123,4 +123,4 @@ const aes_impl_ops_t aes_aesni_impl = {
|
||||
.name = "aesni"
|
||||
};
|
||||
|
||||
#endif /* defined(__x86_64) && defined(HAVE_AES) */
|
||||
#endif /* defined(__x86_64) && HAVE_SIMD(AES) */
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "blake3_impl.h"
|
||||
|
||||
#if !defined(OMIT_SIMD) && (defined(__aarch64__) || \
|
||||
(defined(__x86_64) && defined(HAVE_SSE2)) || \
|
||||
(defined(__x86_64) && HAVE_SIMD(SSE2)) || \
|
||||
(defined(__PPC64__) && defined(__LITTLE_ENDIAN__)))
|
||||
#define USE_SIMD
|
||||
#endif
|
||||
@@ -164,7 +164,7 @@ const blake3_ops_t blake3_sse41_impl = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64) && defined(HAVE_SSE4_1) && defined(HAVE_AVX2)
|
||||
#if defined(__x86_64) && HAVE_SIMD(SSE4_1) && HAVE_SIMD(AVX2)
|
||||
extern void ASMABI zfs_blake3_hash_many_avx2(const uint8_t * const *inputs,
|
||||
size_t num_inputs, size_t blocks, const uint32_t key[8],
|
||||
uint64_t counter, boolean_t increment_counter, uint8_t flags,
|
||||
@@ -197,7 +197,7 @@ blake3_avx2_impl = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64) && defined(HAVE_AVX512F) && defined(HAVE_AVX512VL)
|
||||
#if defined(__x86_64) && HAVE_SIMD(AVX512F) && HAVE_SIMD(AVX512VL)
|
||||
extern void ASMABI zfs_blake3_compress_in_place_avx512(uint32_t cv[8],
|
||||
const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len,
|
||||
uint64_t counter, uint8_t flags);
|
||||
@@ -261,19 +261,19 @@ static const blake3_ops_t *const blake3_impls[] = {
|
||||
&blake3_generic_impl,
|
||||
#ifdef USE_SIMD
|
||||
#if defined(__aarch64__) || \
|
||||
(defined(__x86_64) && defined(HAVE_SSE2)) || \
|
||||
(defined(__x86_64) && HAVE_SIMD(SSE2)) || \
|
||||
(defined(__PPC64__) && defined(__LITTLE_ENDIAN__))
|
||||
&blake3_sse2_impl,
|
||||
#endif
|
||||
#if defined(__aarch64__) || \
|
||||
(defined(__x86_64) && defined(HAVE_SSE4_1)) || \
|
||||
(defined(__x86_64) && HAVE_SIMD(SSE4_1)) || \
|
||||
(defined(__PPC64__) && defined(__LITTLE_ENDIAN__))
|
||||
&blake3_sse41_impl,
|
||||
#endif
|
||||
#if defined(__x86_64) && defined(HAVE_SSE4_1) && defined(HAVE_AVX2)
|
||||
#if defined(__x86_64) && HAVE_SIMD(SSE4_1) && HAVE_SIMD(AVX2)
|
||||
&blake3_avx2_impl,
|
||||
#endif
|
||||
#if defined(__x86_64) && defined(HAVE_AVX512F) && defined(HAVE_AVX512VL)
|
||||
#if defined(__x86_64) && HAVE_SIMD(AVX512F) && HAVE_SIMD(AVX512VL)
|
||||
&blake3_avx512_impl,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -714,7 +714,7 @@ static gcm_impl_ops_t gcm_fastest_impl = {
|
||||
/* All compiled in implementations */
|
||||
static const gcm_impl_ops_t *gcm_all_impl[] = {
|
||||
&gcm_generic_impl,
|
||||
#if defined(__x86_64) && defined(HAVE_PCLMULQDQ)
|
||||
#if defined(__x86_64) && HAVE_SIMD(PCLMULQDQ)
|
||||
&gcm_pclmulqdq_impl,
|
||||
#endif
|
||||
};
|
||||
@@ -801,7 +801,7 @@ gcm_impl_init(void)
|
||||
* Set the fastest implementation given the assumption that the
|
||||
* hardware accelerated version is the fastest.
|
||||
*/
|
||||
#if defined(__x86_64) && defined(HAVE_PCLMULQDQ)
|
||||
#if defined(__x86_64) && HAVE_SIMD(PCLMULQDQ)
|
||||
if (gcm_pclmulqdq_impl.is_supported()) {
|
||||
memcpy(&gcm_fastest_impl, &gcm_pclmulqdq_impl,
|
||||
sizeof (gcm_fastest_impl));
|
||||
@@ -827,7 +827,7 @@ gcm_impl_init(void)
|
||||
} else
|
||||
#endif
|
||||
if (gcm_avx_will_work()) {
|
||||
#ifdef HAVE_MOVBE
|
||||
#if HAVE_SIMD(MOVBE)
|
||||
if (zfs_movbe_available() == B_TRUE) {
|
||||
atomic_swap_32(&gcm_avx_can_use_movbe, B_TRUE);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
#if defined(__x86_64) && defined(HAVE_PCLMULQDQ)
|
||||
#if defined(__x86_64) && HAVE_SIMD(PCLMULQDQ)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/simd.h>
|
||||
@@ -63,4 +63,4 @@ const gcm_impl_ops_t gcm_pclmulqdq_impl = {
|
||||
.name = "pclmulqdq"
|
||||
};
|
||||
|
||||
#endif /* defined(__x86_64) && defined(HAVE_PCLMULQDQ) */
|
||||
#endif /* defined(__x86_64) && HAVE_SIMD(PCLMULQDQ) */
|
||||
@@ -65,7 +65,7 @@ const sha256_ops_t sha256_x64_impl = {
|
||||
.name = "x64"
|
||||
};
|
||||
|
||||
#if defined(HAVE_SSSE3)
|
||||
#if HAVE_SIMD(SSSE3)
|
||||
static boolean_t sha2_have_ssse3(void)
|
||||
{
|
||||
return (kfpu_allowed() && zfs_ssse3_available());
|
||||
@@ -79,7 +79,7 @@ const sha256_ops_t sha256_ssse3_impl = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_AVX)
|
||||
#if HAVE_SIMD(AVX)
|
||||
static boolean_t sha2_have_avx(void)
|
||||
{
|
||||
return (kfpu_allowed() && zfs_avx_available());
|
||||
@@ -93,7 +93,7 @@ const sha256_ops_t sha256_avx_impl = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_AVX2)
|
||||
#if HAVE_SIMD(AVX2)
|
||||
static boolean_t sha2_have_avx2(void)
|
||||
{
|
||||
return (kfpu_allowed() && zfs_avx2_available());
|
||||
@@ -107,7 +107,7 @@ const sha256_ops_t sha256_avx2_impl = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SSE4_1)
|
||||
#if HAVE_SIMD(SSE4_1)
|
||||
static boolean_t sha2_have_shani(void)
|
||||
{
|
||||
return (kfpu_allowed() && zfs_sse4_1_available() && \
|
||||
@@ -186,16 +186,16 @@ static const sha256_ops_t *const sha256_impls[] = {
|
||||
#if defined(__x86_64)
|
||||
&sha256_x64_impl,
|
||||
#endif
|
||||
#if defined(__x86_64) && defined(HAVE_SSSE3)
|
||||
#if defined(__x86_64) && HAVE_SIMD(SSSE3)
|
||||
&sha256_ssse3_impl,
|
||||
#endif
|
||||
#if defined(__x86_64) && defined(HAVE_AVX)
|
||||
#if defined(__x86_64) && HAVE_SIMD(AVX)
|
||||
&sha256_avx_impl,
|
||||
#endif
|
||||
#if defined(__x86_64) && defined(HAVE_AVX2)
|
||||
#if defined(__x86_64) && HAVE_SIMD(AVX2)
|
||||
&sha256_avx2_impl,
|
||||
#endif
|
||||
#if defined(__x86_64) && defined(HAVE_SSE4_1)
|
||||
#if defined(__x86_64) && HAVE_SIMD(SSE4_1)
|
||||
&sha256_shani_impl,
|
||||
#endif
|
||||
#if defined(__aarch64__) || defined(__arm__)
|
||||
|
||||
@@ -65,7 +65,7 @@ const sha512_ops_t sha512_x64_impl = {
|
||||
.name = "x64"
|
||||
};
|
||||
|
||||
#if defined(HAVE_AVX)
|
||||
#if HAVE_SIMD(AVX)
|
||||
static boolean_t sha2_have_avx(void)
|
||||
{
|
||||
return (kfpu_allowed() && zfs_avx_available());
|
||||
@@ -79,7 +79,7 @@ const sha512_ops_t sha512_avx_impl = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_AVX2)
|
||||
#if HAVE_SIMD(AVX2)
|
||||
static boolean_t sha2_have_avx2(void)
|
||||
{
|
||||
return (kfpu_allowed() && zfs_avx2_available());
|
||||
@@ -93,7 +93,7 @@ const sha512_ops_t sha512_avx2_impl = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SHA512EXT)
|
||||
#if HAVE_SIMD(SHA512EXT)
|
||||
static boolean_t sha2_have_sha512ext(void)
|
||||
{
|
||||
return (kfpu_allowed() && zfs_sha512ext_available());
|
||||
@@ -173,13 +173,13 @@ static const sha512_ops_t *const sha512_impls[] = {
|
||||
#if defined(__x86_64)
|
||||
&sha512_x64_impl,
|
||||
#endif
|
||||
#if defined(__x86_64) && defined(HAVE_AVX)
|
||||
#if defined(__x86_64) && HAVE_SIMD(AVX)
|
||||
&sha512_avx_impl,
|
||||
#endif
|
||||
#if defined(__x86_64) && defined(HAVE_AVX2)
|
||||
#if defined(__x86_64) && HAVE_SIMD(AVX2)
|
||||
&sha512_avx2_impl,
|
||||
#endif
|
||||
#if defined(__x86_64) && defined(HAVE_SHA512EXT)
|
||||
#if defined(__x86_64) && HAVE_SIMD(SHA512EXT)
|
||||
&sha512_sha512ext_impl,
|
||||
#endif
|
||||
#if defined(__aarch64__) || defined(__arm__)
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
|
||||
#if defined(__aarch64__)
|
||||
|
||||
/* make gcc <= 9 happy */
|
||||
#if !defined(LD_VERSION) || LD_VERSION >= 233010000
|
||||
/* check for .cfi_negate_ra_state assembler support */
|
||||
#if defined(HAVE_AS_CFI_PSEUDO_OP)
|
||||
#define CFI_NEGATE_RA_STATE .cfi_negate_ra_state
|
||||
#else
|
||||
#define CFI_NEGATE_RA_STATE
|
||||
|
||||
Loaded 100 of 180 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user