mirror of
https://github.com/opnsense/src.git
synced 2026-06-17 20:49:40 -04:00
zfs: merge openzfs/zfs@8302b6e32
Notable upstream pull request merges: #16853894edd084Add TXG timestamp database #17004 -multiple Implement dynamic gang header sizes #17405dea0fc969ZVOL: Return early, if volmode is ZFS_VOLMODE_NONE on FreeBSD side #17455cf146460cDefault to zfs_bclone_wait_dirty=1 #17481523d9d600Validate mountpoint on path-based unmount using statx #1748292da9e0e9ZVOL: Implement zvol_alloc() function on FreeBSD side #17489dee62e074spa: ZIO_TASKQ_ISSUE: Use symbolic priority #17496bf846dcb7Release topology restrictions on special/dedup #174974e92aee23Relax special_small_blocks restrictions #17503ea38787f2Revert "Fix incorrect expected error in ztest" #17505be1e991a1Allow and prefer special vdevs as ZIL #17506ee0cb4cb8ztest: Fix false positive of ENOSPC handling #1750792d3b4ee2zio: rename `io_reexecute` as `io_post`; use it for the direct IO checksum error flag #175086af8db61bmetaslab: don't pass whole zio to throttle reserve APIs #175184c2a7f85dFreeBSD: Add support for _PC_HAS_HIDDENSYSTEM #17521d7ab07dfbZIL: Force writing of open LWB on suspend #17524b6e8db509zpool/zfs: Add '-a|--all' option to scrub, trim, initialize #17531c1e51c55fCorrect weight recalculation of space-based metaslabs #17533d323fbf49FreeBSD: zfs_putpages: don't undirty pages until after write completes #17536b21e04e8dFix zdb pool/ with -k #17537 -multiple Userspace tunables #175402957eabbeAdd support for FreeBSD's Solaris style extended attribute interface #175474bd7a2eaazdb: fix checksum calculation for decompressed blocks #17551 -multiple cleanup: remove var init/update #175610f8a1105eSkip dbuf_evict_one() from dbuf_evict_notify() for reclaim thread #1756310a78e264Faster checksum benchmark on system boot #1756400ce064d8spa: update blkptr diagram to include vdev padding on encrypted blocks #17565 -multiple Physical rewrite #17566fc885f308Don't use wrong weight when passivating group #17572f70c85086BRT: Fix ZAP entry endianness #175750b6fd024aZVOL: Unify zvol minors operations and improve error handling #17581cb5e7e097range_tree: Provide more debug details upon unexpected add/remove #17587 -multiple Fix two issues with dynamic gang headers Obtained from: OpenZFS OpenZFS commit:8302b6e32b
This commit is contained in:
commit
df58e8b150
217 changed files with 5837 additions and 1728 deletions
|
|
@ -16,6 +16,7 @@ SRCS = \
|
|||
os/freebsd/zone.c \
|
||||
page.c \
|
||||
timestamp.c \
|
||||
tunables.c \
|
||||
include/sys/list.h \
|
||||
include/sys/list_impl.h
|
||||
|
||||
|
|
|
|||
|
|
@ -175,6 +175,8 @@ KERNEL_C = \
|
|||
zfeature.c \
|
||||
zfs_byteswap.c \
|
||||
zfs_chksum.c \
|
||||
zfs_crrd.c \
|
||||
zfs_debug_common.c \
|
||||
zfs_fm.c \
|
||||
zfs_fuid.c \
|
||||
zfs_sa.c \
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include_next <sys/zfs_context.h>
|
||||
|
||||
#define ZFS_MODULE_PARAM_ARGS void
|
||||
#define SYSCTL_HANDLER_ARGS void
|
||||
|
||||
/*
|
||||
* Not sure why I need these, but including the canonical stand.h fails because
|
||||
|
|
|
|||
|
|
@ -359,6 +359,7 @@ contrib/openzfs/module/zfs/zcp_synctask.c optional zfs compile-with "${ZFS_C}"
|
|||
contrib/openzfs/module/zfs/zfeature.c optional zfs compile-with "${ZFS_C}"
|
||||
contrib/openzfs/module/zfs/zfs_byteswap.c optional zfs compile-with "${ZFS_C}"
|
||||
contrib/openzfs/module/zfs/zfs_chksum.c optional zfs compile-with "${ZFS_C}"
|
||||
contrib/openzfs/module/zfs/zfs_crrd.c optional zfs compile-with "${ZFS_C}"
|
||||
contrib/openzfs/module/zfs/zfs_fm.c optional zfs compile-with "${ZFS_C} ${NO_WUNUSED_BUT_SET_VARIABLE}"
|
||||
contrib/openzfs/module/zfs/zfs_fuid.c optional zfs compile-with "${ZFS_C}"
|
||||
contrib/openzfs/module/zfs/zfs_impl.c optional zfs compile-with "${ZFS_C}"
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
env:
|
||||
CIRRUS_CLONE_DEPTH: 1
|
||||
ARCH: amd64
|
||||
|
||||
build_task:
|
||||
matrix:
|
||||
freebsd_instance:
|
||||
image_family: freebsd-13-5
|
||||
freebsd_instance:
|
||||
image_family: freebsd-14-2
|
||||
freebsd_instance:
|
||||
image_family: freebsd-15-0-snap
|
||||
prepare_script:
|
||||
- pkg install -y autoconf automake libtool gettext-runtime gmake ksh93 py311-packaging py311-cffi py311-sysctl
|
||||
configure_script:
|
||||
- env MAKE=gmake ./autogen.sh
|
||||
- env MAKE=gmake ./configure --with-config="user" --with-python=3.11
|
||||
build_script:
|
||||
- gmake -j `sysctl -n kern.smp.cpus`
|
||||
install_script:
|
||||
- gmake install
|
||||
1
sys/contrib/openzfs/.github/codeql-cpp.yml
vendored
1
sys/contrib/openzfs/.github/codeql-cpp.yml
vendored
|
|
@ -2,3 +2,4 @@ name: "Custom CodeQL Analysis"
|
|||
|
||||
queries:
|
||||
- uses: ./.github/codeql/custom-queries/cpp/deprecatedFunctionUsage.ql
|
||||
- uses: ./.github/codeql/custom-queries/cpp/dslDatasetHoldReleMismatch.ql
|
||||
|
|
|
|||
34
sys/contrib/openzfs/.github/codeql/custom-queries/cpp/dslDatasetHoldReleMismatch.ql
vendored
Normal file
34
sys/contrib/openzfs/.github/codeql/custom-queries/cpp/dslDatasetHoldReleMismatch.ql
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* @name Detect mismatched dsl_dataset_hold/_rele pairs
|
||||
* @description Flags instances of issue #12014 where
|
||||
* - a dataset held with dsl_dataset_hold_obj() ends up in dsl_dataset_rele_flags(), or
|
||||
* - a dataset held with dsl_dataset_hold_obj_flags() ends up in dsl_dataset_rele().
|
||||
* @kind problem
|
||||
* @severity error
|
||||
* @tags correctness
|
||||
* @id cpp/dslDatasetHoldReleMismatch
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from Variable ds, Call holdCall, Call releCall, string message
|
||||
where
|
||||
ds.getType().toString() = "dsl_dataset_t *" and
|
||||
holdCall.getASuccessor*() = releCall and
|
||||
(
|
||||
(holdCall.getTarget().getName() = "dsl_dataset_hold_obj_flags" and
|
||||
holdCall.getArgument(4).(AddressOfExpr).getOperand().(VariableAccess).getTarget() = ds and
|
||||
releCall.getTarget().getName() = "dsl_dataset_rele" and
|
||||
releCall.getArgument(0).(VariableAccess).getTarget() = ds and
|
||||
message = "Held with dsl_dataset_hold_obj_flags but released with dsl_dataset_rele")
|
||||
or
|
||||
(holdCall.getTarget().getName() = "dsl_dataset_hold_obj" and
|
||||
holdCall.getArgument(3).(AddressOfExpr).getOperand().(VariableAccess).getTarget() = ds and
|
||||
releCall.getTarget().getName() = "dsl_dataset_rele_flags" and
|
||||
releCall.getArgument(0).(VariableAccess).getTarget() = ds and
|
||||
message = "Held with dsl_dataset_hold_obj but released with dsl_dataset_rele_flags")
|
||||
)
|
||||
select releCall,
|
||||
"Mismatched release: held with $@ but released with " + releCall.getTarget().getName() + " for dataset $@",
|
||||
holdCall, holdCall.getTarget().getName(),
|
||||
ds, ds.toString()
|
||||
|
|
@ -71,14 +71,6 @@ case "$OS" in
|
|||
OSv="fedora-unknown"
|
||||
URL="https://download.fedoraproject.org/pub/fedora/linux/releases/42/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-42-1.1.x86_64.qcow2"
|
||||
;;
|
||||
freebsd13-4r)
|
||||
FreeBSD="13.4-RELEASE"
|
||||
OSNAME="FreeBSD $FreeBSD"
|
||||
OSv="freebsd13.0"
|
||||
URLxz="$FREEBSD_REL/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI.raw.xz"
|
||||
KSRC="$FREEBSD_REL/../amd64/$FreeBSD/src.txz"
|
||||
NIC="rtl8139"
|
||||
;;
|
||||
freebsd13-5r)
|
||||
FreeBSD="13.5-RELEASE"
|
||||
OSNAME="FreeBSD $FreeBSD"
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ function debian() {
|
|||
export DEBIAN_FRONTEND="noninteractive"
|
||||
|
||||
echo "##[group]Running apt-get update+upgrade"
|
||||
sudo sed -i '/[[:alpha:]]-backports/d' /etc/apt/sources.list
|
||||
sudo apt-get update -y
|
||||
sudo apt-get upgrade -y
|
||||
echo "##[endgroup]"
|
||||
|
|
@ -51,7 +52,7 @@ function freebsd() {
|
|||
|
||||
echo "##[group]Install Development Tools"
|
||||
sudo pkg install -y autoconf automake autotools base64 checkbashisms fio \
|
||||
gdb gettext gettext-runtime git gmake gsed jq ksh93 lcov libtool lscpu \
|
||||
gdb gettext gettext-runtime git gmake gsed jq ksh lcov libtool lscpu \
|
||||
pkgconf python python3 pamtester pamtester qemu-guest-agent rsync xxhash
|
||||
sudo pkg install -xy \
|
||||
'^samba4[[:digit:]]+$' \
|
||||
|
|
|
|||
|
|
@ -21,11 +21,13 @@ function prefix() {
|
|||
S=$((DIFF-(M*60)))
|
||||
|
||||
CTR=$(cat /tmp/ctr)
|
||||
echo $LINE| grep -q "^Test[: ]" && CTR=$((CTR+1)) && echo $CTR > /tmp/ctr
|
||||
echo $LINE| grep -q '^\[.*] Test[: ]' && CTR=$((CTR+1)) && echo $CTR > /tmp/ctr
|
||||
|
||||
BASE="$HOME/work/zfs/zfs"
|
||||
COLOR="$BASE/scripts/zfs-tests-color.sh"
|
||||
CLINE=$(echo $LINE| grep "^Test[ :]" | sed -e 's|/usr/local|/usr|g' \
|
||||
CLINE=$(echo $LINE| grep '^\[.*] Test[: ]' \
|
||||
| sed -e 's|^\[.*] Test|Test|g' \
|
||||
| sed -e 's|/usr/local|/usr|g' \
|
||||
| sed -e 's| /usr/share/zfs/zfs-tests/tests/| |g' | $COLOR)
|
||||
if [ -z "$CLINE" ]; then
|
||||
printf "vm${ID}: %s\n" "$LINE"
|
||||
|
|
|
|||
|
|
@ -5,16 +5,6 @@ on:
|
|||
pull_request:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
include_stream9:
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
description: 'Test on CentOS 9 stream'
|
||||
include_stream10:
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
description: 'Test on CentOS 10 stream'
|
||||
fedora_kernel_ver:
|
||||
type: string
|
||||
required: false
|
||||
|
|
@ -39,7 +29,7 @@ jobs:
|
|||
- name: Generate OS config and CI type
|
||||
id: os
|
||||
run: |
|
||||
FULL_OS='["almalinux8", "almalinux9", "almalinux10", "debian11", "debian12", "fedora41", "fedora42", "freebsd13-4r", "freebsd14-3s", "freebsd15-0c", "ubuntu22", "ubuntu24"]'
|
||||
FULL_OS='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian11", "debian12", "fedora41", "fedora42", "freebsd13-5r", "freebsd14-3s", "freebsd15-0c", "ubuntu22", "ubuntu24"]'
|
||||
QUICK_OS='["almalinux8", "almalinux9", "almalinux10", "debian12", "fedora42", "freebsd14-3s", "ubuntu24"]'
|
||||
# determine CI type when running on PR
|
||||
ci_type="full"
|
||||
|
|
@ -63,14 +53,6 @@ jobs:
|
|||
os_json=$(echo ${os_selection} | jq -c)
|
||||
fi
|
||||
|
||||
# Add optional runners
|
||||
if [ "${{ github.event.inputs.include_stream9 }}" == 'true' ]; then
|
||||
os_json=$(echo $os_json | jq -c '. += ["centos-stream9"]')
|
||||
fi
|
||||
if [ "${{ github.event.inputs.include_stream10 }}" == 'true' ]; then
|
||||
os_json=$(echo $os_json | jq -c '. += ["centos-stream10"]')
|
||||
fi
|
||||
|
||||
echo $os_json
|
||||
echo "os=$os_json" >> $GITHUB_OUTPUT
|
||||
echo "ci_type=$ci_type" >> $GITHUB_OUTPUT
|
||||
|
|
@ -85,7 +67,7 @@ jobs:
|
|||
# debian: debian11, debian12, ubuntu22, ubuntu24
|
||||
# misc: archlinux, tumbleweed
|
||||
# FreeBSD variants of 2025-06:
|
||||
# FreeBSD Release: freebsd13-4r, freebsd13-5r, freebsd14-1r, freebsd14-2r, freebsd14-3r
|
||||
# FreeBSD Release: freebsd13-5r, freebsd14-2r, freebsd14-3r
|
||||
# FreeBSD Stable: freebsd13-5s, freebsd14-3s
|
||||
# FreeBSD Current: freebsd15-0c
|
||||
os: ${{ fromJson(needs.test-config.outputs.test_os) }}
|
||||
|
|
|
|||
24
sys/contrib/openzfs/.github/workflows/zloop.yml
vendored
24
sys/contrib/openzfs/.github/workflows/zloop.yml
vendored
|
|
@ -12,7 +12,8 @@ jobs:
|
|||
zloop:
|
||||
runs-on: ubuntu-24.04
|
||||
env:
|
||||
TEST_DIR: /var/tmp/zloop
|
||||
WORK_DIR: /mnt/zloop
|
||||
CORE_DIR: /mnt/zloop/cores
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
|
|
@ -40,38 +41,37 @@ jobs:
|
|||
sudo modprobe zfs
|
||||
- name: Tests
|
||||
run: |
|
||||
sudo mkdir -p $TEST_DIR
|
||||
# run for 10 minutes or at most 6 iterations for a maximum runner
|
||||
# time of 60 minutes.
|
||||
sudo /usr/share/zfs/zloop.sh -t 600 -I 6 -l -m 1 -- -T 120 -P 60
|
||||
sudo truncate -s 256G /mnt/vdev
|
||||
sudo zpool create cipool -m $WORK_DIR -O compression=on -o autotrim=on /mnt/vdev
|
||||
sudo /usr/share/zfs/zloop.sh -t 600 -I 6 -l -m 1 -c $CORE_DIR -f $WORK_DIR -- -T 120 -P 60
|
||||
- name: Prepare artifacts
|
||||
if: failure()
|
||||
run: |
|
||||
sudo chmod +r -R $TEST_DIR/
|
||||
sudo chmod +r -R $WORK_DIR/
|
||||
- name: Ztest log
|
||||
if: failure()
|
||||
run: |
|
||||
grep -B10 -A1000 'ASSERT' $TEST_DIR/*/ztest.out || tail -n 1000 $TEST_DIR/*/ztest.out
|
||||
grep -B10 -A1000 'ASSERT' $CORE_DIR/*/ztest.out || tail -n 1000 $CORE_DIR/*/ztest.out
|
||||
- name: Gdb log
|
||||
if: failure()
|
||||
run: |
|
||||
sed -n '/Backtraces (full)/q;p' $TEST_DIR/*/ztest.gdb
|
||||
sed -n '/Backtraces (full)/q;p' $CORE_DIR/*/ztest.gdb
|
||||
- name: Zdb log
|
||||
if: failure()
|
||||
run: |
|
||||
cat $TEST_DIR/*/ztest.zdb
|
||||
cat $CORE_DIR/*/ztest.zdb
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: failure()
|
||||
with:
|
||||
name: Logs
|
||||
path: |
|
||||
/var/tmp/zloop/*/
|
||||
!/var/tmp/zloop/*/vdev/
|
||||
/mnt/zloop/*/
|
||||
!/mnt/zloop/cores/*/vdev/
|
||||
if-no-files-found: ignore
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: failure()
|
||||
with:
|
||||
name: Pool files
|
||||
path: |
|
||||
/var/tmp/zloop/*/vdev/
|
||||
/mnt/zloop/cores/*/vdev/
|
||||
if-no-files-found: ignore
|
||||
|
|
|
|||
|
|
@ -559,6 +559,7 @@ def section_arc(kstats_dict):
|
|||
print()
|
||||
|
||||
compressed_size = arc_stats['compressed_size']
|
||||
uncompressed_size = arc_stats['uncompressed_size']
|
||||
overhead_size = arc_stats['overhead_size']
|
||||
bonus_size = arc_stats['bonus_size']
|
||||
dnode_size = arc_stats['dnode_size']
|
||||
|
|
@ -671,6 +672,8 @@ def section_arc(kstats_dict):
|
|||
print()
|
||||
|
||||
print('ARC misc:')
|
||||
prt_i2('Uncompressed size:', f_perc(uncompressed_size, compressed_size),
|
||||
f_bytes(uncompressed_size))
|
||||
prt_i1('Memory throttles:', arc_stats['memory_throttle_count'])
|
||||
prt_i1('Memory direct reclaims:', arc_stats['memory_direct_count'])
|
||||
prt_i1('Memory indirect reclaims:', arc_stats['memory_indirect_count'])
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ sublivelist_verify_blkptr(void *arg, const blkptr_t *bp, boolean_t free,
|
|||
sublivelist_verify_block_t svb = {
|
||||
.svb_dva = bp->blk_dva[i],
|
||||
.svb_allocated_txg =
|
||||
BP_GET_LOGICAL_BIRTH(bp)
|
||||
BP_GET_BIRTH(bp)
|
||||
};
|
||||
|
||||
if (zfs_btree_find(&sv->sv_leftover, &svb,
|
||||
|
|
@ -619,8 +619,9 @@ livelist_metaslab_validate(spa_t *spa)
|
|||
metaslab_calculate_range_tree_type(vd, m,
|
||||
&start, &shift);
|
||||
metaslab_verify_t mv;
|
||||
mv.mv_allocated = zfs_range_tree_create(NULL,
|
||||
type, NULL, start, shift);
|
||||
mv.mv_allocated = zfs_range_tree_create_flags(
|
||||
NULL, type, NULL, start, shift,
|
||||
0, "livelist_metaslab_validate:mv_allocated");
|
||||
mv.mv_vdid = vd->vdev_id;
|
||||
mv.mv_msid = m->ms_id;
|
||||
mv.mv_start = m->ms_start;
|
||||
|
|
@ -797,8 +798,8 @@ usage(void)
|
|||
"[default is 200]\n");
|
||||
(void) fprintf(stderr, " -K --key=KEY "
|
||||
"decryption key for encrypted dataset\n");
|
||||
(void) fprintf(stderr, " -o --option=\"OPTION=INTEGER\" "
|
||||
"set global variable to an unsigned 32-bit integer\n");
|
||||
(void) fprintf(stderr, " -o --option=\"NAME=VALUE\" "
|
||||
"set the named tunable to the given value\n");
|
||||
(void) fprintf(stderr, " -p --path==PATH "
|
||||
"use one or more with -e to specify path to vdev dir\n");
|
||||
(void) fprintf(stderr, " -P --parseable "
|
||||
|
|
@ -1991,7 +1992,7 @@ dump_ddt_log(ddt_t *ddt)
|
|||
c += strlcpy(&flagstr[c], " UNKNOWN",
|
||||
sizeof (flagstr) - c);
|
||||
flagstr[1] = '[';
|
||||
flagstr[c++] = ']';
|
||||
flagstr[c] = ']';
|
||||
}
|
||||
|
||||
uint64_t count = avl_numnodes(&ddl->ddl_tree);
|
||||
|
|
@ -2568,7 +2569,7 @@ snprintf_blkptr_compact(char *blkbuf, size_t buflen, const blkptr_t *bp,
|
|||
(u_longlong_t)BP_GET_PSIZE(bp),
|
||||
(u_longlong_t)BP_GET_FILL(bp),
|
||||
(u_longlong_t)BP_GET_LOGICAL_BIRTH(bp),
|
||||
(u_longlong_t)BP_GET_BIRTH(bp));
|
||||
(u_longlong_t)BP_GET_PHYSICAL_BIRTH(bp));
|
||||
if (bp_freed)
|
||||
(void) snprintf(blkbuf + strlen(blkbuf),
|
||||
buflen - strlen(blkbuf), " %s", "FREE");
|
||||
|
|
@ -2618,7 +2619,7 @@ visit_indirect(spa_t *spa, const dnode_phys_t *dnp,
|
|||
{
|
||||
int err = 0;
|
||||
|
||||
if (BP_GET_LOGICAL_BIRTH(bp) == 0)
|
||||
if (BP_GET_BIRTH(bp) == 0)
|
||||
return (0);
|
||||
|
||||
print_indirect(spa, bp, zb, dnp);
|
||||
|
|
@ -2806,7 +2807,7 @@ dump_bptree_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
|
|||
(void) arg, (void) tx;
|
||||
char blkbuf[BP_SPRINTF_LEN];
|
||||
|
||||
if (BP_GET_LOGICAL_BIRTH(bp) != 0) {
|
||||
if (BP_GET_BIRTH(bp) != 0) {
|
||||
snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
|
||||
(void) printf("\t%s\n", blkbuf);
|
||||
}
|
||||
|
|
@ -2847,7 +2848,7 @@ dump_bpobj_cb(void *arg, const blkptr_t *bp, boolean_t bp_freed, dmu_tx_t *tx)
|
|||
(void) arg, (void) tx;
|
||||
char blkbuf[BP_SPRINTF_LEN];
|
||||
|
||||
ASSERT(BP_GET_LOGICAL_BIRTH(bp) != 0);
|
||||
ASSERT(BP_GET_BIRTH(bp) != 0);
|
||||
snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), bp, bp_freed);
|
||||
(void) printf("\t%s\n", blkbuf);
|
||||
return (0);
|
||||
|
|
@ -5921,11 +5922,11 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp,
|
|||
* entry back to the block pointer before we claim it.
|
||||
*/
|
||||
if (v == DDT_PHYS_FLAT) {
|
||||
ASSERT3U(BP_GET_BIRTH(bp), ==,
|
||||
ASSERT3U(BP_GET_PHYSICAL_BIRTH(bp), ==,
|
||||
ddt_phys_birth(dde->dde_phys, v));
|
||||
tempbp = *bp;
|
||||
ddt_bp_fill(dde->dde_phys, v, &tempbp,
|
||||
BP_GET_BIRTH(bp));
|
||||
BP_GET_PHYSICAL_BIRTH(bp));
|
||||
bp = &tempbp;
|
||||
}
|
||||
|
||||
|
|
@ -6151,7 +6152,7 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
|
|||
if (zb->zb_level == ZB_DNODE_LEVEL)
|
||||
return (0);
|
||||
|
||||
if (dump_opt['b'] >= 5 && BP_GET_LOGICAL_BIRTH(bp) > 0) {
|
||||
if (dump_opt['b'] >= 5 && BP_GET_BIRTH(bp) > 0) {
|
||||
char blkbuf[BP_SPRINTF_LEN];
|
||||
snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
|
||||
(void) printf("objset %llu object %llu "
|
||||
|
|
@ -6322,8 +6323,9 @@ zdb_claim_removing(spa_t *spa, zdb_cb_t *zcb)
|
|||
|
||||
ASSERT0(zfs_range_tree_space(svr->svr_allocd_segs));
|
||||
|
||||
zfs_range_tree_t *allocs = zfs_range_tree_create(NULL, ZFS_RANGE_SEG64,
|
||||
NULL, 0, 0);
|
||||
zfs_range_tree_t *allocs = zfs_range_tree_create_flags(
|
||||
NULL, ZFS_RANGE_SEG64, NULL, 0, 0,
|
||||
0, "zdb_claim_removing:allocs");
|
||||
for (uint64_t msi = 0; msi < vd->vdev_ms_count; msi++) {
|
||||
metaslab_t *msp = vd->vdev_ms[msi];
|
||||
|
||||
|
|
@ -6750,6 +6752,7 @@ zdb_leak_init(spa_t *spa, zdb_cb_t *zcb)
|
|||
spa->spa_normal_class->mc_ops = &zdb_metaslab_ops;
|
||||
spa->spa_log_class->mc_ops = &zdb_metaslab_ops;
|
||||
spa->spa_embedded_log_class->mc_ops = &zdb_metaslab_ops;
|
||||
spa->spa_special_embedded_log_class->mc_ops = &zdb_metaslab_ops;
|
||||
|
||||
zcb->zcb_vd_obsolete_counts =
|
||||
umem_zalloc(rvd->vdev_children * sizeof (uint32_t *),
|
||||
|
|
@ -6887,7 +6890,9 @@ zdb_leak_fini(spa_t *spa, zdb_cb_t *zcb)
|
|||
for (uint64_t m = 0; m < vd->vdev_ms_count; m++) {
|
||||
metaslab_t *msp = vd->vdev_ms[m];
|
||||
ASSERT3P(msp->ms_group, ==, (msp->ms_group->mg_class ==
|
||||
spa_embedded_log_class(spa)) ?
|
||||
spa_embedded_log_class(spa) ||
|
||||
msp->ms_group->mg_class ==
|
||||
spa_special_embedded_log_class(spa)) ?
|
||||
vd->vdev_log_mg : vd->vdev_mg);
|
||||
|
||||
/*
|
||||
|
|
@ -7121,6 +7126,8 @@ dump_block_stats(spa_t *spa)
|
|||
zcb->zcb_totalasize += metaslab_class_get_alloc(spa_dedup_class(spa));
|
||||
zcb->zcb_totalasize +=
|
||||
metaslab_class_get_alloc(spa_embedded_log_class(spa));
|
||||
zcb->zcb_totalasize +=
|
||||
metaslab_class_get_alloc(spa_special_embedded_log_class(spa));
|
||||
zcb->zcb_start = zcb->zcb_lastprint = gethrtime();
|
||||
err = traverse_pool(spa, 0, flags, zdb_blkptr_cb, zcb);
|
||||
|
||||
|
|
@ -7169,6 +7176,7 @@ dump_block_stats(spa_t *spa)
|
|||
total_alloc = norm_alloc +
|
||||
metaslab_class_get_alloc(spa_log_class(spa)) +
|
||||
metaslab_class_get_alloc(spa_embedded_log_class(spa)) +
|
||||
metaslab_class_get_alloc(spa_special_embedded_log_class(spa)) +
|
||||
metaslab_class_get_alloc(spa_special_class(spa)) +
|
||||
metaslab_class_get_alloc(spa_dedup_class(spa)) +
|
||||
get_unflushed_alloc_space(spa);
|
||||
|
|
@ -7252,6 +7260,18 @@ dump_block_stats(spa_t *spa)
|
|||
100.0 * alloc / space);
|
||||
}
|
||||
|
||||
if (spa_special_embedded_log_class(spa)->mc_allocator[0].mca_rotor
|
||||
!= NULL) {
|
||||
uint64_t alloc = metaslab_class_get_alloc(
|
||||
spa_special_embedded_log_class(spa));
|
||||
uint64_t space = metaslab_class_get_space(
|
||||
spa_special_embedded_log_class(spa));
|
||||
|
||||
(void) printf("\t%-16s %14llu used: %5.2f%%\n",
|
||||
"Special embedded log", (u_longlong_t)alloc,
|
||||
100.0 * alloc / space);
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_BP_EMBEDDED_TYPES; i++) {
|
||||
if (zcb->zcb_embedded_blocks[i] == 0)
|
||||
continue;
|
||||
|
|
@ -7706,7 +7726,8 @@ zdb_set_skip_mmp(char *target)
|
|||
* applies to the new_path parameter if allocated.
|
||||
*/
|
||||
static char *
|
||||
import_checkpointed_state(char *target, nvlist_t *cfg, char **new_path)
|
||||
import_checkpointed_state(char *target, nvlist_t *cfg, boolean_t target_is_spa,
|
||||
char **new_path)
|
||||
{
|
||||
int error = 0;
|
||||
char *poolname, *bogus_name = NULL;
|
||||
|
|
@ -7714,11 +7735,11 @@ import_checkpointed_state(char *target, nvlist_t *cfg, char **new_path)
|
|||
|
||||
/* If the target is not a pool, the extract the pool name */
|
||||
char *path_start = strchr(target, '/');
|
||||
if (path_start != NULL) {
|
||||
if (target_is_spa || path_start == NULL) {
|
||||
poolname = target;
|
||||
} else {
|
||||
size_t poolname_len = path_start - target;
|
||||
poolname = strndup(target, poolname_len);
|
||||
} else {
|
||||
poolname = target;
|
||||
}
|
||||
|
||||
if (cfg == NULL) {
|
||||
|
|
@ -7749,10 +7770,11 @@ import_checkpointed_state(char *target, nvlist_t *cfg, char **new_path)
|
|||
"with error %d\n", bogus_name, error);
|
||||
}
|
||||
|
||||
if (new_path != NULL && path_start != NULL) {
|
||||
if (asprintf(new_path, "%s%s", bogus_name, path_start) == -1) {
|
||||
if (new_path != NULL && !target_is_spa) {
|
||||
if (asprintf(new_path, "%s%s", bogus_name,
|
||||
path_start != NULL ? path_start : "") == -1) {
|
||||
free(bogus_name);
|
||||
if (path_start != NULL)
|
||||
if (!target_is_spa && path_start != NULL)
|
||||
free(poolname);
|
||||
return (NULL);
|
||||
}
|
||||
|
|
@ -7981,7 +8003,7 @@ verify_checkpoint_blocks(spa_t *spa)
|
|||
* name) so we can do verification on it against the current state
|
||||
* of the pool.
|
||||
*/
|
||||
checkpoint_pool = import_checkpointed_state(spa->spa_name, NULL,
|
||||
checkpoint_pool = import_checkpointed_state(spa->spa_name, NULL, B_TRUE,
|
||||
NULL);
|
||||
ASSERT(strcmp(spa->spa_name, checkpoint_pool) != 0);
|
||||
|
||||
|
|
@ -8451,8 +8473,9 @@ dump_zpool(spa_t *spa)
|
|||
|
||||
if (dump_opt['d'] || dump_opt['i']) {
|
||||
spa_feature_t f;
|
||||
mos_refd_objs = zfs_range_tree_create(NULL, ZFS_RANGE_SEG64,
|
||||
NULL, 0, 0);
|
||||
mos_refd_objs = zfs_range_tree_create_flags(
|
||||
NULL, ZFS_RANGE_SEG64, NULL, 0, 0,
|
||||
0, "dump_zpool:mos_refd_objs");
|
||||
dump_objset(dp->dp_meta_objset);
|
||||
|
||||
if (dump_opt['d'] >= 3) {
|
||||
|
|
@ -8588,9 +8611,9 @@ zdb_dump_indirect(blkptr_t *bp, int nbps, int flags)
|
|||
}
|
||||
|
||||
static void
|
||||
zdb_dump_gbh(void *buf, int flags)
|
||||
zdb_dump_gbh(void *buf, uint64_t size, int flags)
|
||||
{
|
||||
zdb_dump_indirect((blkptr_t *)buf, SPA_GBH_NBLKPTRS, flags);
|
||||
zdb_dump_indirect((blkptr_t *)buf, gbh_nblkptrs(size), flags);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -8780,7 +8803,6 @@ zdb_decompress_block(abd_t *pabd, void *buf, void *lbuf, uint64_t lsize,
|
|||
(void) buf;
|
||||
uint64_t orig_lsize = lsize;
|
||||
boolean_t tryzle = ((getenv("ZDB_NO_ZLE") == NULL));
|
||||
boolean_t found = B_FALSE;
|
||||
/*
|
||||
* We don't know how the data was compressed, so just try
|
||||
* every decompress function at every inflated blocksize.
|
||||
|
|
@ -8823,20 +8845,19 @@ zdb_decompress_block(abd_t *pabd, void *buf, void *lbuf, uint64_t lsize,
|
|||
for (cfuncp = cfuncs; *cfuncp; cfuncp++) {
|
||||
if (try_decompress_block(pabd, lsize, psize, flags,
|
||||
*cfuncp, lbuf, lbuf2)) {
|
||||
found = B_TRUE;
|
||||
tryzle = B_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*cfuncp != 0)
|
||||
break;
|
||||
}
|
||||
if (!found && tryzle) {
|
||||
if (tryzle) {
|
||||
for (lsize = orig_lsize; lsize <= maxlsize;
|
||||
lsize += SPA_MINBLOCKSIZE) {
|
||||
if (try_decompress_block(pabd, lsize, psize, flags,
|
||||
ZIO_COMPRESS_ZLE, lbuf, lbuf2)) {
|
||||
*cfuncp = ZIO_COMPRESS_ZLE;
|
||||
found = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -9073,7 +9094,7 @@ zdb_read_block(char *thing, spa_t *spa)
|
|||
zdb_dump_indirect((blkptr_t *)buf,
|
||||
orig_lsize / sizeof (blkptr_t), flags);
|
||||
else if (flags & ZDB_FLAG_GBH)
|
||||
zdb_dump_gbh(buf, flags);
|
||||
zdb_dump_gbh(buf, lsize, flags);
|
||||
else
|
||||
zdb_dump_block(thing, buf, lsize, flags);
|
||||
|
||||
|
|
@ -9120,7 +9141,7 @@ zdb_read_block(char *thing, spa_t *spa)
|
|||
ck_zio->io_offset =
|
||||
DVA_GET_OFFSET(&bp->blk_dva[0]);
|
||||
ck_zio->io_bp = bp;
|
||||
zio_checksum_compute(ck_zio, ck, pabd, lsize);
|
||||
zio_checksum_compute(ck_zio, ck, pabd, psize);
|
||||
printf(
|
||||
"%12s\t"
|
||||
"cksum=%016llx:%016llx:%016llx:%016llx\n",
|
||||
|
|
@ -9377,9 +9398,11 @@ main(int argc, char **argv)
|
|||
while (*optarg != '\0') { *optarg++ = '*'; }
|
||||
break;
|
||||
case 'o':
|
||||
error = set_global_var(optarg);
|
||||
dump_opt[c]++;
|
||||
dump_all = 0;
|
||||
error = handle_tunable_option(optarg, B_FALSE);
|
||||
if (error != 0)
|
||||
usage();
|
||||
zdb_exit(1);
|
||||
break;
|
||||
case 'p':
|
||||
if (searchdirs == NULL) {
|
||||
|
|
@ -9545,6 +9568,12 @@ main(int argc, char **argv)
|
|||
error = 0;
|
||||
goto fini;
|
||||
}
|
||||
if (dump_opt['o'])
|
||||
/*
|
||||
* Avoid blasting tunable options off the top of the
|
||||
* screen.
|
||||
*/
|
||||
zdb_exit(1);
|
||||
usage();
|
||||
}
|
||||
|
||||
|
|
@ -9697,7 +9726,7 @@ main(int argc, char **argv)
|
|||
char *checkpoint_target = NULL;
|
||||
if (dump_opt['k']) {
|
||||
checkpoint_pool = import_checkpointed_state(target, cfg,
|
||||
&checkpoint_target);
|
||||
target_is_spa, &checkpoint_target);
|
||||
|
||||
if (checkpoint_target != NULL)
|
||||
target = checkpoint_target;
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, const void *arg)
|
|||
|
||||
if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
|
||||
(void) printf("%shas blkptr, %s\n", tab_prefix,
|
||||
!BP_IS_HOLE(bp) && BP_GET_LOGICAL_BIRTH(bp) >=
|
||||
!BP_IS_HOLE(bp) && BP_GET_BIRTH(bp) >=
|
||||
spa_min_claim_txg(zilog->zl_spa) ?
|
||||
"will claim" : "won't claim");
|
||||
print_log_bp(bp, tab_prefix);
|
||||
|
|
@ -189,7 +189,7 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, const void *arg)
|
|||
(void) printf("%s<hole>\n", tab_prefix);
|
||||
return;
|
||||
}
|
||||
if (BP_GET_LOGICAL_BIRTH(bp) < zilog->zl_header->zh_claim_txg) {
|
||||
if (BP_GET_BIRTH(bp) < zilog->zl_header->zh_claim_txg) {
|
||||
(void) printf("%s<block already committed>\n",
|
||||
tab_prefix);
|
||||
return;
|
||||
|
|
@ -240,7 +240,7 @@ zil_prt_rec_write_enc(zilog_t *zilog, int txtype, const void *arg)
|
|||
|
||||
if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
|
||||
(void) printf("%shas blkptr, %s\n", tab_prefix,
|
||||
!BP_IS_HOLE(bp) && BP_GET_LOGICAL_BIRTH(bp) >=
|
||||
!BP_IS_HOLE(bp) && BP_GET_BIRTH(bp) >=
|
||||
spa_min_claim_txg(zilog->zl_spa) ?
|
||||
"will claim" : "won't claim");
|
||||
print_log_bp(bp, tab_prefix);
|
||||
|
|
@ -476,7 +476,7 @@ print_log_block(zilog_t *zilog, const blkptr_t *bp, void *arg,
|
|||
|
||||
if (claim_txg != 0)
|
||||
claim = "already claimed";
|
||||
else if (BP_GET_LOGICAL_BIRTH(bp) >= spa_min_claim_txg(zilog->zl_spa))
|
||||
else if (BP_GET_BIRTH(bp) >= spa_min_claim_txg(zilog->zl_spa))
|
||||
claim = "will claim";
|
||||
else
|
||||
claim = "won't claim";
|
||||
|
|
|
|||
|
|
@ -134,11 +134,13 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
|||
* of blkid cache and L2ARC VDEV does not contain pool guid in its
|
||||
* blkid, so this is a special case for L2ARC VDEV.
|
||||
*/
|
||||
else if (gsp->gs_vdev_guid != 0 && gsp->gs_devid == NULL &&
|
||||
else if (gsp->gs_vdev_guid != 0 &&
|
||||
nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID, &vdev_guid) == 0 &&
|
||||
gsp->gs_vdev_guid == vdev_guid) {
|
||||
(void) nvlist_lookup_string(nvl, ZPOOL_CONFIG_DEVID,
|
||||
&gsp->gs_devid);
|
||||
if (gsp->gs_devid == NULL) {
|
||||
(void) nvlist_lookup_string(nvl, ZPOOL_CONFIG_DEVID,
|
||||
&gsp->gs_devid);
|
||||
}
|
||||
(void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_EXPANSION_TIME,
|
||||
&gsp->gs_vdev_expandtime);
|
||||
return (B_TRUE);
|
||||
|
|
@ -156,22 +158,28 @@ zfs_agent_iter_pool(zpool_handle_t *zhp, void *arg)
|
|||
/*
|
||||
* For each vdev in this pool, look for a match by devid
|
||||
*/
|
||||
if ((config = zpool_get_config(zhp, NULL)) != NULL) {
|
||||
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
|
||||
&nvl) == 0) {
|
||||
(void) zfs_agent_iter_vdev(zhp, nvl, gsp);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* if a match was found then grab the pool guid
|
||||
*/
|
||||
if (gsp->gs_vdev_guid && gsp->gs_devid) {
|
||||
(void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
|
||||
&gsp->gs_pool_guid);
|
||||
}
|
||||
boolean_t found = B_FALSE;
|
||||
uint64_t pool_guid;
|
||||
|
||||
/* Get pool configuration and extract pool GUID */
|
||||
if ((config = zpool_get_config(zhp, NULL)) == NULL ||
|
||||
nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
|
||||
&pool_guid) != 0)
|
||||
goto out;
|
||||
|
||||
/* Skip this pool if we're looking for a specific pool */
|
||||
if (gsp->gs_pool_guid != 0 && pool_guid != gsp->gs_pool_guid)
|
||||
goto out;
|
||||
|
||||
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvl) == 0)
|
||||
found = zfs_agent_iter_vdev(zhp, nvl, gsp);
|
||||
|
||||
if (found && gsp->gs_pool_guid == 0)
|
||||
gsp->gs_pool_guid = pool_guid;
|
||||
|
||||
out:
|
||||
zpool_close(zhp);
|
||||
return (gsp->gs_devid != NULL && gsp->gs_vdev_guid != 0);
|
||||
return (found);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -233,20 +241,17 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl)
|
|||
* For multipath, spare and l2arc devices ZFS_EV_VDEV_GUID or
|
||||
* ZFS_EV_POOL_GUID may be missing so find them.
|
||||
*/
|
||||
if (devid == NULL || pool_guid == 0 || vdev_guid == 0) {
|
||||
if (devid == NULL)
|
||||
search.gs_vdev_guid = vdev_guid;
|
||||
else
|
||||
search.gs_devid = devid;
|
||||
zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search);
|
||||
if (devid == NULL)
|
||||
devid = search.gs_devid;
|
||||
if (pool_guid == 0)
|
||||
pool_guid = search.gs_pool_guid;
|
||||
if (vdev_guid == 0)
|
||||
vdev_guid = search.gs_vdev_guid;
|
||||
devtype = search.gs_vdev_type;
|
||||
}
|
||||
search.gs_devid = devid;
|
||||
search.gs_vdev_guid = vdev_guid;
|
||||
search.gs_pool_guid = pool_guid;
|
||||
zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search);
|
||||
if (devid == NULL)
|
||||
devid = search.gs_devid;
|
||||
if (pool_guid == 0)
|
||||
pool_guid = search.gs_pool_guid;
|
||||
if (vdev_guid == 0)
|
||||
vdev_guid = search.gs_vdev_guid;
|
||||
devtype = search.gs_vdev_type;
|
||||
|
||||
/*
|
||||
* We want to avoid reporting "remove" events coming from
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ zed_event_fini(struct zed_conf *zcp)
|
|||
static void
|
||||
_bump_event_queue_length(void)
|
||||
{
|
||||
int zzlm = -1, wr;
|
||||
int zzlm, wr;
|
||||
char qlen_buf[12] = {0}; /* parameter is int => max "-2147483647\n" */
|
||||
long int qlen, orig_qlen;
|
||||
|
||||
|
|
|
|||
|
|
@ -440,7 +440,7 @@ get_usage(zfs_help_t idx)
|
|||
return (gettext("\tredact <snapshot> <bookmark> "
|
||||
"<redaction_snapshot> ...\n"));
|
||||
case HELP_REWRITE:
|
||||
return (gettext("\trewrite [-rvx] [-o <offset>] [-l <length>] "
|
||||
return (gettext("\trewrite [-Prvx] [-o <offset>] [-l <length>] "
|
||||
"<directory|file ...>\n"));
|
||||
case HELP_JAIL:
|
||||
return (gettext("\tjail <jailid|jailname> <filesystem>\n"));
|
||||
|
|
@ -1974,9 +1974,8 @@ fill_dataset_info(nvlist_t *list, zfs_handle_t *zhp, boolean_t as_int)
|
|||
}
|
||||
|
||||
if (type == ZFS_TYPE_SNAPSHOT) {
|
||||
char *ds, *snap;
|
||||
ds = snap = strdup(zfs_get_name(zhp));
|
||||
ds = strsep(&snap, "@");
|
||||
char *snap = strdup(zfs_get_name(zhp));
|
||||
char *ds = strsep(&snap, "@");
|
||||
fnvlist_add_string(list, "dataset", ds);
|
||||
fnvlist_add_string(list, "snapshot_name", snap);
|
||||
free(ds);
|
||||
|
|
@ -2019,8 +2018,7 @@ get_callback(zfs_handle_t *zhp, void *data)
|
|||
nvlist_t *user_props = zfs_get_user_props(zhp);
|
||||
zprop_list_t *pl = cbp->cb_proplist;
|
||||
nvlist_t *propval;
|
||||
nvlist_t *item, *d, *props;
|
||||
item = d = props = NULL;
|
||||
nvlist_t *item, *d = NULL, *props = NULL;
|
||||
const char *strval;
|
||||
const char *sourceval;
|
||||
boolean_t received = is_recvd_column(cbp);
|
||||
|
|
@ -5879,7 +5877,7 @@ parse_fs_perm_set(fs_perm_set_t *fspset, nvlist_t *nvl)
|
|||
static inline const char *
|
||||
deleg_perm_comment(zfs_deleg_note_t note)
|
||||
{
|
||||
const char *str = "";
|
||||
const char *str;
|
||||
|
||||
/* subcommands */
|
||||
switch (note) {
|
||||
|
|
@ -7729,6 +7727,7 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual)
|
|||
struct extmnttab 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.
|
||||
|
|
@ -7770,6 +7769,24 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual)
|
|||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the filesystem is mounted, check that the mountpoint matches
|
||||
* the one in the mnttab entry w.r.t. provided path. If it doesn't,
|
||||
* then we should not proceed further.
|
||||
*/
|
||||
entry_mntpnt = strdup(entry.mnt_mountp);
|
||||
if (zfs_is_mounted(zhp, &zfs_mntpnt)) {
|
||||
if (strcmp(zfs_mntpnt, entry_mntpnt) != 0) {
|
||||
(void) fprintf(stderr, gettext("cannot %s '%s': "
|
||||
"not an original mountpoint\n"), cmdname, path);
|
||||
free(zfs_mntpnt);
|
||||
free(entry_mntpnt);
|
||||
goto out;
|
||||
}
|
||||
free(zfs_mntpnt);
|
||||
}
|
||||
free(entry_mntpnt);
|
||||
|
||||
if (op == OP_SHARE) {
|
||||
char nfs_mnt_prop[ZFS_MAXPROPLEN];
|
||||
char smbshare_prop[ZFS_MAXPROPLEN];
|
||||
|
|
@ -9160,8 +9177,11 @@ zfs_do_rewrite(int argc, char **argv)
|
|||
zfs_rewrite_args_t args;
|
||||
memset(&args, 0, sizeof (args));
|
||||
|
||||
while ((c = getopt(argc, argv, "l:o:rvx")) != -1) {
|
||||
while ((c = getopt(argc, argv, "Pl:o:rvx")) != -1) {
|
||||
switch (c) {
|
||||
case 'P':
|
||||
args.flags |= ZFS_REWRITE_PHYSICAL;
|
||||
break;
|
||||
case 'l':
|
||||
args.len = strtoll(optarg, NULL, 0);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -379,8 +379,8 @@ process_unique_cmd_columns(vdev_cmd_data_list_t *vcdl)
|
|||
static int
|
||||
vdev_process_cmd_output(vdev_cmd_data_t *data, char *line)
|
||||
{
|
||||
char *col = NULL;
|
||||
char *val = line;
|
||||
char *col;
|
||||
char *val;
|
||||
char *equals;
|
||||
char **tmp;
|
||||
|
||||
|
|
@ -397,6 +397,7 @@ vdev_process_cmd_output(vdev_cmd_data_t *data, char *line)
|
|||
col = line;
|
||||
val = equals + 1;
|
||||
} else {
|
||||
col = NULL;
|
||||
val = line;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
* Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>
|
||||
* Copyright (c) 2021, Colm Buckley <colm@tuatha.org>
|
||||
* Copyright (c) 2021, 2023, Klara Inc.
|
||||
* Copyright [2021] Hewlett Packard Enterprise Development LP
|
||||
* Copyright (c) 2021, 2025 Hewlett Packard Enterprise Development LP.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
|
@ -510,16 +510,16 @@ get_usage(zpool_help_t idx)
|
|||
case HELP_REOPEN:
|
||||
return (gettext("\treopen [-n] <pool>\n"));
|
||||
case HELP_INITIALIZE:
|
||||
return (gettext("\tinitialize [-c | -s | -u] [-w] <pool> "
|
||||
"[<device> ...]\n"));
|
||||
return (gettext("\tinitialize [-c | -s | -u] [-w] <-a | <pool> "
|
||||
"[<device> ...]>\n"));
|
||||
case HELP_SCRUB:
|
||||
return (gettext("\tscrub [-e | -s | -p | -C] [-w] "
|
||||
"<pool> ...\n"));
|
||||
return (gettext("\tscrub [-e | -s | -p | -C | -E | -S] [-w] "
|
||||
"<-a | <pool> [<pool> ...]>\n"));
|
||||
case HELP_RESILVER:
|
||||
return (gettext("\tresilver <pool> ...\n"));
|
||||
case HELP_TRIM:
|
||||
return (gettext("\ttrim [-dw] [-r <rate>] [-c | -s] <pool> "
|
||||
"[<device> ...]\n"));
|
||||
return (gettext("\ttrim [-dw] [-r <rate>] [-c | -s] "
|
||||
"<-a | <pool> [<device> ...]>\n"));
|
||||
case HELP_STATUS:
|
||||
return (gettext("\tstatus [-DdegiLPpstvx] "
|
||||
"[-c script1[,script2,...]] ...\n"
|
||||
|
|
@ -560,33 +560,6 @@ get_usage(zpool_help_t idx)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
zpool_collect_leaves(zpool_handle_t *zhp, nvlist_t *nvroot, nvlist_t *res)
|
||||
{
|
||||
uint_t children = 0;
|
||||
nvlist_t **child;
|
||||
uint_t i;
|
||||
|
||||
(void) nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
|
||||
&child, &children);
|
||||
|
||||
if (children == 0) {
|
||||
char *path = zpool_vdev_name(g_zfs, zhp, nvroot,
|
||||
VDEV_NAME_PATH);
|
||||
|
||||
if (strcmp(path, VDEV_TYPE_INDIRECT) != 0 &&
|
||||
strcmp(path, VDEV_TYPE_HOLE) != 0)
|
||||
fnvlist_add_boolean(res, path);
|
||||
|
||||
free(path);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < children; i++) {
|
||||
zpool_collect_leaves(zhp, child[i], res);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback routine that will print out a pool property value.
|
||||
*/
|
||||
|
|
@ -794,22 +767,26 @@ zpool_do_initialize(int argc, char **argv)
|
|||
int c;
|
||||
char *poolname;
|
||||
zpool_handle_t *zhp;
|
||||
nvlist_t *vdevs;
|
||||
int err = 0;
|
||||
boolean_t wait = B_FALSE;
|
||||
boolean_t initialize_all = B_FALSE;
|
||||
|
||||
struct option long_options[] = {
|
||||
{"cancel", no_argument, NULL, 'c'},
|
||||
{"suspend", no_argument, NULL, 's'},
|
||||
{"uninit", no_argument, NULL, 'u'},
|
||||
{"wait", no_argument, NULL, 'w'},
|
||||
{"all", no_argument, NULL, 'a'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
pool_initialize_func_t cmd_type = POOL_INITIALIZE_START;
|
||||
while ((c = getopt_long(argc, argv, "csuw", long_options,
|
||||
while ((c = getopt_long(argc, argv, "acsuw", long_options,
|
||||
NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
initialize_all = B_TRUE;
|
||||
break;
|
||||
case 'c':
|
||||
if (cmd_type != POOL_INITIALIZE_START &&
|
||||
cmd_type != POOL_INITIALIZE_CANCEL) {
|
||||
|
|
@ -856,7 +833,18 @@ zpool_do_initialize(int argc, char **argv)
|
|||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1) {
|
||||
initialize_cbdata_t cbdata = {
|
||||
.wait = wait,
|
||||
.cmd_type = cmd_type
|
||||
};
|
||||
|
||||
if (initialize_all && argc > 0) {
|
||||
(void) fprintf(stderr, gettext("-a cannot be combined with "
|
||||
"individual pools or vdevs\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
if (argc < 1 && !initialize_all) {
|
||||
(void) fprintf(stderr, gettext("missing pool name argument\n"));
|
||||
usage(B_FALSE);
|
||||
return (-1);
|
||||
|
|
@ -868,30 +856,35 @@ zpool_do_initialize(int argc, char **argv)
|
|||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
poolname = argv[0];
|
||||
zhp = zpool_open(g_zfs, poolname);
|
||||
if (zhp == NULL)
|
||||
return (-1);
|
||||
|
||||
vdevs = fnvlist_alloc();
|
||||
if (argc == 1) {
|
||||
/* no individual leaf vdevs specified, so add them all */
|
||||
nvlist_t *config = zpool_get_config(zhp, NULL);
|
||||
nvlist_t *nvroot = fnvlist_lookup_nvlist(config,
|
||||
ZPOOL_CONFIG_VDEV_TREE);
|
||||
zpool_collect_leaves(zhp, nvroot, vdevs);
|
||||
if (argc == 0 && initialize_all) {
|
||||
/* Initilize each pool recursively */
|
||||
err = for_each_pool(argc, argv, B_TRUE, NULL, ZFS_TYPE_POOL,
|
||||
B_FALSE, zpool_initialize_one, &cbdata);
|
||||
return (err);
|
||||
} else if (argc == 1) {
|
||||
/* no individual leaf vdevs specified, initialize the pool */
|
||||
poolname = argv[0];
|
||||
zhp = zpool_open(g_zfs, poolname);
|
||||
if (zhp == NULL)
|
||||
return (-1);
|
||||
err = zpool_initialize_one(zhp, &cbdata);
|
||||
} else {
|
||||
/* individual leaf vdevs specified, initialize them */
|
||||
poolname = argv[0];
|
||||
zhp = zpool_open(g_zfs, poolname);
|
||||
if (zhp == NULL)
|
||||
return (-1);
|
||||
nvlist_t *vdevs = fnvlist_alloc();
|
||||
for (int i = 1; i < argc; i++) {
|
||||
fnvlist_add_boolean(vdevs, argv[i]);
|
||||
}
|
||||
if (wait)
|
||||
err = zpool_initialize_wait(zhp, cmd_type, vdevs);
|
||||
else
|
||||
err = zpool_initialize(zhp, cmd_type, vdevs);
|
||||
fnvlist_free(vdevs);
|
||||
}
|
||||
|
||||
if (wait)
|
||||
err = zpool_initialize_wait(zhp, cmd_type, vdevs);
|
||||
else
|
||||
err = zpool_initialize(zhp, cmd_type, vdevs);
|
||||
|
||||
fnvlist_free(vdevs);
|
||||
zpool_close(zhp);
|
||||
|
||||
return (err);
|
||||
|
|
@ -1788,7 +1781,7 @@ zpool_do_labelclear(int argc, char **argv)
|
|||
{
|
||||
char vdev[MAXPATHLEN];
|
||||
char *name = NULL;
|
||||
int c, fd = -1, ret = 0;
|
||||
int c, fd, ret = 0;
|
||||
nvlist_t *config;
|
||||
pool_state_t state;
|
||||
boolean_t inuse = B_FALSE;
|
||||
|
|
@ -6157,7 +6150,6 @@ static void
|
|||
get_interval_count_filter_guids(int *argc, char **argv, float *interval,
|
||||
unsigned long *count, iostat_cbdata_t *cb)
|
||||
{
|
||||
char **tmpargv = argv;
|
||||
int argc_for_interval = 0;
|
||||
|
||||
/* Is the last arg an interval value? Or a guid? */
|
||||
|
|
@ -6181,7 +6173,7 @@ get_interval_count_filter_guids(int *argc, char **argv, float *interval,
|
|||
}
|
||||
|
||||
/* Point to our list of possible intervals */
|
||||
tmpargv = &argv[*argc - argc_for_interval];
|
||||
char **tmpargv = &argv[*argc - argc_for_interval];
|
||||
|
||||
*argc = *argc - argc_for_interval;
|
||||
get_interval_count(&argc_for_interval, tmpargv,
|
||||
|
|
@ -6377,7 +6369,6 @@ zpool_do_iostat(int argc, char **argv)
|
|||
int npools;
|
||||
float interval = 0;
|
||||
unsigned long count = 0;
|
||||
int winheight = 24;
|
||||
zpool_list_t *list;
|
||||
boolean_t verbose = B_FALSE;
|
||||
boolean_t latency = B_FALSE, l_histo = B_FALSE, rq_histo = B_FALSE;
|
||||
|
|
@ -6673,7 +6664,7 @@ zpool_do_iostat(int argc, char **argv)
|
|||
* even when terminal window has its height
|
||||
* changed.
|
||||
*/
|
||||
winheight = terminal_height();
|
||||
int winheight = terminal_height();
|
||||
/*
|
||||
* Are we connected to TTY? If not, headers_once
|
||||
* should be true, to avoid breaking scripts.
|
||||
|
|
@ -8368,6 +8359,8 @@ zpool_do_reopen(int argc, char **argv)
|
|||
typedef struct scrub_cbdata {
|
||||
int cb_type;
|
||||
pool_scrub_cmd_t cb_scrub_cmd;
|
||||
time_t cb_date_start;
|
||||
time_t cb_date_end;
|
||||
} scrub_cbdata_t;
|
||||
|
||||
static boolean_t
|
||||
|
|
@ -8411,8 +8404,8 @@ scrub_callback(zpool_handle_t *zhp, void *data)
|
|||
return (1);
|
||||
}
|
||||
|
||||
err = zpool_scan(zhp, cb->cb_type, cb->cb_scrub_cmd);
|
||||
|
||||
err = zpool_scan_range(zhp, cb->cb_type, cb->cb_scrub_cmd,
|
||||
cb->cb_date_start, cb->cb_date_end);
|
||||
if (err == 0 && zpool_has_checkpoint(zhp) &&
|
||||
cb->cb_type == POOL_SCAN_SCRUB) {
|
||||
(void) printf(gettext("warning: will not scrub state that "
|
||||
|
|
@ -8430,10 +8423,34 @@ wait_callback(zpool_handle_t *zhp, void *data)
|
|||
return (zpool_wait(zhp, *act));
|
||||
}
|
||||
|
||||
static time_t
|
||||
date_string_to_sec(const char *timestr, boolean_t rounding)
|
||||
{
|
||||
struct tm tm = {0};
|
||||
int adjustment = rounding ? 1 : 0;
|
||||
|
||||
/* Allow mktime to determine timezone. */
|
||||
tm.tm_isdst = -1;
|
||||
|
||||
if (strptime(timestr, "%Y-%m-%d %H:%M", &tm) == NULL) {
|
||||
if (strptime(timestr, "%Y-%m-%d", &tm) == NULL) {
|
||||
fprintf(stderr, gettext("Failed to parse the date.\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
adjustment *= 24 * 60 * 60;
|
||||
} else {
|
||||
adjustment *= 60;
|
||||
}
|
||||
|
||||
return (mktime(&tm) + adjustment);
|
||||
}
|
||||
|
||||
/*
|
||||
* zpool scrub [-e | -s | -p | -C] [-w] <pool> ...
|
||||
* zpool scrub [-e | -s | -p | -C | -E | -S] [-w] <pool> ...
|
||||
*
|
||||
* -e Only scrub blocks in the error log.
|
||||
* -E End date of scrub.
|
||||
* -S Start date of scrub.
|
||||
* -s Stop. Stops any in-progress scrub.
|
||||
* -p Pause. Pause in-progress scrub.
|
||||
* -w Wait. Blocks until scrub has completed.
|
||||
|
|
@ -8449,21 +8466,36 @@ zpool_do_scrub(int argc, char **argv)
|
|||
|
||||
cb.cb_type = POOL_SCAN_SCRUB;
|
||||
cb.cb_scrub_cmd = POOL_SCRUB_NORMAL;
|
||||
cb.cb_date_start = cb.cb_date_end = 0;
|
||||
|
||||
boolean_t is_error_scrub = B_FALSE;
|
||||
boolean_t is_pause = B_FALSE;
|
||||
boolean_t is_stop = B_FALSE;
|
||||
boolean_t is_txg_continue = B_FALSE;
|
||||
boolean_t scrub_all = B_FALSE;
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, "spweC")) != -1) {
|
||||
while ((c = getopt(argc, argv, "aspweCE:S:")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
scrub_all = B_TRUE;
|
||||
break;
|
||||
case 'e':
|
||||
is_error_scrub = B_TRUE;
|
||||
break;
|
||||
case 'E':
|
||||
/*
|
||||
* Round the date. It's better to scrub more data than
|
||||
* less. This also makes the date inclusive.
|
||||
*/
|
||||
cb.cb_date_end = date_string_to_sec(optarg, B_TRUE);
|
||||
break;
|
||||
case 's':
|
||||
is_stop = B_TRUE;
|
||||
break;
|
||||
case 'S':
|
||||
cb.cb_date_start = date_string_to_sec(optarg, B_FALSE);
|
||||
break;
|
||||
case 'p':
|
||||
is_pause = B_TRUE;
|
||||
break;
|
||||
|
|
@ -8511,6 +8543,19 @@ zpool_do_scrub(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if ((cb.cb_date_start != 0 || cb.cb_date_end != 0) &&
|
||||
cb.cb_scrub_cmd != POOL_SCRUB_NORMAL) {
|
||||
(void) fprintf(stderr, gettext("invalid option combination: "
|
||||
"start/end date is available only with normal scrub\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
if (cb.cb_date_start != 0 && cb.cb_date_end != 0 &&
|
||||
cb.cb_date_start > cb.cb_date_end) {
|
||||
(void) fprintf(stderr, gettext("invalid arguments: "
|
||||
"end date has to be later than start date\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
if (wait && (cb.cb_type == POOL_SCAN_NONE ||
|
||||
cb.cb_scrub_cmd == POOL_SCRUB_PAUSE)) {
|
||||
(void) fprintf(stderr, gettext("invalid option combination: "
|
||||
|
|
@ -8521,7 +8566,7 @@ zpool_do_scrub(int argc, char **argv)
|
|||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1) {
|
||||
if (argc < 1 && !scrub_all) {
|
||||
(void) fprintf(stderr, gettext("missing pool name argument\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
|
@ -8551,6 +8596,7 @@ zpool_do_resilver(int argc, char **argv)
|
|||
|
||||
cb.cb_type = POOL_SCAN_RESILVER;
|
||||
cb.cb_scrub_cmd = POOL_SCRUB_NORMAL;
|
||||
cb.cb_date_start = cb.cb_date_end = 0;
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, "")) != -1) {
|
||||
|
|
@ -8593,6 +8639,7 @@ zpool_do_trim(int argc, char **argv)
|
|||
{"rate", required_argument, NULL, 'r'},
|
||||
{"suspend", no_argument, NULL, 's'},
|
||||
{"wait", no_argument, NULL, 'w'},
|
||||
{"all", no_argument, NULL, 'a'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
|
@ -8600,11 +8647,16 @@ zpool_do_trim(int argc, char **argv)
|
|||
uint64_t rate = 0;
|
||||
boolean_t secure = B_FALSE;
|
||||
boolean_t wait = B_FALSE;
|
||||
boolean_t trimall = B_FALSE;
|
||||
int error;
|
||||
|
||||
int c;
|
||||
while ((c = getopt_long(argc, argv, "cdr:sw", long_options, NULL))
|
||||
while ((c = getopt_long(argc, argv, "acdr:sw", long_options, NULL))
|
||||
!= -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
trimall = B_TRUE;
|
||||
break;
|
||||
case 'c':
|
||||
if (cmd_type != POOL_TRIM_START &&
|
||||
cmd_type != POOL_TRIM_CANCEL) {
|
||||
|
|
@ -8663,7 +8715,18 @@ zpool_do_trim(int argc, char **argv)
|
|||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1) {
|
||||
trimflags_t trim_flags = {
|
||||
.secure = secure,
|
||||
.rate = rate,
|
||||
.wait = wait,
|
||||
};
|
||||
|
||||
trim_cbdata_t cbdata = {
|
||||
.trim_flags = trim_flags,
|
||||
.cmd_type = cmd_type
|
||||
};
|
||||
|
||||
if (argc < 1 && !trimall) {
|
||||
(void) fprintf(stderr, gettext("missing pool name argument\n"));
|
||||
usage(B_FALSE);
|
||||
return (-1);
|
||||
|
|
@ -8671,41 +8734,46 @@ zpool_do_trim(int argc, char **argv)
|
|||
|
||||
if (wait && (cmd_type != POOL_TRIM_START)) {
|
||||
(void) fprintf(stderr, gettext("-w cannot be used with -c or "
|
||||
"-s\n"));
|
||||
"-s options\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
char *poolname = argv[0];
|
||||
zpool_handle_t *zhp = zpool_open(g_zfs, poolname);
|
||||
if (zhp == NULL)
|
||||
return (-1);
|
||||
if (trimall && argc > 0) {
|
||||
(void) fprintf(stderr, gettext("-a cannot be combined with "
|
||||
"individual zpools or vdevs\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
trimflags_t trim_flags = {
|
||||
.secure = secure,
|
||||
.rate = rate,
|
||||
.wait = wait,
|
||||
};
|
||||
|
||||
nvlist_t *vdevs = fnvlist_alloc();
|
||||
if (argc == 1) {
|
||||
if (argc == 0 && trimall) {
|
||||
cbdata.trim_flags.fullpool = B_TRUE;
|
||||
/* Trim each pool recursively */
|
||||
error = for_each_pool(argc, argv, B_TRUE, NULL, ZFS_TYPE_POOL,
|
||||
B_FALSE, zpool_trim_one, &cbdata);
|
||||
} else if (argc == 1) {
|
||||
char *poolname = argv[0];
|
||||
zpool_handle_t *zhp = zpool_open(g_zfs, poolname);
|
||||
if (zhp == NULL)
|
||||
return (-1);
|
||||
/* no individual leaf vdevs specified, so add them all */
|
||||
nvlist_t *config = zpool_get_config(zhp, NULL);
|
||||
nvlist_t *nvroot = fnvlist_lookup_nvlist(config,
|
||||
ZPOOL_CONFIG_VDEV_TREE);
|
||||
zpool_collect_leaves(zhp, nvroot, vdevs);
|
||||
trim_flags.fullpool = B_TRUE;
|
||||
error = zpool_trim_one(zhp, &cbdata);
|
||||
zpool_close(zhp);
|
||||
} else {
|
||||
trim_flags.fullpool = B_FALSE;
|
||||
char *poolname = argv[0];
|
||||
zpool_handle_t *zhp = zpool_open(g_zfs, poolname);
|
||||
if (zhp == NULL)
|
||||
return (-1);
|
||||
/* leaf vdevs specified, trim only those */
|
||||
cbdata.trim_flags.fullpool = B_FALSE;
|
||||
nvlist_t *vdevs = fnvlist_alloc();
|
||||
for (int i = 1; i < argc; i++) {
|
||||
fnvlist_add_boolean(vdevs, argv[i]);
|
||||
}
|
||||
error = zpool_trim(zhp, cbdata.cmd_type, vdevs,
|
||||
&cbdata.trim_flags);
|
||||
fnvlist_free(vdevs);
|
||||
zpool_close(zhp);
|
||||
}
|
||||
|
||||
int error = zpool_trim(zhp, cmd_type, vdevs, &trim_flags);
|
||||
|
||||
fnvlist_free(vdevs);
|
||||
zpool_close(zhp);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
@ -10706,7 +10774,6 @@ status_callback_json(zpool_handle_t *zhp, void *data)
|
|||
uint_t c;
|
||||
vdev_stat_t *vs;
|
||||
nvlist_t *item, *d, *load_info, *vds;
|
||||
item = d = NULL;
|
||||
|
||||
/* If dedup stats were requested, also fetch dedupcached. */
|
||||
if (cbp->cb_dedup_stats > 1)
|
||||
|
|
@ -11330,7 +11397,8 @@ upgrade_enable_all(zpool_handle_t *zhp, int *countp)
|
|||
const char *fname = spa_feature_table[i].fi_uname;
|
||||
const char *fguid = spa_feature_table[i].fi_guid;
|
||||
|
||||
if (!spa_feature_table[i].fi_zfs_mod_supported)
|
||||
if (!spa_feature_table[i].fi_zfs_mod_supported ||
|
||||
(spa_feature_table[i].fi_flags & ZFEATURE_FLAG_NO_UPGRADE))
|
||||
continue;
|
||||
|
||||
if (!nvlist_exists(enabled, fguid) && requested_features[i]) {
|
||||
|
|
@ -11485,7 +11553,11 @@ upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
|
|||
"Note that the pool "
|
||||
"'compatibility' feature can be "
|
||||
"used to inhibit\nfeature "
|
||||
"upgrades.\n\n"));
|
||||
"upgrades.\n\n"
|
||||
"Features marked with (*) are not "
|
||||
"applied automatically on upgrade, "
|
||||
"and\nmust be applied explicitly "
|
||||
"with zpool-set(7).\n\n"));
|
||||
(void) printf(gettext("POOL "
|
||||
"FEATURE\n"));
|
||||
(void) printf(gettext("------"
|
||||
|
|
@ -11499,7 +11571,9 @@ upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
|
|||
poolfirst = B_FALSE;
|
||||
}
|
||||
|
||||
(void) printf(gettext(" %s\n"), fname);
|
||||
(void) printf(gettext(" %s%s\n"), fname,
|
||||
spa_feature_table[i].fi_flags &
|
||||
ZFEATURE_FLAG_NO_UPGRADE ? "(*)" : "");
|
||||
}
|
||||
/*
|
||||
* If they did "zpool upgrade -a", then we could
|
||||
|
|
|
|||
|
|
@ -574,7 +574,6 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
|
|||
nvlist_t *cnv = child[c];
|
||||
const char *path;
|
||||
struct stat64 statbuf;
|
||||
int64_t size = -1LL;
|
||||
const char *childtype;
|
||||
int fd, err;
|
||||
|
||||
|
|
@ -656,7 +655,7 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
|
|||
statbuf.st_size == MAXOFFSET_T)
|
||||
continue;
|
||||
|
||||
size = statbuf.st_size;
|
||||
int64_t size = statbuf.st_size;
|
||||
|
||||
/*
|
||||
* Also make sure that devices and
|
||||
|
|
@ -876,6 +875,18 @@ check_replication(nvlist_t *config, nvlist_t *newroot)
|
|||
(u_longlong_t)mirror->zprl_children);
|
||||
ret = -1;
|
||||
}
|
||||
} else if (is_raidz_draid(current, new)) {
|
||||
if (current->zprl_parity != new->zprl_parity) {
|
||||
vdev_error(gettext(
|
||||
"mismatched replication level: pool and "
|
||||
"new vdev with different redundancy, %s "
|
||||
"and %s vdevs, %llu vs. %llu\n"),
|
||||
current->zprl_type,
|
||||
new->zprl_type,
|
||||
(u_longlong_t)current->zprl_parity,
|
||||
(u_longlong_t)new->zprl_parity);
|
||||
ret = -1;
|
||||
}
|
||||
} else if (strcmp(current->zprl_type, new->zprl_type) != 0) {
|
||||
vdev_error(gettext(
|
||||
"mismatched replication level: pool uses %s "
|
||||
|
|
@ -1353,7 +1364,7 @@ is_grouping(const char *type, int *mindev, int *maxdev)
|
|||
static int
|
||||
draid_config_by_type(nvlist_t *nv, const char *type, uint64_t children)
|
||||
{
|
||||
uint64_t nparity = 1;
|
||||
uint64_t nparity;
|
||||
uint64_t nspares = 0;
|
||||
uint64_t ndata = UINT64_MAX;
|
||||
uint64_t ngroups = 1;
|
||||
|
|
@ -1581,13 +1592,12 @@ construct_spec(nvlist_t *props, int argc, char **argv)
|
|||
is_dedup = is_spare = B_FALSE;
|
||||
}
|
||||
|
||||
if (is_log || is_special || is_dedup) {
|
||||
if (is_log) {
|
||||
if (strcmp(type, VDEV_TYPE_MIRROR) != 0) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("invalid vdev "
|
||||
"specification: unsupported '%s' "
|
||||
"device: %s\n"), is_log ? "log" :
|
||||
"special", type);
|
||||
"specification: unsupported 'log' "
|
||||
"device: %s\n"), type);
|
||||
goto spec_out;
|
||||
}
|
||||
nlogs++;
|
||||
|
|
|
|||
|
|
@ -809,8 +809,8 @@ static ztest_option_t option_table[] = {
|
|||
{ 'X', "raidz-expansion", NULL,
|
||||
"Perform a dedicated raidz expansion test",
|
||||
NO_DEFAULT, NULL},
|
||||
{ 'o', "option", "\"OPTION=INTEGER\"",
|
||||
"Set global variable to an unsigned 32-bit integer value",
|
||||
{ 'o', "option", "\"NAME=VALUE\"",
|
||||
"Set the named tunable to the given value",
|
||||
NO_DEFAULT, NULL},
|
||||
{ 'G', "dump-debug-msg", NULL,
|
||||
"Dump zfs_dbgmsg buffer before exiting due to an error",
|
||||
|
|
@ -919,7 +919,7 @@ ztest_parse_name_value(const char *input, ztest_shared_opts_t *zo)
|
|||
{
|
||||
char name[32];
|
||||
char *value;
|
||||
int state = ZTEST_VDEV_CLASS_RND;
|
||||
int state;
|
||||
|
||||
(void) strlcpy(name, input, sizeof (name));
|
||||
|
||||
|
|
@ -3882,7 +3882,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
|
|||
* If newvd is too small, it should fail with EOVERFLOW.
|
||||
*
|
||||
* If newvd is a distributed spare and it's being attached to a
|
||||
* dRAID which is not its parent it should fail with EINVAL.
|
||||
* dRAID which is not its parent it should fail with ENOTSUP.
|
||||
*/
|
||||
if (pvd->vdev_ops != &vdev_mirror_ops &&
|
||||
pvd->vdev_ops != &vdev_root_ops && (!replacing ||
|
||||
|
|
@ -3901,7 +3901,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
|
|||
else if (ashift > oldvd->vdev_top->vdev_ashift)
|
||||
expected_error = EDOM;
|
||||
else if (newvd_is_dspare && pvd != vdev_draid_spare_get_parent(newvd))
|
||||
expected_error = EINVAL;
|
||||
expected_error = ENOTSUP;
|
||||
else
|
||||
expected_error = 0;
|
||||
|
||||
|
|
@ -7069,7 +7069,7 @@ ztest_set_global_vars(void)
|
|||
char *kv = ztest_opts.zo_gvars[i];
|
||||
VERIFY3U(strlen(kv), <=, ZO_GVARS_MAX_ARGLEN);
|
||||
VERIFY3U(strlen(kv), >, 0);
|
||||
int err = set_global_var(kv);
|
||||
int err = handle_tunable_option(kv, B_TRUE);
|
||||
if (ztest_opts.zo_verbose > 0) {
|
||||
(void) printf("setting global var %s ... %s\n", kv,
|
||||
err ? "failed" : "ok");
|
||||
|
|
@ -7813,6 +7813,9 @@ ztest_dataset_open(int d)
|
|||
|
||||
ztest_dataset_name(name, ztest_opts.zo_pool, d);
|
||||
|
||||
if (ztest_opts.zo_verbose >= 6)
|
||||
(void) printf("Opening %s\n", name);
|
||||
|
||||
(void) pthread_rwlock_rdlock(&ztest_name_lock);
|
||||
|
||||
error = ztest_dataset_create(name);
|
||||
|
|
@ -8308,41 +8311,44 @@ static void
|
|||
ztest_generic_run(ztest_shared_t *zs, spa_t *spa)
|
||||
{
|
||||
kthread_t **run_threads;
|
||||
int t;
|
||||
int i, ndatasets;
|
||||
|
||||
run_threads = umem_zalloc(ztest_opts.zo_threads * sizeof (kthread_t *),
|
||||
UMEM_NOFAIL);
|
||||
|
||||
/*
|
||||
* Actual number of datasets to be used.
|
||||
*/
|
||||
ndatasets = MIN(ztest_opts.zo_datasets, ztest_opts.zo_threads);
|
||||
|
||||
/*
|
||||
* Prepare the datasets first.
|
||||
*/
|
||||
for (i = 0; i < ndatasets; i++)
|
||||
VERIFY0(ztest_dataset_open(i));
|
||||
|
||||
/*
|
||||
* Kick off all the tests that run in parallel.
|
||||
*/
|
||||
for (t = 0; t < ztest_opts.zo_threads; t++) {
|
||||
if (t < ztest_opts.zo_datasets && ztest_dataset_open(t) != 0) {
|
||||
umem_free(run_threads, ztest_opts.zo_threads *
|
||||
sizeof (kthread_t *));
|
||||
return;
|
||||
}
|
||||
|
||||
run_threads[t] = thread_create(NULL, 0, ztest_thread,
|
||||
(void *)(uintptr_t)t, 0, NULL, TS_RUN | TS_JOINABLE,
|
||||
for (i = 0; i < ztest_opts.zo_threads; i++) {
|
||||
run_threads[i] = thread_create(NULL, 0, ztest_thread,
|
||||
(void *)(uintptr_t)i, 0, NULL, TS_RUN | TS_JOINABLE,
|
||||
defclsyspri);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for all of the tests to complete.
|
||||
*/
|
||||
for (t = 0; t < ztest_opts.zo_threads; t++)
|
||||
VERIFY0(thread_join(run_threads[t]));
|
||||
for (i = 0; i < ztest_opts.zo_threads; i++)
|
||||
VERIFY0(thread_join(run_threads[i]));
|
||||
|
||||
/*
|
||||
* Close all datasets. This must be done after all the threads
|
||||
* are joined so we can be sure none of the datasets are in-use
|
||||
* by any of the threads.
|
||||
*/
|
||||
for (t = 0; t < ztest_opts.zo_threads; t++) {
|
||||
if (t < ztest_opts.zo_datasets)
|
||||
ztest_dataset_close(t);
|
||||
}
|
||||
for (i = 0; i < ndatasets; i++)
|
||||
ztest_dataset_close(i);
|
||||
|
||||
txg_wait_synced(spa_get_dsl(spa), 0);
|
||||
|
||||
|
|
@ -8465,6 +8471,7 @@ ztest_run(ztest_shared_t *zs)
|
|||
|
||||
int d = ztest_random(ztest_opts.zo_datasets);
|
||||
ztest_dataset_destroy(d);
|
||||
txg_wait_synced(spa_get_dsl(spa), 0);
|
||||
}
|
||||
zs->zs_enospc_count = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@
|
|||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 36
|
||||
#serial 37
|
||||
|
||||
AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL])
|
||||
AC_DEFUN([AX_PYTHON_DEVEL],[
|
||||
|
|
@ -316,7 +316,7 @@ EOD`
|
|||
PYTHON_LIBS="-L$ac_python_libdir -lpython$ac_python_version"
|
||||
fi
|
||||
|
||||
if test -z "PYTHON_LIBS"; then
|
||||
if test -z "$PYTHON_LIBS"; then
|
||||
AC_MSG_WARN([
|
||||
Cannot determine location of your Python DSO. Please check it was installed with
|
||||
dynamic libraries enabled, or try setting PYTHON_LIBS by hand.
|
||||
|
|
|
|||
24
sys/contrib/openzfs/config/kernel-free-inode.m4
Normal file
24
sys/contrib/openzfs/config/kernel-free-inode.m4
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
dnl #
|
||||
dnl # Linux 5.2 API change
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_SOPS_FREE_INODE], [
|
||||
ZFS_LINUX_TEST_SRC([super_operations_free_inode], [
|
||||
#include <linux/fs.h>
|
||||
|
||||
static void free_inode(struct inode *) { }
|
||||
|
||||
static struct super_operations sops __attribute__ ((unused)) = {
|
||||
.free_inode = free_inode,
|
||||
};
|
||||
],[])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SOPS_FREE_INODE], [
|
||||
AC_MSG_CHECKING([whether sops->free_inode() exists])
|
||||
ZFS_LINUX_TEST_RESULT([super_operations_free_inode], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_SOPS_FREE_INODE, 1, [sops->free_inode() exists])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
|
@ -134,6 +134,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
|
|||
ZFS_AC_KERNEL_SRC_PIN_USER_PAGES
|
||||
ZFS_AC_KERNEL_SRC_TIMER
|
||||
ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_WB_ERR
|
||||
ZFS_AC_KERNEL_SRC_SOPS_FREE_INODE
|
||||
case "$host_cpu" in
|
||||
powerpc*)
|
||||
ZFS_AC_KERNEL_SRC_CPU_HAS_FEATURE
|
||||
|
|
@ -252,6 +253,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
|
|||
ZFS_AC_KERNEL_PIN_USER_PAGES
|
||||
ZFS_AC_KERNEL_TIMER
|
||||
ZFS_AC_KERNEL_SUPER_BLOCK_S_WB_ERR
|
||||
ZFS_AC_KERNEL_SOPS_FREE_INODE
|
||||
case "$host_cpu" in
|
||||
powerpc*)
|
||||
ZFS_AC_KERNEL_CPU_HAS_FEATURE
|
||||
|
|
|
|||
34
sys/contrib/openzfs/config/user-statx.m4
Normal file
34
sys/contrib/openzfs/config/user-statx.m4
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
dnl #
|
||||
dnl # Check for statx() function and STATX_MNT_ID availability
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_USER_STATX], [
|
||||
AC_CHECK_HEADERS([linux/stat.h],
|
||||
[have_stat_headers=yes],
|
||||
[have_stat_headers=no])
|
||||
|
||||
AS_IF([test "x$have_stat_headers" = "xyes"], [
|
||||
AC_CHECK_FUNC([statx], [
|
||||
AC_DEFINE([HAVE_STATX], [1], [statx() is available])
|
||||
|
||||
dnl Check for STATX_MNT_ID availability
|
||||
AC_MSG_CHECKING([for STATX_MNT_ID])
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
#include <linux/stat.h>
|
||||
]], [[
|
||||
struct statx stx;
|
||||
int mask = STATX_MNT_ID;
|
||||
(void)mask;
|
||||
(void)stx.stx_mnt_id;
|
||||
]])
|
||||
], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_STATX_MNT_ID], [1], [STATX_MNT_ID is available])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
], [
|
||||
AC_MSG_WARN([linux/stat.h not found; skipping statx support])
|
||||
])
|
||||
]) dnl end AC_DEFUN
|
||||
|
|
@ -17,6 +17,7 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [
|
|||
ZFS_AC_CONFIG_USER_LIBUDEV
|
||||
ZFS_AC_CONFIG_USER_LIBUUID
|
||||
ZFS_AC_CONFIG_USER_LIBBLKID
|
||||
ZFS_AC_CONFIG_USER_STATX
|
||||
])
|
||||
ZFS_AC_CONFIG_USER_LIBTIRPC
|
||||
ZFS_AC_CONFIG_USER_LIBCRYPTO
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ lib/systemd/system/zfs-import-scan.service
|
|||
lib/systemd/system/zfs-import.target
|
||||
lib/systemd/system/zfs-load-key.service
|
||||
lib/systemd/system/zfs-mount.service
|
||||
lib/systemd/system/zfs-mount@.service
|
||||
lib/systemd/system/zfs-scrub-monthly@.timer
|
||||
lib/systemd/system/zfs-scrub-weekly@.timer
|
||||
lib/systemd/system/zfs-scrub@.service
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ systemdunit_DATA = \
|
|||
%D%/systemd/system/zfs-import-scan.service \
|
||||
%D%/systemd/system/zfs-import.target \
|
||||
%D%/systemd/system/zfs-mount.service \
|
||||
%D%/systemd/system/zfs-mount@.service \
|
||||
%D%/systemd/system/zfs-scrub-monthly@.timer \
|
||||
%D%/systemd/system/zfs-scrub-weekly@.timer \
|
||||
%D%/systemd/system/zfs-scrub@.service \
|
||||
|
|
|
|||
26
sys/contrib/openzfs/etc/systemd/system/zfs-mount@.service.in
Normal file
26
sys/contrib/openzfs/etc/systemd/system/zfs-mount@.service.in
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
[Unit]
|
||||
Description=Mount ZFS filesystem %I
|
||||
Documentation=man:zfs(8)
|
||||
DefaultDependencies=no
|
||||
After=systemd-udev-settle.service
|
||||
After=zfs-import.target
|
||||
After=zfs-mount.service
|
||||
After=systemd-remount-fs.service
|
||||
Before=local-fs.target
|
||||
ConditionPathIsDirectory=/sys/module/zfs
|
||||
|
||||
# This merely tells the service manager
|
||||
# that unmounting everything undoes the
|
||||
# effect of this service. No extra logic
|
||||
# is ran as a result of these settings.
|
||||
Conflicts=umount.target
|
||||
Before=umount.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
EnvironmentFile=-@initconfdir@/zfs
|
||||
ExecStart=@sbindir@/zfs mount -R %I
|
||||
|
||||
[Install]
|
||||
WantedBy=zfs.target
|
||||
|
|
@ -10,6 +10,7 @@ COMMON_H = \
|
|||
cityhash.h \
|
||||
zfeature_common.h \
|
||||
zfs_comutil.h \
|
||||
zfs_crrd.h \
|
||||
zfs_deleg.h \
|
||||
zfs_fletcher.h \
|
||||
zfs_namecheck.h \
|
||||
|
|
@ -69,7 +70,6 @@ COMMON_H = \
|
|||
sys/metaslab_impl.h \
|
||||
sys/mmp.h \
|
||||
sys/mntent.h \
|
||||
sys/mod.h \
|
||||
sys/multilist.h \
|
||||
sys/nvpair.h \
|
||||
sys/nvpair_impl.h \
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
* Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
|
||||
* Copyright (c) 2019 Datto Inc.
|
||||
* Copyright (c) 2021, Colm Buckley <colm@tuatha.org>
|
||||
* Copyright (c) 2025 Hewlett Packard Enterprise Development LP.
|
||||
*/
|
||||
|
||||
#ifndef _LIBZFS_H
|
||||
|
|
@ -288,10 +289,22 @@ typedef struct trimflags {
|
|||
uint64_t rate;
|
||||
} trimflags_t;
|
||||
|
||||
typedef struct trim_cbdata {
|
||||
trimflags_t trim_flags;
|
||||
pool_trim_func_t cmd_type;
|
||||
} trim_cbdata_t;
|
||||
|
||||
typedef struct initialize_cbdata {
|
||||
boolean_t wait;
|
||||
pool_initialize_func_t cmd_type;
|
||||
} initialize_cbdata_t;
|
||||
/*
|
||||
* Functions to manipulate pool and vdev state
|
||||
*/
|
||||
_LIBZFS_H int zpool_scan(zpool_handle_t *, pool_scan_func_t, pool_scrub_cmd_t);
|
||||
_LIBZFS_H int zpool_scan_range(zpool_handle_t *, pool_scan_func_t,
|
||||
pool_scrub_cmd_t, time_t, time_t);
|
||||
_LIBZFS_H int zpool_initialize_one(zpool_handle_t *, void *);
|
||||
_LIBZFS_H int zpool_initialize(zpool_handle_t *, pool_initialize_func_t,
|
||||
nvlist_t *);
|
||||
_LIBZFS_H int zpool_initialize_wait(zpool_handle_t *, pool_initialize_func_t,
|
||||
|
|
@ -304,7 +317,9 @@ _LIBZFS_H int zpool_reguid(zpool_handle_t *);
|
|||
_LIBZFS_H int zpool_set_guid(zpool_handle_t *, const uint64_t *);
|
||||
_LIBZFS_H int zpool_reopen_one(zpool_handle_t *, void *);
|
||||
|
||||
_LIBZFS_H void zpool_collect_leaves(zpool_handle_t *, nvlist_t *, nvlist_t *);
|
||||
_LIBZFS_H int zpool_sync_one(zpool_handle_t *, void *);
|
||||
_LIBZFS_H int zpool_trim_one(zpool_handle_t *, void *);
|
||||
|
||||
_LIBZFS_H int zpool_ddt_prune(zpool_handle_t *, zpool_ddt_prune_unit_t,
|
||||
uint64_t);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ noinst_HEADERS = \
|
|||
%D%/spl/sys/list_impl.h \
|
||||
%D%/spl/sys/lock.h \
|
||||
%D%/spl/sys/misc.h \
|
||||
%D%/spl/sys/mod_os.h \
|
||||
%D%/spl/sys/mod.h \
|
||||
%D%/spl/sys/mode.h \
|
||||
%D%/spl/sys/mount.h \
|
||||
%D%/spl/sys/mutex.h \
|
||||
|
|
|
|||
|
|
@ -56,4 +56,9 @@ struct opensolaris_utsname {
|
|||
#define task_io_account_read(n)
|
||||
#define task_io_account_write(n)
|
||||
|
||||
/*
|
||||
* Check if the current thread is a memory reclaim thread.
|
||||
*/
|
||||
extern int current_is_reclaim_thread(void);
|
||||
|
||||
#endif /* _OPENSOLARIS_SYS_MISC_H_ */
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
extern const int zfs_vm_pagerret_bad;
|
||||
extern const int zfs_vm_pagerret_error;
|
||||
extern const int zfs_vm_pagerret_ok;
|
||||
extern const int zfs_vm_pagerret_pend;
|
||||
extern const int zfs_vm_pagerput_sync;
|
||||
extern const int zfs_vm_pagerput_inval;
|
||||
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ struct taskq;
|
|||
#define LOOKUP_XATTR 0x02 /* lookup up extended attr dir */
|
||||
#define CREATE_XATTR_DIR 0x04 /* Create extended attr dir */
|
||||
#define LOOKUP_HAVE_SYSATTR_DIR 0x08 /* Already created virtual GFS dir */
|
||||
#define LOOKUP_NAMED_ATTR 0x10 /* Lookup a named attribute */
|
||||
|
||||
/*
|
||||
* Public vnode manipulation functions.
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ kernel_spl_sys_HEADERS = \
|
|||
%D%/spl/sys/kstat.h \
|
||||
%D%/spl/sys/list.h \
|
||||
%D%/spl/sys/misc.h \
|
||||
%D%/spl/sys/mod_os.h \
|
||||
%D%/spl/sys/mod.h \
|
||||
%D%/spl/sys/mutex.h \
|
||||
%D%/spl/sys/param.h \
|
||||
%D%/spl/sys/proc.h \
|
||||
|
|
|
|||
|
|
@ -71,6 +71,22 @@ atomic_cas_ptr(volatile void *target, void *cmp, void *newval)
|
|||
return ((void *)atomic_cas_64((volatile uint64_t *)target,
|
||||
(uint64_t)cmp, (uint64_t)newval));
|
||||
}
|
||||
static __inline__ void *
|
||||
atomic_swap_ptr(volatile void *target, void *newval)
|
||||
{
|
||||
return ((void *)atomic_swap_64((volatile uint64_t *)target,
|
||||
(uint64_t)newval));
|
||||
}
|
||||
static __inline__ void *
|
||||
atomic_load_ptr(volatile void *target)
|
||||
{
|
||||
return ((void *)atomic_load_64((volatile uint64_t *)target));
|
||||
}
|
||||
static __inline__ void
|
||||
atomic_store_ptr(volatile void *target, void *newval)
|
||||
{
|
||||
atomic_store_64((volatile uint64_t *)target, (uint64_t)newval);
|
||||
}
|
||||
#else /* _LP64 */
|
||||
static __inline__ void *
|
||||
atomic_cas_ptr(volatile void *target, void *cmp, void *newval)
|
||||
|
|
@ -78,6 +94,22 @@ atomic_cas_ptr(volatile void *target, void *cmp, void *newval)
|
|||
return ((void *)atomic_cas_32((volatile uint32_t *)target,
|
||||
(uint32_t)cmp, (uint32_t)newval));
|
||||
}
|
||||
static __inline__ void *
|
||||
atomic_swap_ptr(volatile void *target, void *newval)
|
||||
{
|
||||
return ((void *)atomic_swap_32((volatile uint32_t *)target,
|
||||
(uint32_t)newval));
|
||||
}
|
||||
static __inline__ void *
|
||||
atomic_load_ptr(volatile void *target)
|
||||
{
|
||||
return ((void *)atomic_load_32((volatile uint32_t *)target));
|
||||
}
|
||||
static __inline__ void
|
||||
atomic_store_ptr(volatile void *target, void *newval)
|
||||
{
|
||||
atomic_store_32((volatile uint32_t *)target, (uint32_t)newval);
|
||||
}
|
||||
#endif /* _LP64 */
|
||||
|
||||
#endif /* _SPL_ATOMIC_H */
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ void *spl_kvmalloc(size_t size, gfp_t flags);
|
|||
/*
|
||||
* Convert a KM_* flags mask to its Linux GFP_* counterpart. The conversion
|
||||
* function is context aware which means that KM_SLEEP allocations can be
|
||||
* safely used in syncing contexts which have set PF_FSTRANS.
|
||||
* safely used in syncing contexts which have set SPL_FSTRANS.
|
||||
*/
|
||||
static inline gfp_t
|
||||
kmem_flags_convert(int flags)
|
||||
|
|
@ -91,25 +91,11 @@ typedef struct {
|
|||
} fstrans_cookie_t;
|
||||
|
||||
/*
|
||||
* Introduced in Linux 3.9, however this cannot be solely relied on before
|
||||
* Linux 3.18 as it doesn't turn off __GFP_FS as it should.
|
||||
* SPL_FSTRANS is the set of flags that indicate that the task is in a
|
||||
* filesystem or IO codepath, and so any allocation must not call back into
|
||||
* those codepaths (eg to swap).
|
||||
*/
|
||||
#ifdef PF_MEMALLOC_NOIO
|
||||
#define __SPL_PF_MEMALLOC_NOIO (PF_MEMALLOC_NOIO)
|
||||
#else
|
||||
#define __SPL_PF_MEMALLOC_NOIO (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PF_FSTRANS is removed from Linux 4.12
|
||||
*/
|
||||
#ifdef PF_FSTRANS
|
||||
#define __SPL_PF_FSTRANS (PF_FSTRANS)
|
||||
#else
|
||||
#define __SPL_PF_FSTRANS (0)
|
||||
#endif
|
||||
|
||||
#define SPL_FSTRANS (__SPL_PF_FSTRANS|__SPL_PF_MEMALLOC_NOIO)
|
||||
#define SPL_FSTRANS (PF_MEMALLOC_NOIO)
|
||||
|
||||
static inline fstrans_cookie_t
|
||||
spl_fstrans_mark(void)
|
||||
|
|
@ -141,43 +127,8 @@ spl_fstrans_check(void)
|
|||
return (current->flags & SPL_FSTRANS);
|
||||
}
|
||||
|
||||
/*
|
||||
* specifically used to check PF_FSTRANS flag, cannot be relied on for
|
||||
* checking spl_fstrans_mark().
|
||||
*/
|
||||
static inline int
|
||||
__spl_pf_fstrans_check(void)
|
||||
{
|
||||
return (current->flags & __SPL_PF_FSTRANS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Kernel compatibility for GFP flags
|
||||
*/
|
||||
/* < 4.13 */
|
||||
#ifndef __GFP_RETRY_MAYFAIL
|
||||
#define __GFP_RETRY_MAYFAIL __GFP_REPEAT
|
||||
#endif
|
||||
/* < 4.4 */
|
||||
#ifndef __GFP_RECLAIM
|
||||
#define __GFP_RECLAIM __GFP_WAIT
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ATOMIC64_T
|
||||
#define kmem_alloc_used_add(size) atomic64_add(size, &kmem_alloc_used)
|
||||
#define kmem_alloc_used_sub(size) atomic64_sub(size, &kmem_alloc_used)
|
||||
#define kmem_alloc_used_read() atomic64_read(&kmem_alloc_used)
|
||||
#define kmem_alloc_used_set(size) atomic64_set(&kmem_alloc_used, size)
|
||||
extern atomic64_t kmem_alloc_used;
|
||||
extern unsigned long long kmem_alloc_max;
|
||||
#else /* HAVE_ATOMIC64_T */
|
||||
#define kmem_alloc_used_add(size) atomic_add(size, &kmem_alloc_used)
|
||||
#define kmem_alloc_used_sub(size) atomic_sub(size, &kmem_alloc_used)
|
||||
#define kmem_alloc_used_read() atomic_read(&kmem_alloc_used)
|
||||
#define kmem_alloc_used_set(size) atomic_set(&kmem_alloc_used, size)
|
||||
extern atomic_t kmem_alloc_used;
|
||||
extern unsigned long long kmem_alloc_max;
|
||||
#endif /* HAVE_ATOMIC64_T */
|
||||
extern uint64_t kmem_alloc_max;
|
||||
|
||||
extern unsigned int spl_kmem_alloc_warn;
|
||||
extern unsigned int spl_kmem_alloc_max;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,13 @@
|
|||
#define _OS_LINUX_SPL_MISC_H
|
||||
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/swap.h>
|
||||
|
||||
extern void spl_signal_kobj_evt(struct block_device *bdev);
|
||||
|
||||
/*
|
||||
* Check if the current thread is a memory reclaim thread.
|
||||
*/
|
||||
extern int current_is_reclaim_thread(void);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -59,8 +59,6 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
|
|||
__field(uint64_t, z_size)
|
||||
__field(uint64_t, z_pflags)
|
||||
__field(uint32_t, z_sync_cnt)
|
||||
__field(uint32_t, z_sync_writes_cnt)
|
||||
__field(uint32_t, z_async_writes_cnt)
|
||||
__field(mode_t, z_mode)
|
||||
__field(boolean_t, z_is_sa)
|
||||
__field(boolean_t, z_is_ctldir)
|
||||
|
|
@ -92,8 +90,6 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
|
|||
__entry->z_size = zn->z_size;
|
||||
__entry->z_pflags = zn->z_pflags;
|
||||
__entry->z_sync_cnt = zn->z_sync_cnt;
|
||||
__entry->z_sync_writes_cnt = zn->z_sync_writes_cnt;
|
||||
__entry->z_async_writes_cnt = zn->z_async_writes_cnt;
|
||||
__entry->z_mode = zn->z_mode;
|
||||
__entry->z_is_sa = zn->z_is_sa;
|
||||
__entry->z_is_ctldir = zn->z_is_ctldir;
|
||||
|
|
@ -117,7 +113,7 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
|
|||
TP_printk("zn { id %llu unlinked %u atime_dirty %u "
|
||||
"zn_prefetch %u blksz %u seq %u "
|
||||
"mapcnt %llu size %llu pflags %llu "
|
||||
"sync_cnt %u sync_writes_cnt %u async_writes_cnt %u "
|
||||
"sync_cnt %u "
|
||||
"mode 0x%x is_sa %d is_ctldir %d "
|
||||
"inode { uid %u gid %u ino %lu nlink %u size %lli "
|
||||
"blkbits %u bytes %u mode 0x%x generation %x } } "
|
||||
|
|
@ -126,7 +122,6 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
|
|||
__entry->z_zn_prefetch, __entry->z_blksz,
|
||||
__entry->z_seq, __entry->z_mapcnt, __entry->z_size,
|
||||
__entry->z_pflags, __entry->z_sync_cnt,
|
||||
__entry->z_sync_writes_cnt, __entry->z_async_writes_cnt,
|
||||
__entry->z_mode, __entry->z_is_sa, __entry->z_is_ctldir,
|
||||
__entry->i_uid, __entry->i_gid, __entry->i_ino, __entry->i_nlink,
|
||||
__entry->i_size, __entry->i_blkbits,
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
__field(zio_flag_t, zio_orig_flags) \
|
||||
__field(enum zio_stage, zio_orig_stage) \
|
||||
__field(enum zio_stage, zio_orig_pipeline) \
|
||||
__field(uint8_t, zio_reexecute) \
|
||||
__field(uint8_t, zio_post) \
|
||||
__field(uint64_t, zio_txg) \
|
||||
__field(int, zio_error) \
|
||||
__field(uint64_t, zio_ena) \
|
||||
|
|
@ -74,7 +74,7 @@
|
|||
__entry->zio_orig_flags = zio->io_orig_flags; \
|
||||
__entry->zio_orig_stage = zio->io_orig_stage; \
|
||||
__entry->zio_orig_pipeline = zio->io_orig_pipeline; \
|
||||
__entry->zio_reexecute = zio->io_reexecute; \
|
||||
__entry->zio_post = zio->io_post; \
|
||||
__entry->zio_txg = zio->io_txg; \
|
||||
__entry->zio_error = zio->io_error; \
|
||||
__entry->zio_ena = zio->io_ena; \
|
||||
|
|
@ -92,7 +92,7 @@
|
|||
"zio { type %u prio %u size %llu orig_size %llu " \
|
||||
"offset %llu timestamp %llu delta %llu delay %llu " \
|
||||
"flags 0x%llx stage 0x%x pipeline 0x%x orig_flags 0x%llx " \
|
||||
"orig_stage 0x%x orig_pipeline 0x%x reexecute %u " \
|
||||
"orig_stage 0x%x orig_pipeline 0x%x post %u " \
|
||||
"txg %llu error %d ena %llu prop { checksum %u compress %u " \
|
||||
"type %u level %u copies %u dedup %u dedup_verify %u nopwrite %u } }"
|
||||
|
||||
|
|
@ -102,7 +102,7 @@
|
|||
__entry->zio_timestamp, __entry->zio_delta, __entry->zio_delay, \
|
||||
__entry->zio_flags, __entry->zio_stage, __entry->zio_pipeline, \
|
||||
__entry->zio_orig_flags, __entry->zio_orig_stage, \
|
||||
__entry->zio_orig_pipeline, __entry->zio_reexecute, \
|
||||
__entry->zio_orig_pipeline, __entry->zio_post, \
|
||||
__entry->zio_txg, __entry->zio_error, __entry->zio_ena, \
|
||||
__entry->zp_checksum, __entry->zp_compress, __entry->zp_type, \
|
||||
__entry->zp_level, __entry->zp_copies, __entry->zp_dedup, \
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ struct znode;
|
|||
|
||||
extern int zfs_sync(struct super_block *, int, cred_t *);
|
||||
extern int zfs_inode_alloc(struct super_block *, struct inode **ip);
|
||||
extern void zfs_inode_free(struct inode *);
|
||||
extern void zfs_inode_destroy(struct inode *);
|
||||
extern void zfs_mark_inode_dirty(struct inode *);
|
||||
extern boolean_t zfs_relatime_need_update(const struct inode *);
|
||||
|
|
|
|||
|
|
@ -954,7 +954,7 @@ typedef struct arc_sums {
|
|||
wmsum_t arcstat_data_size;
|
||||
wmsum_t arcstat_metadata_size;
|
||||
wmsum_t arcstat_dbuf_size;
|
||||
wmsum_t arcstat_dnode_size;
|
||||
aggsum_t arcstat_dnode_size;
|
||||
wmsum_t arcstat_bonus_size;
|
||||
wmsum_t arcstat_l2_hits;
|
||||
wmsum_t arcstat_l2_misses;
|
||||
|
|
|
|||
|
|
@ -164,6 +164,7 @@ typedef struct dbuf_dirty_record {
|
|||
boolean_t dr_nopwrite;
|
||||
boolean_t dr_brtwrite;
|
||||
boolean_t dr_diowrite;
|
||||
boolean_t dr_rewrite;
|
||||
boolean_t dr_has_raw_params;
|
||||
|
||||
/* Override and raw params are mutually exclusive. */
|
||||
|
|
|
|||
|
|
@ -414,6 +414,9 @@ typedef struct dmu_buf {
|
|||
#define DMU_POOL_ZPOOL_CHECKPOINT "com.delphix:zpool_checkpoint"
|
||||
#define DMU_POOL_LOG_SPACEMAP_ZAP "com.delphix:log_spacemap_zap"
|
||||
#define DMU_POOL_DELETED_CLONES "com.delphix:deleted_clones"
|
||||
#define DMU_POOL_TXG_LOG_TIME_MINUTES "com.klaraystems:txg_log_time:minutes"
|
||||
#define DMU_POOL_TXG_LOG_TIME_DAYS "com.klaraystems:txg_log_time:days"
|
||||
#define DMU_POOL_TXG_LOG_TIME_MONTHS "com.klaraystems:txg_log_time:months"
|
||||
|
||||
/*
|
||||
* Allocate an object from this objset. The range of object numbers
|
||||
|
|
@ -822,6 +825,7 @@ struct blkptr *dmu_buf_get_blkptr(dmu_buf_t *db);
|
|||
*/
|
||||
void dmu_buf_will_dirty(dmu_buf_t *db, dmu_tx_t *tx);
|
||||
void dmu_buf_will_dirty_flags(dmu_buf_t *db, dmu_tx_t *tx, dmu_flags_t flags);
|
||||
void dmu_buf_will_rewrite(dmu_buf_t *db, dmu_tx_t *tx);
|
||||
boolean_t dmu_buf_is_dirty(dmu_buf_t *db, dmu_tx_t *tx);
|
||||
void dmu_buf_set_crypt_params(dmu_buf_t *db_fake, boolean_t byteorder,
|
||||
const uint8_t *salt, const uint8_t *iv, const uint8_t *mac, dmu_tx_t *tx);
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ struct objset {
|
|||
* The largest zpl file block allowed in special class.
|
||||
* cached here instead of zfsvfs for easier access.
|
||||
*/
|
||||
int os_zpl_special_smallblock;
|
||||
uint64_t os_zpl_special_smallblock;
|
||||
|
||||
/*
|
||||
* Pointer is constant; the blkptr it points to is protected by
|
||||
|
|
|
|||
|
|
@ -59,6 +59,13 @@ typedef int (blkptr_cb_t)(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
|
|||
*/
|
||||
#define TRAVERSE_NO_DECRYPT (1<<5)
|
||||
|
||||
/*
|
||||
* Always use logical birth time for birth time comparisons. This is useful
|
||||
* for operations that care about user data changes rather than physical
|
||||
* block rewrites (e.g., incremental replication).
|
||||
*/
|
||||
#define TRAVERSE_LOGICAL (1<<6)
|
||||
|
||||
/* Special traverse error return value to indicate skipping of children */
|
||||
#define TRAVERSE_VISIT_NO_CHILDREN -1
|
||||
|
||||
|
|
|
|||
|
|
@ -1627,6 +1627,9 @@ typedef struct zfs_rewrite_args {
|
|||
uint64_t arg;
|
||||
} zfs_rewrite_args_t;
|
||||
|
||||
/* zfs_rewrite_args flags */
|
||||
#define ZFS_REWRITE_PHYSICAL 0x1 /* Preserve logical birth time. */
|
||||
|
||||
#define ZFS_IOC_REWRITE _IOW(0x83, 3, zfs_rewrite_args_t)
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -110,9 +110,10 @@ void metaslab_class_balance(metaslab_class_t *mc, boolean_t onsync);
|
|||
void metaslab_class_histogram_verify(metaslab_class_t *);
|
||||
uint64_t metaslab_class_fragmentation(metaslab_class_t *);
|
||||
uint64_t metaslab_class_expandable_space(metaslab_class_t *);
|
||||
boolean_t metaslab_class_throttle_reserve(metaslab_class_t *, int, zio_t *,
|
||||
boolean_t, boolean_t *);
|
||||
boolean_t metaslab_class_throttle_unreserve(metaslab_class_t *, int, zio_t *);
|
||||
boolean_t metaslab_class_throttle_reserve(metaslab_class_t *, int, int,
|
||||
uint64_t, boolean_t, boolean_t *);
|
||||
boolean_t metaslab_class_throttle_unreserve(metaslab_class_t *, int, int,
|
||||
uint64_t);
|
||||
void metaslab_class_evict_old(metaslab_class_t *, uint64_t);
|
||||
const char *metaslab_class_get_name(metaslab_class_t *);
|
||||
uint64_t metaslab_class_get_alloc(metaslab_class_t *);
|
||||
|
|
|
|||
|
|
@ -539,6 +539,8 @@ typedef struct metaslab_unflushed_phys {
|
|||
uint64_t msp_unflushed_txg;
|
||||
} metaslab_unflushed_phys_t;
|
||||
|
||||
char *metaslab_rt_name(metaslab_group_t *, metaslab_t *, const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
|
||||
* Copyright (C) 2007 The Regents of the University of California.
|
||||
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
|
||||
* Written by Brian Behlendorf <behlendorf1@llnl.gov>.
|
||||
* UCRL-CODE-235197
|
||||
*
|
||||
* This file is part of the SPL, Solaris Porting Layer.
|
||||
*
|
||||
* The SPL is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SPL is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with the SPL. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _SYS_MOD_H
|
||||
#define _SYS_MOD_H
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/mod_os.h>
|
||||
#else
|
||||
/*
|
||||
* Exported symbols
|
||||
*/
|
||||
#define EXPORT_SYMBOL(x)
|
||||
#endif
|
||||
|
||||
#endif /* SYS_MOD_H */
|
||||
|
|
@ -49,6 +49,9 @@ typedef enum zfs_range_seg_type {
|
|||
ZFS_RANGE_SEG_NUM_TYPES,
|
||||
} zfs_range_seg_type_t;
|
||||
|
||||
#define ZFS_RT_NAME(rt) (((rt)->rt_name != NULL) ? (rt)->rt_name : "")
|
||||
#define ZFS_RT_F_DYN_NAME (1ULL << 0) /* if rt_name must be freed */
|
||||
|
||||
/*
|
||||
* Note: the range_tree may not be accessed concurrently; consumers
|
||||
* must provide external locking if required.
|
||||
|
|
@ -68,6 +71,9 @@ typedef struct zfs_range_tree {
|
|||
void *rt_arg;
|
||||
uint64_t rt_gap; /* allowable inter-segment gap */
|
||||
|
||||
uint64_t rt_flags;
|
||||
const char *rt_name; /* details for debugging */
|
||||
|
||||
/*
|
||||
* The rt_histogram maintains a histogram of ranges. Each bucket,
|
||||
* rt_histogram[i], contains the number of ranges whose size is:
|
||||
|
|
@ -281,6 +287,9 @@ zfs_range_tree_t *zfs_range_tree_create_gap(const zfs_range_tree_ops_t *ops,
|
|||
uint64_t gap);
|
||||
zfs_range_tree_t *zfs_range_tree_create(const zfs_range_tree_ops_t *ops,
|
||||
zfs_range_seg_type_t type, void *arg, uint64_t start, uint64_t shift);
|
||||
zfs_range_tree_t *zfs_range_tree_create_flags(const zfs_range_tree_ops_t *ops,
|
||||
zfs_range_seg_type_t type, void *arg, uint64_t start, uint64_t shift,
|
||||
uint64_t flags, const char *name);
|
||||
void zfs_range_tree_destroy(zfs_range_tree_t *rt);
|
||||
boolean_t zfs_range_tree_contains(zfs_range_tree_t *rt, uint64_t start,
|
||||
uint64_t size);
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ typedef struct zio_cksum_salt {
|
|||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* 6 |BDX|lvl| type | cksum |E| comp| PSIZE | LSIZE |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* 7 | padding |
|
||||
* 7 |R| padding |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* 8 | padding |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|
|
@ -175,6 +175,7 @@ typedef struct zio_cksum_salt {
|
|||
* E blkptr_t contains embedded data (see below)
|
||||
* lvl level of indirection
|
||||
* type DMU object type
|
||||
* R rewrite (reallocated/rewritten at phys birth TXG)
|
||||
* phys birth txg when dva[0] was written; zero if same as logical birth txg
|
||||
* note that typically all the dva's would be written in this
|
||||
* txg, but they could be different if they were moved by
|
||||
|
|
@ -190,11 +191,11 @@ typedef struct zio_cksum_salt {
|
|||
*
|
||||
* 64 56 48 40 32 24 16 8 0
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* 0 | vdev1 | pad | ASIZE |
|
||||
* 0 | pad | vdev1 | pad | ASIZE |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* 1 |G| offset1 |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* 2 | vdev2 | pad | ASIZE |
|
||||
* 2 | pad | vdev2 | pad | ASIZE |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* 3 |G| offset2 |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|
|
@ -204,7 +205,7 @@ typedef struct zio_cksum_salt {
|
|||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* 6 |BDX|lvl| type | cksum |E| comp| PSIZE | LSIZE |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* 7 | padding |
|
||||
* 7 |R| padding |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* 8 | padding |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
|
|
@ -373,7 +374,8 @@ typedef enum bp_embedded_type {
|
|||
typedef struct blkptr {
|
||||
dva_t blk_dva[SPA_DVAS_PER_BP]; /* Data Virtual Addresses */
|
||||
uint64_t blk_prop; /* size, compression, type, etc */
|
||||
uint64_t blk_pad[2]; /* Extra space for the future */
|
||||
uint64_t blk_prop2; /* additional properties */
|
||||
uint64_t blk_pad; /* Extra space for the future */
|
||||
uint64_t blk_birth_word[2];
|
||||
uint64_t blk_fill; /* fill count */
|
||||
zio_cksum_t blk_cksum; /* 256-bit checksum */
|
||||
|
|
@ -476,32 +478,51 @@ typedef struct blkptr {
|
|||
#define BP_GET_FREE(bp) BF64_GET((bp)->blk_fill, 0, 1)
|
||||
#define BP_SET_FREE(bp, x) BF64_SET((bp)->blk_fill, 0, 1, x)
|
||||
|
||||
/*
|
||||
* Block birth time macros for different use cases:
|
||||
* - BP_GET_LOGICAL_BIRTH(): When the block was logically modified by user.
|
||||
* To be used with a focus on user data, like incremental replication.
|
||||
* - BP_GET_PHYSICAL_BIRTH(): When the block was physically written to disks.
|
||||
* For regular writes is equal to logical birth. For dedup and block cloning
|
||||
* can be smaller than logical birth. For remapped and rewritten blocks can
|
||||
* be bigger. To be used with focus on physical disk content: ARC, DDT, scrub.
|
||||
* - BP_GET_RAW_PHYSICAL_BIRTH(): Raw physical birth value. Zero if equal
|
||||
* to logical birth. Should only be used for BP copying and debugging.
|
||||
* - BP_GET_BIRTH(): When the block was allocated, which is a physical birth
|
||||
* for rewritten blocks (rewrite flag set) or logical birth otherwise.
|
||||
*/
|
||||
#define BP_GET_LOGICAL_BIRTH(bp) (bp)->blk_birth_word[1]
|
||||
#define BP_SET_LOGICAL_BIRTH(bp, x) ((bp)->blk_birth_word[1] = (x))
|
||||
|
||||
#define BP_GET_PHYSICAL_BIRTH(bp) (bp)->blk_birth_word[0]
|
||||
#define BP_GET_RAW_PHYSICAL_BIRTH(bp) (bp)->blk_birth_word[0]
|
||||
#define BP_SET_PHYSICAL_BIRTH(bp, x) ((bp)->blk_birth_word[0] = (x))
|
||||
|
||||
#define BP_GET_BIRTH(bp) \
|
||||
(BP_IS_EMBEDDED(bp) ? 0 : \
|
||||
BP_GET_PHYSICAL_BIRTH(bp) ? BP_GET_PHYSICAL_BIRTH(bp) : \
|
||||
#define BP_GET_PHYSICAL_BIRTH(bp) \
|
||||
(BP_IS_EMBEDDED(bp) ? 0 : \
|
||||
BP_GET_RAW_PHYSICAL_BIRTH(bp) ? BP_GET_RAW_PHYSICAL_BIRTH(bp) : \
|
||||
BP_GET_LOGICAL_BIRTH(bp))
|
||||
|
||||
#define BP_SET_BIRTH(bp, logical, physical) \
|
||||
{ \
|
||||
ASSERT(!BP_IS_EMBEDDED(bp)); \
|
||||
BP_SET_LOGICAL_BIRTH(bp, logical); \
|
||||
BP_SET_PHYSICAL_BIRTH(bp, \
|
||||
((logical) == (physical) ? 0 : (physical))); \
|
||||
#define BP_GET_BIRTH(bp) \
|
||||
((BP_IS_EMBEDDED(bp) || !BP_GET_REWRITE(bp)) ? \
|
||||
BP_GET_LOGICAL_BIRTH(bp) : BP_GET_PHYSICAL_BIRTH(bp))
|
||||
|
||||
#define BP_SET_BIRTH(bp, logical, physical) \
|
||||
{ \
|
||||
ASSERT(!BP_IS_EMBEDDED(bp)); \
|
||||
BP_SET_LOGICAL_BIRTH(bp, logical); \
|
||||
BP_SET_PHYSICAL_BIRTH(bp, \
|
||||
((logical) == (physical) ? 0 : (physical))); \
|
||||
}
|
||||
|
||||
#define BP_GET_FILL(bp) \
|
||||
((BP_IS_ENCRYPTED(bp)) ? BF64_GET((bp)->blk_fill, 0, 32) : \
|
||||
((BP_IS_EMBEDDED(bp)) ? 1 : (bp)->blk_fill))
|
||||
(BP_IS_EMBEDDED(bp) ? 1 : \
|
||||
BP_IS_ENCRYPTED(bp) ? BF64_GET((bp)->blk_fill, 0, 32) : \
|
||||
(bp)->blk_fill)
|
||||
|
||||
#define BP_SET_FILL(bp, fill) \
|
||||
{ \
|
||||
if (BP_IS_ENCRYPTED(bp)) \
|
||||
ASSERT(!BP_IS_EMBEDDED(bp)); \
|
||||
if (BP_IS_ENCRYPTED(bp)) \
|
||||
BF64_SET((bp)->blk_fill, 0, 32, fill); \
|
||||
else \
|
||||
(bp)->blk_fill = fill; \
|
||||
|
|
@ -516,6 +537,15 @@ typedef struct blkptr {
|
|||
BF64_SET((bp)->blk_fill, 32, 32, iv2); \
|
||||
}
|
||||
|
||||
#define BP_GET_REWRITE(bp) \
|
||||
(BP_IS_EMBEDDED(bp) ? 0 : BF64_GET((bp)->blk_prop2, 63, 1))
|
||||
|
||||
#define BP_SET_REWRITE(bp, x) \
|
||||
{ \
|
||||
ASSERT(!BP_IS_EMBEDDED(bp)); \
|
||||
BF64_SET((bp)->blk_prop2, 63, 1, x); \
|
||||
}
|
||||
|
||||
#define BP_IS_METADATA(bp) \
|
||||
(BP_GET_LEVEL(bp) > 0 || DMU_OT_IS_METADATA(BP_GET_TYPE(bp)))
|
||||
|
||||
|
|
@ -545,7 +575,7 @@ typedef struct blkptr {
|
|||
(dva1)->dva_word[0] == (dva2)->dva_word[0])
|
||||
|
||||
#define BP_EQUAL(bp1, bp2) \
|
||||
(BP_GET_BIRTH(bp1) == BP_GET_BIRTH(bp2) && \
|
||||
(BP_GET_PHYSICAL_BIRTH(bp1) == BP_GET_PHYSICAL_BIRTH(bp2) && \
|
||||
BP_GET_LOGICAL_BIRTH(bp1) == BP_GET_LOGICAL_BIRTH(bp2) && \
|
||||
DVA_EQUAL(&(bp1)->blk_dva[0], &(bp2)->blk_dva[0]) && \
|
||||
DVA_EQUAL(&(bp1)->blk_dva[1], &(bp2)->blk_dva[1]) && \
|
||||
|
|
@ -588,8 +618,8 @@ typedef struct blkptr {
|
|||
{ \
|
||||
BP_ZERO_DVAS(bp); \
|
||||
(bp)->blk_prop = 0; \
|
||||
(bp)->blk_pad[0] = 0; \
|
||||
(bp)->blk_pad[1] = 0; \
|
||||
(bp)->blk_prop2 = 0; \
|
||||
(bp)->blk_pad = 0; \
|
||||
(bp)->blk_birth_word[0] = 0; \
|
||||
(bp)->blk_birth_word[1] = 0; \
|
||||
(bp)->blk_fill = 0; \
|
||||
|
|
@ -696,7 +726,7 @@ typedef struct blkptr {
|
|||
(u_longlong_t)BP_GET_LSIZE(bp), \
|
||||
(u_longlong_t)BP_GET_PSIZE(bp), \
|
||||
(u_longlong_t)BP_GET_LOGICAL_BIRTH(bp), \
|
||||
(u_longlong_t)BP_GET_BIRTH(bp), \
|
||||
(u_longlong_t)BP_GET_PHYSICAL_BIRTH(bp), \
|
||||
(u_longlong_t)BP_GET_FILL(bp), \
|
||||
ws, \
|
||||
(u_longlong_t)bp->blk_cksum.zc_word[0], \
|
||||
|
|
@ -1065,6 +1095,7 @@ extern metaslab_class_t *spa_normal_class(spa_t *spa);
|
|||
extern metaslab_class_t *spa_log_class(spa_t *spa);
|
||||
extern metaslab_class_t *spa_embedded_log_class(spa_t *spa);
|
||||
extern metaslab_class_t *spa_special_class(spa_t *spa);
|
||||
extern metaslab_class_t *spa_special_embedded_log_class(spa_t *spa);
|
||||
extern metaslab_class_t *spa_dedup_class(spa_t *spa);
|
||||
extern metaslab_class_t *spa_preferred_class(spa_t *spa, const zio_t *zio);
|
||||
extern boolean_t spa_special_has_ddt(spa_t *spa);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@
|
|||
#include <sys/dsl_deadlist.h>
|
||||
#include <zfeature_common.h>
|
||||
|
||||
#include "zfs_crrd.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
@ -246,6 +248,7 @@ struct spa {
|
|||
metaslab_class_t *spa_log_class; /* intent log data class */
|
||||
metaslab_class_t *spa_embedded_log_class; /* log on normal vdevs */
|
||||
metaslab_class_t *spa_special_class; /* special allocation class */
|
||||
metaslab_class_t *spa_special_embedded_log_class; /* log on special */
|
||||
metaslab_class_t *spa_dedup_class; /* dedup allocation class */
|
||||
uint64_t spa_first_txg; /* first txg after spa_open() */
|
||||
uint64_t spa_final_txg; /* txg of export/destroy */
|
||||
|
|
@ -343,6 +346,12 @@ struct spa {
|
|||
spa_checkpoint_info_t spa_checkpoint_info; /* checkpoint accounting */
|
||||
zthr_t *spa_checkpoint_discard_zthr;
|
||||
|
||||
kmutex_t spa_txg_log_time_lock; /* for spa_txg_log_time */
|
||||
dbrrd_t spa_txg_log_time;
|
||||
uint64_t spa_last_noted_txg;
|
||||
uint64_t spa_last_noted_txg_time;
|
||||
uint64_t spa_last_flush_txg_time;
|
||||
|
||||
space_map_t *spa_syncing_log_sm; /* current log space map */
|
||||
avl_tree_t spa_sm_logs_by_txg;
|
||||
kmutex_t spa_flushed_ms_lock; /* for metaslabs_by_flushed */
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ extern uint64_t vdev_asize_to_psize_txg(vdev_t *vd, uint64_t asize,
|
|||
extern uint64_t vdev_psize_to_asize_txg(vdev_t *vd, uint64_t psize,
|
||||
uint64_t txg);
|
||||
extern uint64_t vdev_psize_to_asize(vdev_t *vd, uint64_t psize);
|
||||
extern uint64_t vdev_get_min_alloc(vdev_t *vd);
|
||||
|
||||
/*
|
||||
* Return the amount of space allocated for a gang block header. Note that
|
||||
|
|
@ -148,7 +149,20 @@ extern uint64_t vdev_psize_to_asize(vdev_t *vd, uint64_t psize);
|
|||
static inline uint64_t
|
||||
vdev_gang_header_asize(vdev_t *vd)
|
||||
{
|
||||
return (vdev_psize_to_asize_txg(vd, SPA_GANGBLOCKSIZE, 0));
|
||||
return (vdev_psize_to_asize_txg(vd, SPA_OLD_GANGBLOCKSIZE, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the amount of data that can be stored in a gang header. Because we
|
||||
* need to ensure gang headers can always be allocated (as long as there is
|
||||
* space available), this is the minimum allocatable size on the vdev. Note that
|
||||
* since the physical birth txg is not provided, this must be constant for
|
||||
* a given vdev. (e.g. raidz expansion can't change this)
|
||||
*/
|
||||
static inline uint64_t
|
||||
vdev_gang_header_psize(vdev_t *vd)
|
||||
{
|
||||
return (vdev_get_min_alloc(vd));
|
||||
}
|
||||
|
||||
extern int vdev_fault(spa_t *spa, uint64_t guid, vdev_aux_t aux);
|
||||
|
|
|
|||
|
|
@ -621,7 +621,6 @@ extern uint64_t vdev_default_asize(vdev_t *vd, uint64_t psize, uint64_t txg);
|
|||
extern uint64_t vdev_default_min_asize(vdev_t *vd);
|
||||
extern uint64_t vdev_get_min_asize(vdev_t *vd);
|
||||
extern void vdev_set_min_asize(vdev_t *vd);
|
||||
extern uint64_t vdev_get_min_alloc(vdev_t *vd);
|
||||
extern uint64_t vdev_get_nparity(vdev_t *vd);
|
||||
extern uint64_t vdev_get_ndisks(vdev_t *vd);
|
||||
|
||||
|
|
@ -645,10 +644,11 @@ extern int vdev_obsolete_counts_are_precise(vdev_t *vd, boolean_t *are_precise);
|
|||
int vdev_checkpoint_sm_object(vdev_t *vd, uint64_t *sm_obj);
|
||||
void vdev_metaslab_group_create(vdev_t *vd);
|
||||
uint64_t vdev_best_ashift(uint64_t logical, uint64_t a, uint64_t b);
|
||||
#if defined(__linux__)
|
||||
#if defined(__linux__) && defined(_KERNEL)
|
||||
int param_get_raidz_impl(char *buf, zfs_kernel_param_t *kp);
|
||||
#endif
|
||||
int param_set_raidz_impl(ZFS_MODULE_PARAM_ARGS);
|
||||
char *vdev_rt_name(vdev_t *vd, const char *name);
|
||||
|
||||
/*
|
||||
* Vdev ashift optimization tunables
|
||||
|
|
|
|||
|
|
@ -311,6 +311,7 @@ xva_getxoptattr(xvattr_t *xvap)
|
|||
*/
|
||||
#define V_ACE_MASK 0x1 /* mask represents NFSv4 ACE permissions */
|
||||
#define V_APPEND 0x2 /* want to do append only check */
|
||||
#define V_NAMEDATTR 0x4 /* is a named attribute check */
|
||||
|
||||
/*
|
||||
* Structure used on VOP_GETSECATTR and VOP_SETSECATTR operations
|
||||
|
|
|
|||
|
|
@ -204,18 +204,6 @@ extern void vpanic(const char *, va_list)
|
|||
#endif /* DTRACE_PROBE4 */
|
||||
#define DTRACE_PROBE4(a, b, c, d, e, f, g, h, i)
|
||||
|
||||
/*
|
||||
* Tunables.
|
||||
*/
|
||||
typedef struct zfs_kernel_param {
|
||||
const char *name; /* unused stub */
|
||||
} zfs_kernel_param_t;
|
||||
|
||||
#define ZFS_MODULE_PARAM(scope_prefix, name_prefix, name, type, perm, desc)
|
||||
#define ZFS_MODULE_PARAM_ARGS void
|
||||
#define ZFS_MODULE_PARAM_CALL(scope_prefix, name_prefix, name, setfunc, \
|
||||
getfunc, perm, desc)
|
||||
|
||||
/*
|
||||
* Threads.
|
||||
*/
|
||||
|
|
@ -236,6 +224,11 @@ typedef pthread_t kthread_t;
|
|||
#define thread_join(t) pthread_join((pthread_t)(t), NULL)
|
||||
|
||||
#define newproc(f, a, cid, pri, ctp, pid) (ENOSYS)
|
||||
/*
|
||||
* Check if the current thread is a memory reclaim thread.
|
||||
* Always returns false in userspace (no memory reclaim thread).
|
||||
*/
|
||||
#define current_is_reclaim_thread() (0)
|
||||
|
||||
/* in libzpool, p0 exists only to have its address taken */
|
||||
typedef struct proc {
|
||||
|
|
@ -673,7 +666,7 @@ extern void random_fini(void);
|
|||
|
||||
struct spa;
|
||||
extern void show_pool_stats(struct spa *);
|
||||
extern int set_global_var(char const *arg);
|
||||
extern int handle_tunable_option(const char *, boolean_t);
|
||||
|
||||
typedef struct callb_cpr {
|
||||
kmutex_t *cc_lockp;
|
||||
|
|
@ -778,7 +771,6 @@ typedef int fstrans_cookie_t;
|
|||
|
||||
extern fstrans_cookie_t spl_fstrans_mark(void);
|
||||
extern void spl_fstrans_unmark(fstrans_cookie_t);
|
||||
extern int __spl_pf_fstrans_check(void);
|
||||
extern int kmem_cache_reap_active(void);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -202,8 +202,6 @@ typedef struct znode {
|
|||
uint64_t z_size; /* file size (cached) */
|
||||
uint64_t z_pflags; /* pflags (cached) */
|
||||
uint32_t z_sync_cnt; /* synchronous open count */
|
||||
uint32_t z_sync_writes_cnt; /* synchronous write count */
|
||||
uint32_t z_async_writes_cnt; /* asynchronous write count */
|
||||
mode_t z_mode; /* mode (cached) */
|
||||
kmutex_t z_acl_lock; /* acl data lock */
|
||||
zfs_acl_t *z_acl_cached; /* cached acl */
|
||||
|
|
|
|||
|
|
@ -635,6 +635,8 @@ extern void zil_set_logbias(zilog_t *zilog, uint64_t slogval);
|
|||
|
||||
extern uint64_t zil_max_copied_data(zilog_t *zilog);
|
||||
extern uint64_t zil_max_log_data(zilog_t *zilog, size_t hdrsize);
|
||||
extern itx_wr_state_t zil_write_state(zilog_t *zilog, uint64_t size,
|
||||
uint32_t blocksize, boolean_t o_direct, boolean_t commit);
|
||||
|
||||
extern void zil_sums_init(zil_sums_t *zs);
|
||||
extern void zil_sums_fini(zil_sums_t *zs);
|
||||
|
|
@ -642,6 +644,8 @@ extern void zil_kstat_values_update(zil_kstat_values_t *zs,
|
|||
zil_sums_t *zil_sums);
|
||||
|
||||
extern int zil_replay_disable;
|
||||
extern uint_t zfs_immediate_write_sz;
|
||||
extern int zil_special_is_slog;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,21 +59,36 @@ typedef struct zio_eck {
|
|||
|
||||
/*
|
||||
* Gang block headers are self-checksumming and contain an array
|
||||
* of block pointers.
|
||||
* of block pointers. The old gang block size has enough room for 3 blkptrs,
|
||||
* while new gang blocks can store more.
|
||||
*
|
||||
* Layout:
|
||||
* +--------+--------+--------+-----+---------+-----------+
|
||||
* | | | | | | |
|
||||
* | blkptr | blkptr | blkptr | ... | padding | zio_eck_t |
|
||||
* | 1 | 2 | 3 | | | |
|
||||
* +--------+--------+--------+-----+---------+-----------+
|
||||
* 128B 128B 128B 88B 40B
|
||||
*/
|
||||
#define SPA_GANGBLOCKSIZE SPA_MINBLOCKSIZE
|
||||
#define SPA_GBH_NBLKPTRS ((SPA_GANGBLOCKSIZE - \
|
||||
sizeof (zio_eck_t)) / sizeof (blkptr_t))
|
||||
#define SPA_GBH_FILLER ((SPA_GANGBLOCKSIZE - \
|
||||
sizeof (zio_eck_t) - \
|
||||
(SPA_GBH_NBLKPTRS * sizeof (blkptr_t))) /\
|
||||
sizeof (uint64_t))
|
||||
#define SPA_OLD_GANGBLOCKSIZE SPA_MINBLOCKSIZE
|
||||
typedef void zio_gbh_phys_t;
|
||||
|
||||
typedef struct zio_gbh {
|
||||
blkptr_t zg_blkptr[SPA_GBH_NBLKPTRS];
|
||||
uint64_t zg_filler[SPA_GBH_FILLER];
|
||||
zio_eck_t zg_tail;
|
||||
} zio_gbh_phys_t;
|
||||
static inline uint64_t
|
||||
gbh_nblkptrs(uint64_t size) {
|
||||
ASSERT(IS_P2ALIGNED(size, sizeof (blkptr_t)));
|
||||
return ((size - sizeof (zio_eck_t)) / sizeof (blkptr_t));
|
||||
}
|
||||
|
||||
static inline zio_eck_t *
|
||||
gbh_eck(zio_gbh_phys_t *gbh, uint64_t size) {
|
||||
ASSERT(IS_P2ALIGNED(size, sizeof (blkptr_t)));
|
||||
return ((zio_eck_t *)((uintptr_t)gbh + size - sizeof (zio_eck_t)));
|
||||
}
|
||||
|
||||
static inline blkptr_t *
|
||||
gbh_bp(zio_gbh_phys_t *gbh, int bp) {
|
||||
return (&((blkptr_t *)gbh)[bp]);
|
||||
}
|
||||
|
||||
enum zio_checksum {
|
||||
ZIO_CHECKSUM_INHERIT = 0,
|
||||
|
|
@ -196,7 +211,7 @@ typedef uint64_t zio_flag_t;
|
|||
#define ZIO_FLAG_DONT_RETRY (1ULL << 10)
|
||||
#define ZIO_FLAG_NODATA (1ULL << 12)
|
||||
#define ZIO_FLAG_INDUCE_DAMAGE (1ULL << 13)
|
||||
#define ZIO_FLAG_IO_ALLOCATING (1ULL << 14)
|
||||
#define ZIO_FLAG_ALLOC_THROTTLED (1ULL << 14)
|
||||
|
||||
#define ZIO_FLAG_DDT_INHERIT (ZIO_FLAG_IO_RETRY - 1)
|
||||
#define ZIO_FLAG_GANG_INHERIT (ZIO_FLAG_IO_RETRY - 1)
|
||||
|
|
@ -226,8 +241,7 @@ typedef uint64_t zio_flag_t;
|
|||
#define ZIO_FLAG_NOPWRITE (1ULL << 29)
|
||||
#define ZIO_FLAG_REEXECUTED (1ULL << 30)
|
||||
#define ZIO_FLAG_DELEGATED (1ULL << 31)
|
||||
#define ZIO_FLAG_DIO_CHKSUM_ERR (1ULL << 32)
|
||||
#define ZIO_FLAG_PREALLOCATED (1ULL << 33)
|
||||
#define ZIO_FLAG_PREALLOCATED (1ULL << 32)
|
||||
|
||||
#define ZIO_ALLOCATOR_NONE (-1)
|
||||
#define ZIO_HAS_ALLOCATOR(zio) ((zio)->io_allocator != ZIO_ALLOCATOR_NONE)
|
||||
|
|
@ -360,6 +374,7 @@ typedef struct zio_prop {
|
|||
boolean_t zp_encrypt;
|
||||
boolean_t zp_byteorder;
|
||||
boolean_t zp_direct_write;
|
||||
boolean_t zp_rewrite;
|
||||
uint8_t zp_salt[ZIO_DATA_SALT_LEN];
|
||||
uint8_t zp_iv[ZIO_DATA_IV_LEN];
|
||||
uint8_t zp_mac[ZIO_DATA_MAC_LEN];
|
||||
|
|
@ -399,7 +414,9 @@ typedef struct zio_vsd_ops {
|
|||
|
||||
typedef struct zio_gang_node {
|
||||
zio_gbh_phys_t *gn_gbh;
|
||||
struct zio_gang_node *gn_child[SPA_GBH_NBLKPTRS];
|
||||
uint64_t gn_gangblocksize;
|
||||
uint64_t gn_allocsize;
|
||||
struct zio_gang_node *gn_child[];
|
||||
} zio_gang_node_t;
|
||||
|
||||
typedef zio_t *zio_gang_issue_func_t(zio_t *zio, blkptr_t *bp,
|
||||
|
|
@ -418,14 +435,16 @@ typedef struct zio_transform {
|
|||
typedef zio_t *zio_pipe_stage_t(zio_t *zio);
|
||||
|
||||
/*
|
||||
* The io_reexecute flags are distinct from io_flags because the child must
|
||||
* be able to propagate them to the parent. The normal io_flags are local
|
||||
* to the zio, not protected by any lock, and not modifiable by children;
|
||||
* the reexecute flags are protected by io_lock, modifiable by children,
|
||||
* and always propagated -- even when ZIO_FLAG_DONT_PROPAGATE is set.
|
||||
* The io_post flags describe additional actions that a parent IO should
|
||||
* consider or perform on behalf of a child. They are distinct from io_flags
|
||||
* because the child must be able to propagate them to the parent. The normal
|
||||
* io_flags are local to the zio, not protected by any lock, and not modifiable
|
||||
* by children; the reexecute flags are protected by io_lock, modifiable by
|
||||
* children, and always propagated -- even when ZIO_FLAG_DONT_PROPAGATE is set.
|
||||
*/
|
||||
#define ZIO_REEXECUTE_NOW 0x01
|
||||
#define ZIO_REEXECUTE_SUSPEND 0x02
|
||||
#define ZIO_POST_REEXECUTE (1 << 0)
|
||||
#define ZIO_POST_SUSPEND (1 << 1)
|
||||
#define ZIO_POST_DIO_CHKSUM_ERR (1 << 2)
|
||||
|
||||
/*
|
||||
* The io_trim flags are used to specify the type of TRIM to perform. They
|
||||
|
|
@ -461,7 +480,7 @@ struct zio {
|
|||
enum zio_child io_child_type;
|
||||
enum trim_flag io_trim_flags;
|
||||
zio_priority_t io_priority;
|
||||
uint8_t io_reexecute;
|
||||
uint8_t io_post;
|
||||
uint8_t io_state[ZIO_WAIT_TYPES];
|
||||
uint64_t io_txg;
|
||||
spa_t *io_spa;
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@
|
|||
#define SPEC_MAXOFFSET_T ((1LL << ((NBBY * sizeof (daddr32_t)) + \
|
||||
DEV_BSHIFT - 1)) - 1)
|
||||
|
||||
extern void zvol_create_minor(const char *);
|
||||
extern void zvol_create_minors_recursive(const char *);
|
||||
extern void zvol_create_minors(const char *);
|
||||
extern void zvol_remove_minors(spa_t *, const char *, boolean_t);
|
||||
extern void zvol_rename_minors(spa_t *, const char *, const char *, boolean_t);
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,6 @@ zvol_state_t *zvol_find_by_name_hash(const char *name,
|
|||
uint64_t hash, int mode);
|
||||
int zvol_first_open(zvol_state_t *zv, boolean_t readonly);
|
||||
uint64_t zvol_name_hash(const char *name);
|
||||
void zvol_remove_minors_impl(const char *name);
|
||||
void zvol_last_close(zvol_state_t *zv);
|
||||
void zvol_insert(zvol_state_t *zv);
|
||||
void zvol_log_truncate(zvol_state_t *zv, dmu_tx_t *tx, uint64_t off,
|
||||
|
|
@ -132,7 +131,7 @@ void zv_request_task_free(zv_request_task_t *task);
|
|||
* platform dependent functions exported to platform independent code
|
||||
*/
|
||||
void zvol_os_free(zvol_state_t *zv);
|
||||
void zvol_os_rename_minor(zvol_state_t *zv, const char *newname);
|
||||
int zvol_os_rename_minor(zvol_state_t *zv, const char *newname);
|
||||
int zvol_os_create_minor(const char *name);
|
||||
int zvol_os_update_volsize(zvol_state_t *zv, uint64_t volsize);
|
||||
boolean_t zvol_os_is_zvol(const char *path);
|
||||
|
|
|
|||
|
|
@ -87,6 +87,9 @@ typedef enum spa_feature {
|
|||
SPA_FEATURE_FAST_DEDUP,
|
||||
SPA_FEATURE_LONGNAME,
|
||||
SPA_FEATURE_LARGE_MICROZAP,
|
||||
SPA_FEATURE_DYNAMIC_GANG_HEADER,
|
||||
SPA_FEATURE_BLOCK_CLONING_ENDIAN,
|
||||
SPA_FEATURE_PHYSICAL_REWRITE,
|
||||
SPA_FEATURES
|
||||
} spa_feature_t;
|
||||
|
||||
|
|
@ -103,7 +106,15 @@ typedef enum zfeature_flags {
|
|||
/* Activate this feature at the same time it is enabled. */
|
||||
ZFEATURE_FLAG_ACTIVATE_ON_ENABLE = (1 << 2),
|
||||
/* Each dataset has a field set if it has ever used this feature. */
|
||||
ZFEATURE_FLAG_PER_DATASET = (1 << 3)
|
||||
ZFEATURE_FLAG_PER_DATASET = (1 << 3),
|
||||
/*
|
||||
* This feature isn't enabled by zpool upgrade; it must be explicitly
|
||||
* listed to be enabled. It will also be applied if listed in an
|
||||
* explicitly provided compatibility list. This flag can be removed
|
||||
* from a given feature once support is sufficiently widespread, or
|
||||
* worries about backwards compatibility are no longer relevant.
|
||||
*/
|
||||
ZFEATURE_FLAG_NO_UPGRADE = (1 << 4)
|
||||
} zfeature_flags_t;
|
||||
|
||||
typedef enum zfeature_type {
|
||||
|
|
|
|||
75
sys/contrib/openzfs/include/zfs_crrd.h
Normal file
75
sys/contrib/openzfs/include/zfs_crrd.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
// 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) 2024 Klara Inc.
|
||||
*
|
||||
* This software was developed by
|
||||
* Mariusz Zaborski <mariusz.zaborski@klarasystems.com>
|
||||
* Fred Weigel <fred.weigel@klarasystems.com>
|
||||
* under sponsorship from Wasabi Technology, Inc. and Klara Inc.
|
||||
*/
|
||||
|
||||
#ifndef _CRRD_H_
|
||||
#define _CRRD_H_
|
||||
|
||||
#define RRD_MAX_ENTRIES 256
|
||||
|
||||
#define RRD_ENTRY_SIZE sizeof (uint64_t)
|
||||
#define RRD_STRUCT_ELEM (sizeof (rrd_t) / RRD_ENTRY_SIZE)
|
||||
|
||||
typedef enum {
|
||||
DBRRD_FLOOR,
|
||||
DBRRD_CEILING
|
||||
} dbrrd_rounding_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t rrdd_time;
|
||||
uint64_t rrdd_txg;
|
||||
} rrd_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t rrd_head; /* head (beginning) */
|
||||
uint64_t rrd_tail; /* tail (end) */
|
||||
uint64_t rrd_length;
|
||||
|
||||
rrd_data_t rrd_entries[RRD_MAX_ENTRIES];
|
||||
} rrd_t;
|
||||
|
||||
typedef struct {
|
||||
rrd_t dbr_minutes;
|
||||
rrd_t dbr_days;
|
||||
rrd_t dbr_months;
|
||||
} dbrrd_t;
|
||||
|
||||
size_t rrd_len(rrd_t *rrd);
|
||||
|
||||
const rrd_data_t *rrd_entry(rrd_t *r, size_t i);
|
||||
rrd_data_t *rrd_tail_entry(rrd_t *rrd);
|
||||
uint64_t rrd_tail(rrd_t *rrd);
|
||||
uint64_t rrd_get(rrd_t *rrd, size_t i);
|
||||
|
||||
void rrd_add(rrd_t *rrd, hrtime_t time, uint64_t txg);
|
||||
|
||||
void dbrrd_add(dbrrd_t *db, hrtime_t time, uint64_t txg);
|
||||
uint64_t dbrrd_query(dbrrd_t *r, hrtime_t tv, dbrrd_rounding_t rouding);
|
||||
|
||||
#endif
|
||||
|
|
@ -20,6 +20,7 @@ libspl_la_SOURCES = \
|
|||
%D%/strlcat.c \
|
||||
%D%/strlcpy.c \
|
||||
%D%/timestamp.c \
|
||||
%D%/tunables.c \
|
||||
%D%/include/sys/list.h \
|
||||
%D%/include/sys/list_impl.h
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ libspl_sys_HEADERS = \
|
|||
%D%/sys/list_impl.h \
|
||||
%D%/sys/mhd.h \
|
||||
%D%/sys/mkdev.h \
|
||||
%D%/sys/mod.h \
|
||||
%D%/sys/policy.h \
|
||||
%D%/sys/poll.h \
|
||||
%D%/sys/priv.h \
|
||||
|
|
@ -58,6 +59,7 @@ libspl_sys_HEADERS = \
|
|||
%D%/sys/time.h \
|
||||
%D%/sys/trace_spl.h \
|
||||
%D%/sys/trace_zfs.h \
|
||||
%D%/sys/tunables.h \
|
||||
%D%/sys/types.h \
|
||||
%D%/sys/types32.h \
|
||||
%D%/sys/uio.h \
|
||||
|
|
|
|||
|
|
@ -31,6 +31,11 @@
|
|||
|
||||
#include <sys/mount.h> /* for BLKGETSIZE64 */
|
||||
|
||||
#ifdef HAVE_STATX
|
||||
#include <fcntl.h>
|
||||
#include <linux/stat.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Emulate Solaris' behavior of returning the block device size in fstat64().
|
||||
*/
|
||||
|
|
|
|||
56
sys/contrib/openzfs/lib/libspl/include/sys/mod.h
Normal file
56
sys/contrib/openzfs/lib/libspl/include/sys/mod.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
// 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 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
* Copyright (c) 2025, Rob Norris <robn@despairlabs.com>
|
||||
*/
|
||||
|
||||
#ifndef _SYS_MOD_H
|
||||
#define _SYS_MOD_H
|
||||
|
||||
#include <sys/tunables.h>
|
||||
|
||||
#define ZFS_MODULE_PARAM(scope, prefix, name, type, perm, desc) \
|
||||
static const zfs_tunable_t _zfs_tunable_##prefix##name = { \
|
||||
.zt_name = #prefix#name, \
|
||||
.zt_varp = &prefix##name, \
|
||||
.zt_varsz = sizeof (prefix##name), \
|
||||
.zt_type = ZFS_TUNABLE_TYPE_##type, \
|
||||
.zt_perm = ZFS_TUNABLE_PERM_##perm, \
|
||||
.zt_desc = desc \
|
||||
}; \
|
||||
static const zfs_tunable_t * \
|
||||
__zfs_tunable_##prefix##name \
|
||||
__attribute__((__section__("zfs_tunables"))) \
|
||||
__attribute__((__used__)) \
|
||||
= &_zfs_tunable_##prefix##name;
|
||||
|
||||
#define ZFS_MODULE_PARAM_ARGS void
|
||||
#define ZFS_MODULE_PARAM_CALL(scope_prefix, name_prefix, name, setfunc, \
|
||||
getfunc, perm, desc)
|
||||
|
||||
#define EXPORT_SYMBOL(x)
|
||||
|
||||
#endif
|
||||
60
sys/contrib/openzfs/lib/libspl/include/sys/tunables.h
Normal file
60
sys/contrib/openzfs/lib/libspl/include/sys/tunables.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
// 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) 2025, Rob Norris <robn@despairlabs.com>
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TUNABLES_H
|
||||
#define _SYS_TUNABLES_H
|
||||
|
||||
typedef enum {
|
||||
ZFS_TUNABLE_TYPE_INT,
|
||||
ZFS_TUNABLE_TYPE_UINT,
|
||||
ZFS_TUNABLE_TYPE_ULONG,
|
||||
ZFS_TUNABLE_TYPE_U64,
|
||||
ZFS_TUNABLE_TYPE_STRING,
|
||||
} zfs_tunable_type_t;
|
||||
|
||||
typedef enum {
|
||||
ZFS_TUNABLE_PERM_ZMOD_RW,
|
||||
ZFS_TUNABLE_PERM_ZMOD_RD,
|
||||
} zfs_tunable_perm_t;
|
||||
|
||||
typedef struct zfs_tunable {
|
||||
const char *zt_name;
|
||||
void *zt_varp;
|
||||
size_t zt_varsz;
|
||||
zfs_tunable_type_t zt_type;
|
||||
zfs_tunable_perm_t zt_perm;
|
||||
const char *zt_desc;
|
||||
} zfs_tunable_t;
|
||||
|
||||
int zfs_tunable_set(const zfs_tunable_t *tunable, const char *val);
|
||||
int zfs_tunable_get(const zfs_tunable_t *tunable, char *val, size_t valsz);
|
||||
|
||||
const zfs_tunable_t *zfs_tunable_lookup(const char *name);
|
||||
|
||||
typedef int (*zfs_tunable_iter_t)(const zfs_tunable_t *tunable, void *arg);
|
||||
void zfs_tunable_iter(zfs_tunable_iter_t cb, void *arg);
|
||||
|
||||
#endif
|
||||
|
|
@ -102,7 +102,7 @@ static inline void *
|
|||
umem_alloc_aligned(size_t size, size_t align, int flags)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
int rc = EINVAL;
|
||||
int rc;
|
||||
|
||||
do {
|
||||
rc = posix_memalign(&ptr, align, size);
|
||||
|
|
|
|||
|
|
@ -85,13 +85,21 @@ _sol_getmntent(FILE *fp, struct mnttab *mgetp)
|
|||
}
|
||||
|
||||
static int
|
||||
getextmntent_impl(FILE *fp, struct extmnttab *mp)
|
||||
getextmntent_impl(FILE *fp, struct extmnttab *mp, uint64_t *mnt_id)
|
||||
{
|
||||
int ret;
|
||||
struct stat64 st;
|
||||
|
||||
*mnt_id = 0;
|
||||
ret = _sol_getmntent(fp, (struct mnttab *)mp);
|
||||
if (ret == 0) {
|
||||
#ifdef HAVE_STATX_MNT_ID
|
||||
struct statx stx;
|
||||
if (statx(AT_FDCWD, mp->mnt_mountp,
|
||||
AT_STATX_SYNC_AS_STAT | AT_SYMLINK_NOFOLLOW,
|
||||
STATX_MNT_ID, &stx) == 0 && (stx.stx_mask & STATX_MNT_ID))
|
||||
*mnt_id = stx.stx_mnt_id;
|
||||
#endif
|
||||
if (stat64(mp->mnt_mountp, &st) != 0) {
|
||||
mp->mnt_major = 0;
|
||||
mp->mnt_minor = 0;
|
||||
|
|
@ -110,6 +118,12 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
|
|||
struct stat64 st;
|
||||
FILE *fp;
|
||||
int match;
|
||||
boolean_t have_mnt_id = B_FALSE;
|
||||
uint64_t target_mnt_id = 0;
|
||||
uint64_t entry_mnt_id;
|
||||
#ifdef HAVE_STATX_MNT_ID
|
||||
struct statx stx;
|
||||
#endif
|
||||
|
||||
if (strlen(path) >= MAXPATHLEN) {
|
||||
(void) fprintf(stderr, "invalid object; pathname too long\n");
|
||||
|
|
@ -128,6 +142,13 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
|
|||
return (-1);
|
||||
}
|
||||
|
||||
#ifdef HAVE_STATX_MNT_ID
|
||||
if (statx(AT_FDCWD, path, AT_STATX_SYNC_AS_STAT | AT_SYMLINK_NOFOLLOW,
|
||||
STATX_MNT_ID, &stx) == 0 && (stx.stx_mask & STATX_MNT_ID)) {
|
||||
have_mnt_id = B_TRUE;
|
||||
target_mnt_id = stx.stx_mnt_id;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((fp = fopen(MNTTAB, "re")) == NULL) {
|
||||
(void) fprintf(stderr, "cannot open %s\n", MNTTAB);
|
||||
|
|
@ -139,12 +160,15 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
|
|||
*/
|
||||
|
||||
match = 0;
|
||||
while (getextmntent_impl(fp, entry) == 0) {
|
||||
if (makedev(entry->mnt_major, entry->mnt_minor) ==
|
||||
statbuf->st_dev) {
|
||||
match = 1;
|
||||
break;
|
||||
while (getextmntent_impl(fp, entry, &entry_mnt_id) == 0) {
|
||||
if (have_mnt_id) {
|
||||
match = (entry_mnt_id == target_mnt_id);
|
||||
} else {
|
||||
match = makedev(entry->mnt_major, entry->mnt_minor) ==
|
||||
statbuf->st_dev;
|
||||
}
|
||||
if (match)
|
||||
break;
|
||||
}
|
||||
(void) fclose(fp);
|
||||
|
||||
|
|
|
|||
319
sys/contrib/openzfs/lib/libspl/tunables.c
Normal file
319
sys/contrib/openzfs/lib/libspl/tunables.c
Normal file
|
|
@ -0,0 +1,319 @@
|
|||
// 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) 2025, Rob Norris <robn@despairlabs.com>
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/tunables.h>
|
||||
|
||||
/*
|
||||
* Userspace tunables.
|
||||
*
|
||||
* Tunables are external pointers to global variables that are wired up to the
|
||||
* host environment in some way that allows the operator to directly change
|
||||
* their values "under the hood".
|
||||
*
|
||||
* In userspace, the "host environment" is the program using libzpool.so. So
|
||||
* that it can manipulate tunables if it wants, we provide an API to access
|
||||
* them.
|
||||
*
|
||||
* Tunables are declared through the ZFS_MODULE_PARAM* macros, which associate
|
||||
* a global variable with some metadata we can use to describe and access the
|
||||
* tunable. This is done by creating a uniquely-named zfs_tunable_t.
|
||||
*
|
||||
* At runtime, we need a way to discover these zfs_tunable_t items. Since they
|
||||
* are declared globally, all over the codebase, there's no central place to
|
||||
* record or list them. So, we take advantage of the compiler's "linker set"
|
||||
* feature.
|
||||
*
|
||||
* In the ZFS_MODULE_PARAM macro, after we create the zfs_tunable_t, we also
|
||||
* create a zfs_tunable_t* pointing to it. That pointer is forced into the
|
||||
* "zfs_tunables" ELF section in compiled object. At link time, the linker will
|
||||
* collect all these pointers into one single big "zfs_tunable" section, and
|
||||
* will generate two new symbols in the final object: __start_zfs_tunable and
|
||||
* __stop_zfs_tunable. These point to the first and last item in that section,
|
||||
* which allows us to access the pointers in that section like an array, and
|
||||
* through those pointers access the tunable metadata, and from there the
|
||||
* actual C variable that the tunable describes.
|
||||
*/
|
||||
|
||||
extern const zfs_tunable_t *__start_zfs_tunables;
|
||||
extern const zfs_tunable_t *__stop_zfs_tunables;
|
||||
|
||||
/*
|
||||
* Because there are no tunables in libspl itself, the above symbols will not
|
||||
* be generated, which will stop libspl being linked at all. To work around
|
||||
* that, we force a symbol into that section, and then when iterating, skip
|
||||
* any NULL pointers.
|
||||
*/
|
||||
static void *__zfs_tunable__placeholder
|
||||
__attribute__((__section__("zfs_tunables")))
|
||||
__attribute__((__used__)) = NULL;
|
||||
|
||||
/*
|
||||
* Find the name tunable by walking through the linker set and comparing names,
|
||||
* as described above. This is not particularly efficient but it's a fairly
|
||||
* rare task, so it shouldn't be a big deal.
|
||||
*/
|
||||
const zfs_tunable_t *
|
||||
zfs_tunable_lookup(const char *name)
|
||||
{
|
||||
for (const zfs_tunable_t **ztp = &__start_zfs_tunables;
|
||||
ztp != &__stop_zfs_tunables; ztp++) {
|
||||
const zfs_tunable_t *zt = *ztp;
|
||||
if (zt == NULL)
|
||||
continue;
|
||||
if (strcmp(name, zt->zt_name) == 0)
|
||||
return (zt);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Like zfs_tunable_lookup, but call the provided callback for each tunable.
|
||||
*/
|
||||
void
|
||||
zfs_tunable_iter(zfs_tunable_iter_t cb, void *arg)
|
||||
{
|
||||
for (const zfs_tunable_t **ztp = &__start_zfs_tunables;
|
||||
ztp != &__stop_zfs_tunables; ztp++) {
|
||||
const zfs_tunable_t *zt = *ztp;
|
||||
if (zt == NULL)
|
||||
continue;
|
||||
if (cb(zt, arg))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a string into an int or uint. It's easier to have a pair of "generic"
|
||||
* functions that clamp to a given min and max rather than have multiple
|
||||
* functions for each width of type.
|
||||
*/
|
||||
static int
|
||||
zfs_tunable_parse_int(const char *val, intmax_t *np,
|
||||
intmax_t min, intmax_t max)
|
||||
{
|
||||
intmax_t n;
|
||||
char *end;
|
||||
errno = 0;
|
||||
n = strtoimax(val, &end, 0);
|
||||
if (errno != 0)
|
||||
return (errno);
|
||||
if (*end != '\0')
|
||||
return (EINVAL);
|
||||
if (n < min || n > max)
|
||||
return (ERANGE);
|
||||
*np = n;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_tunable_parse_uint(const char *val, uintmax_t *np,
|
||||
uintmax_t min, uintmax_t max)
|
||||
{
|
||||
uintmax_t n;
|
||||
char *end;
|
||||
errno = 0;
|
||||
n = strtoumax(val, &end, 0);
|
||||
if (errno != 0)
|
||||
return (errno);
|
||||
if (*end != '\0')
|
||||
return (EINVAL);
|
||||
if (strchr(val, '-'))
|
||||
return (ERANGE);
|
||||
if (n < min || n > max)
|
||||
return (ERANGE);
|
||||
*np = n;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set helpers for each tunable type. Parses the string, and if produces a
|
||||
* valid value for the tunable, sets it. No effort is made to make sure the
|
||||
* tunable is of the right type; that's done in zfs_tunable_set() below.
|
||||
*/
|
||||
static int
|
||||
zfs_tunable_set_int(const zfs_tunable_t *zt, const char *val)
|
||||
{
|
||||
intmax_t n;
|
||||
int err = zfs_tunable_parse_int(val, &n, INT_MIN, INT_MAX);
|
||||
if (err != 0)
|
||||
return (err);
|
||||
*(int *)zt->zt_varp = n;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_tunable_set_uint(const zfs_tunable_t *zt, const char *val)
|
||||
{
|
||||
uintmax_t n;
|
||||
int err = zfs_tunable_parse_uint(val, &n, 0, UINT_MAX);
|
||||
if (err != 0)
|
||||
return (err);
|
||||
*(unsigned int *)zt->zt_varp = n;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_tunable_set_ulong(const zfs_tunable_t *zt, const char *val)
|
||||
{
|
||||
uintmax_t n;
|
||||
int err = zfs_tunable_parse_uint(val, &n, 0, ULONG_MAX);
|
||||
if (err != 0)
|
||||
return (err);
|
||||
*(unsigned long *)zt->zt_varp = n;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_tunable_set_u64(const zfs_tunable_t *zt, const char *val)
|
||||
{
|
||||
uintmax_t n;
|
||||
int err = zfs_tunable_parse_uint(val, &n, 0, UINT64_MAX);
|
||||
if (err != 0)
|
||||
return (err);
|
||||
*(uint64_t *)zt->zt_varp = n;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_tunable_set_string(const zfs_tunable_t *zt, const char *val)
|
||||
{
|
||||
(void) zt, (void) val;
|
||||
/*
|
||||
* We can't currently handle strings. String tunables are pointers
|
||||
* into read-only memory, so we can update the pointer, but not the
|
||||
* contents. That would mean taking an allocation, but we don't have
|
||||
* an obvious place to free it.
|
||||
*
|
||||
* For now, it's no big deal as there's only a couple of string
|
||||
* tunables anyway.
|
||||
*/
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get helpers for each tunable type. Converts the value to a string if
|
||||
* necessary and writes it into the provided buffer. The type is assumed to
|
||||
* be correct; zfs_tunable_get() below will call the correct function for the
|
||||
* type.
|
||||
*/
|
||||
static int
|
||||
zfs_tunable_get_int(const zfs_tunable_t *zt, char *val, size_t valsz)
|
||||
{
|
||||
snprintf(val, valsz, "%d", *(int *)zt->zt_varp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_tunable_get_uint(const zfs_tunable_t *zt, char *val, size_t valsz)
|
||||
{
|
||||
snprintf(val, valsz, "%u", *(unsigned int *)zt->zt_varp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_tunable_get_ulong(const zfs_tunable_t *zt, char *val, size_t valsz)
|
||||
{
|
||||
snprintf(val, valsz, "%lu", *(unsigned long *)zt->zt_varp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_tunable_get_u64(const zfs_tunable_t *zt, char *val, size_t valsz)
|
||||
{
|
||||
snprintf(val, valsz, "%"PRIu64, *(uint64_t *)zt->zt_varp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_tunable_get_string(const zfs_tunable_t *zt, char *val, size_t valsz)
|
||||
{
|
||||
strlcpy(val, *(char **)zt->zt_varp, valsz);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* The public set function. Delegates to the type-specific version. */
|
||||
int
|
||||
zfs_tunable_set(const zfs_tunable_t *zt, const char *val)
|
||||
{
|
||||
int err;
|
||||
switch (zt->zt_type) {
|
||||
case ZFS_TUNABLE_TYPE_INT:
|
||||
err = zfs_tunable_set_int(zt, val);
|
||||
break;
|
||||
case ZFS_TUNABLE_TYPE_UINT:
|
||||
err = zfs_tunable_set_uint(zt, val);
|
||||
break;
|
||||
case ZFS_TUNABLE_TYPE_ULONG:
|
||||
err = zfs_tunable_set_ulong(zt, val);
|
||||
break;
|
||||
case ZFS_TUNABLE_TYPE_U64:
|
||||
err = zfs_tunable_set_u64(zt, val);
|
||||
break;
|
||||
case ZFS_TUNABLE_TYPE_STRING:
|
||||
err = zfs_tunable_set_string(zt, val);
|
||||
break;
|
||||
default:
|
||||
err = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
|
||||
/* The public get function. Delegates to the type-specific version. */
|
||||
int
|
||||
zfs_tunable_get(const zfs_tunable_t *zt, char *val, size_t valsz)
|
||||
{
|
||||
int err;
|
||||
switch (zt->zt_type) {
|
||||
case ZFS_TUNABLE_TYPE_INT:
|
||||
err = zfs_tunable_get_int(zt, val, valsz);
|
||||
break;
|
||||
case ZFS_TUNABLE_TYPE_UINT:
|
||||
err = zfs_tunable_get_uint(zt, val, valsz);
|
||||
break;
|
||||
case ZFS_TUNABLE_TYPE_ULONG:
|
||||
err = zfs_tunable_get_ulong(zt, val, valsz);
|
||||
break;
|
||||
case ZFS_TUNABLE_TYPE_U64:
|
||||
err = zfs_tunable_get_u64(zt, val, valsz);
|
||||
break;
|
||||
case ZFS_TUNABLE_TYPE_STRING:
|
||||
err = zfs_tunable_get_string(zt, val, valsz);
|
||||
break;
|
||||
default:
|
||||
err = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
|
|
@ -244,6 +244,10 @@
|
|||
<elf-symbol name='uu_strerror' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='uu_strndup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='uu_zalloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_tunable_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_tunable_iter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_tunable_lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_tunable_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
</elf-function-symbols>
|
||||
<abi-instr address-size='64' path='lib/libspl/assert.c' language='LANG_C99'>
|
||||
<typedef-decl name='__pid_t' type-id='95e97e5e' id='3629bad8'/>
|
||||
|
|
@ -612,7 +616,6 @@
|
|||
<array-type-def dimensions='1' type-id='de572c22' size-in-bits='1472' id='6d3c2f42'>
|
||||
<subrange length='23' type-id='7359adad' id='fdd0f594'/>
|
||||
</array-type-def>
|
||||
<type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/>
|
||||
<array-type-def dimensions='1' type-id='3a47d82b' size-in-bits='256' id='a133ec23'>
|
||||
<subrange length='4' type-id='7359adad' id='16fe7105'/>
|
||||
</array-type-def>
|
||||
|
|
@ -978,8 +981,6 @@
|
|||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/os/linux/gethostid.c' language='LANG_C99'>
|
||||
<type-decl name='long long unsigned int' size-in-bits='64' id='3a47d82b'/>
|
||||
<pointer-type-def type-id='26a90f95' size-in-bits='64' id='9b23c9ad'/>
|
||||
<qualified-type-def type-id='9b23c9ad' restrict='yes' id='8c85230f'/>
|
||||
<function-decl name='fclose' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='822cd80b'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
|
|
@ -1019,6 +1020,13 @@
|
|||
<array-type-def dimensions='1' type-id='03085adc' size-in-bits='192' id='083f8d58'>
|
||||
<subrange length='3' type-id='7359adad' id='56f209d2'/>
|
||||
</array-type-def>
|
||||
<array-type-def dimensions='1' type-id='d315442e' size-in-bits='16' id='811205dc'>
|
||||
<subrange length='1' type-id='7359adad' id='52f813b4'/>
|
||||
</array-type-def>
|
||||
<array-type-def dimensions='1' type-id='d3130597' size-in-bits='768' id='f63f23b9'>
|
||||
<subrange length='12' type-id='7359adad' id='84827bdc'/>
|
||||
</array-type-def>
|
||||
<type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/>
|
||||
<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'/>
|
||||
|
|
@ -1053,6 +1061,93 @@
|
|||
<var-decl name='mnt_minor' type-id='3502e3ff' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='__u16' type-id='8efea9e5' id='d315442e'/>
|
||||
<typedef-decl name='__s32' type-id='95e97e5e' id='3158a266'/>
|
||||
<typedef-decl name='__u32' type-id='f0981eeb' id='3f1a6b60'/>
|
||||
<typedef-decl name='__s64' type-id='1eb56b1e' id='49659421'/>
|
||||
<typedef-decl name='__u64' type-id='3a47d82b' id='d3130597'/>
|
||||
<class-decl name='statx_timestamp' size-in-bits='128' is-struct='yes' visibility='default' id='94101016'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='tv_sec' type-id='49659421' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='tv_nsec' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='96'>
|
||||
<var-decl name='__reserved' type-id='3158a266' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='statx' size-in-bits='2048' is-struct='yes' visibility='default' id='720b04c5'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='stx_mask' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='32'>
|
||||
<var-decl name='stx_blksize' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='stx_attributes' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<var-decl name='stx_nlink' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='160'>
|
||||
<var-decl name='stx_uid' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='192'>
|
||||
<var-decl name='stx_gid' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='224'>
|
||||
<var-decl name='stx_mode' type-id='d315442e' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='240'>
|
||||
<var-decl name='__spare0' type-id='811205dc' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='256'>
|
||||
<var-decl name='stx_ino' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='320'>
|
||||
<var-decl name='stx_size' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='384'>
|
||||
<var-decl name='stx_blocks' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='448'>
|
||||
<var-decl name='stx_attributes_mask' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='512'>
|
||||
<var-decl name='stx_atime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='640'>
|
||||
<var-decl name='stx_btime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='768'>
|
||||
<var-decl name='stx_ctime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='896'>
|
||||
<var-decl name='stx_mtime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1024'>
|
||||
<var-decl name='stx_rdev_major' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1056'>
|
||||
<var-decl name='stx_rdev_minor' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1088'>
|
||||
<var-decl name='stx_dev_major' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1120'>
|
||||
<var-decl name='stx_dev_minor' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1152'>
|
||||
<var-decl name='stx_mnt_id' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1216'>
|
||||
<var-decl name='__spare2' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1280'>
|
||||
<var-decl name='__spare3' type-id='f63f23b9' 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'/>
|
||||
|
|
@ -1142,6 +1237,8 @@
|
|||
<pointer-type-def type-id='1b055409' size-in-bits='64' id='9d424d31'/>
|
||||
<pointer-type-def type-id='0bbec9cd' size-in-bits='64' id='62f7a03d'/>
|
||||
<qualified-type-def type-id='62f7a03d' restrict='yes' id='f1cadedf'/>
|
||||
<pointer-type-def type-id='720b04c5' size-in-bits='64' id='936b8e35'/>
|
||||
<qualified-type-def type-id='936b8e35' restrict='yes' id='31d265b7'/>
|
||||
<function-decl name='getmntent_r' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='e75a27e9'/>
|
||||
<parameter type-id='3cad23cd'/>
|
||||
|
|
@ -1157,6 +1254,14 @@
|
|||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='26a90f95'/>
|
||||
</function-decl>
|
||||
<function-decl name='statx' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='f0981eeb'/>
|
||||
<parameter type-id='31d265b7'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='__fprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='e75a27e9'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
|
|
@ -1307,6 +1412,91 @@
|
|||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/tunables.c' language='LANG_C99'>
|
||||
<enum-decl name='zfs_tunable_type_t' naming-typedef-id='f50b1525' id='56905369'>
|
||||
<underlying-type type-id='9cac1fee'/>
|
||||
<enumerator name='ZFS_TUNABLE_TYPE_INT' value='0'/>
|
||||
<enumerator name='ZFS_TUNABLE_TYPE_UINT' value='1'/>
|
||||
<enumerator name='ZFS_TUNABLE_TYPE_ULONG' value='2'/>
|
||||
<enumerator name='ZFS_TUNABLE_TYPE_U64' value='3'/>
|
||||
<enumerator name='ZFS_TUNABLE_TYPE_STRING' value='4'/>
|
||||
</enum-decl>
|
||||
<typedef-decl name='zfs_tunable_type_t' type-id='56905369' id='f50b1525'/>
|
||||
<enum-decl name='zfs_tunable_perm_t' naming-typedef-id='ada7336b' id='e80e6ebf'>
|
||||
<underlying-type type-id='9cac1fee'/>
|
||||
<enumerator name='ZFS_TUNABLE_PERM_ZMOD_RW' value='0'/>
|
||||
<enumerator name='ZFS_TUNABLE_PERM_ZMOD_RD' value='1'/>
|
||||
</enum-decl>
|
||||
<typedef-decl name='zfs_tunable_perm_t' type-id='e80e6ebf' id='ada7336b'/>
|
||||
<class-decl name='zfs_tunable' size-in-bits='320' is-struct='yes' visibility='default' id='1a97ee0e'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='zt_name' type-id='80f4b756' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='zt_varp' type-id='eaa32e2f' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<var-decl name='zt_varsz' type-id='b59d7dce' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='192'>
|
||||
<var-decl name='zt_type' type-id='f50b1525' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='224'>
|
||||
<var-decl name='zt_perm' type-id='ada7336b' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='256'>
|
||||
<var-decl name='zt_desc' type-id='80f4b756' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='zfs_tunable_t' type-id='1a97ee0e' id='12bf5c5e'/>
|
||||
<typedef-decl name='zfs_tunable_iter_t' type-id='7ef33f92' id='d8d5f4ab'/>
|
||||
<typedef-decl name='intmax_t' type-id='5b475db0' id='e104d842'/>
|
||||
<typedef-decl name='uintmax_t' type-id='04d82f4b' id='f8b828c9'/>
|
||||
<typedef-decl name='__intmax_t' type-id='bd54fe1a' id='5b475db0'/>
|
||||
<typedef-decl name='__uintmax_t' type-id='7359adad' id='04d82f4b'/>
|
||||
<pointer-type-def type-id='26a90f95' size-in-bits='64' id='9b23c9ad'/>
|
||||
<qualified-type-def type-id='9b23c9ad' restrict='yes' id='8c85230f'/>
|
||||
<qualified-type-def type-id='12bf5c5e' const='yes' id='180e47ee'/>
|
||||
<pointer-type-def type-id='180e47ee' size-in-bits='64' id='a27af98c'/>
|
||||
<pointer-type-def type-id='92f86508' size-in-bits='64' id='7ef33f92'/>
|
||||
<function-decl name='strtoimax' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='8c85230f'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='e104d842'/>
|
||||
</function-decl>
|
||||
<function-decl name='strtoumax' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='8c85230f'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='f8b828c9'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_tunable_lookup' mangled-name='zfs_tunable_lookup' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_lookup'>
|
||||
<parameter type-id='80f4b756' name='name'/>
|
||||
<return type-id='a27af98c'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_tunable_iter' mangled-name='zfs_tunable_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_iter'>
|
||||
<parameter type-id='d8d5f4ab' name='cb'/>
|
||||
<parameter type-id='eaa32e2f' name='arg'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_tunable_set' mangled-name='zfs_tunable_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_set'>
|
||||
<parameter type-id='a27af98c' name='zt'/>
|
||||
<parameter type-id='80f4b756' name='val'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_tunable_get' mangled-name='zfs_tunable_get' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_get'>
|
||||
<parameter type-id='a27af98c' name='zt'/>
|
||||
<parameter type-id='26a90f95' name='val'/>
|
||||
<parameter type-id='b59d7dce' name='valsz'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-type size-in-bits='64' id='92f86508'>
|
||||
<parameter type-id='a27af98c'/>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-type>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libuutil/uu_alloc.c' language='LANG_C99'>
|
||||
<type-decl name='char' size-in-bits='8' id='a84c031d'/>
|
||||
<type-decl name='unsigned int' size-in-bits='32' id='f0981eeb'/>
|
||||
|
|
|
|||
|
|
@ -93,9 +93,9 @@ livelist_compare(const void *larg, const void *rarg)
|
|||
* 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_LOGICAL_BIRTH(l) < BP_GET_LOGICAL_BIRTH(r)) {
|
||||
if (BP_GET_BIRTH(l) < BP_GET_BIRTH(r)) {
|
||||
return (-1);
|
||||
} else if (BP_GET_LOGICAL_BIRTH(l) > BP_GET_LOGICAL_BIRTH(r)) {
|
||||
} else if (BP_GET_BIRTH(l) > BP_GET_BIRTH(r)) {
|
||||
return (+1);
|
||||
}
|
||||
return (0);
|
||||
|
|
|
|||
|
|
@ -451,6 +451,10 @@
|
|||
<elf-symbol name='zfs_strip_partition' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_strip_path' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_truncate_shares' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_tunable_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_tunable_iter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_tunable_lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_tunable_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_type_to_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_unmount' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_unmountall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
|
|
@ -479,6 +483,7 @@
|
|||
<elf-symbol name='zpool_clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_clear_label' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_close' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_collect_leaves' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_collect_unsup_feat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_ddt_prune' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
|
|
@ -528,6 +533,7 @@
|
|||
<elf-symbol name='zpool_import_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_in_use' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_initialize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_initialize_one' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_initialize_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_is_draid_spare' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_iter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
|
|
@ -568,6 +574,7 @@
|
|||
<elf-symbol name='zpool_reguid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_reopen_one' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_scan' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_scan_range' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_search_import' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_set_bootenv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_set_guid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
|
|
@ -577,6 +584,7 @@
|
|||
<elf-symbol name='zpool_state_to_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_sync_one' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_trim' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_trim_one' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_upgrade' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_vdev_attach' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_vdev_clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
|
|
@ -631,7 +639,7 @@
|
|||
<elf-symbol name='fletcher_4_superscalar_ops' size='128' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libzfs_config_ops' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='sa_protocol_names' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='spa_feature_table' size='2464' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='spa_feature_table' size='2632' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfeature_checks_disable' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_deleg_perm_tab' size='528' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_history_event_names' size='328' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
|
|
@ -1450,8 +1458,103 @@
|
|||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/os/linux/getmntany.c' language='LANG_C99'>
|
||||
<array-type-def dimensions='1' type-id='d315442e' size-in-bits='16' id='811205dc'>
|
||||
<subrange length='1' type-id='7359adad' id='52f813b4'/>
|
||||
</array-type-def>
|
||||
<array-type-def dimensions='1' type-id='d3130597' size-in-bits='768' id='f63f23b9'>
|
||||
<subrange length='12' type-id='7359adad' id='84827bdc'/>
|
||||
</array-type-def>
|
||||
<typedef-decl name='__u16' type-id='8efea9e5' id='d315442e'/>
|
||||
<typedef-decl name='__s32' type-id='95e97e5e' id='3158a266'/>
|
||||
<typedef-decl name='__u32' type-id='f0981eeb' id='3f1a6b60'/>
|
||||
<typedef-decl name='__s64' type-id='1eb56b1e' id='49659421'/>
|
||||
<typedef-decl name='__u64' type-id='3a47d82b' id='d3130597'/>
|
||||
<class-decl name='statx_timestamp' size-in-bits='128' is-struct='yes' visibility='default' id='94101016'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='tv_sec' type-id='49659421' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='tv_nsec' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='96'>
|
||||
<var-decl name='__reserved' type-id='3158a266' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='statx' size-in-bits='2048' is-struct='yes' visibility='default' id='720b04c5'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='stx_mask' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='32'>
|
||||
<var-decl name='stx_blksize' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='stx_attributes' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<var-decl name='stx_nlink' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='160'>
|
||||
<var-decl name='stx_uid' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='192'>
|
||||
<var-decl name='stx_gid' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='224'>
|
||||
<var-decl name='stx_mode' type-id='d315442e' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='240'>
|
||||
<var-decl name='__spare0' type-id='811205dc' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='256'>
|
||||
<var-decl name='stx_ino' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='320'>
|
||||
<var-decl name='stx_size' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='384'>
|
||||
<var-decl name='stx_blocks' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='448'>
|
||||
<var-decl name='stx_attributes_mask' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='512'>
|
||||
<var-decl name='stx_atime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='640'>
|
||||
<var-decl name='stx_btime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='768'>
|
||||
<var-decl name='stx_ctime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='896'>
|
||||
<var-decl name='stx_mtime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1024'>
|
||||
<var-decl name='stx_rdev_major' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1056'>
|
||||
<var-decl name='stx_rdev_minor' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1088'>
|
||||
<var-decl name='stx_dev_major' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1120'>
|
||||
<var-decl name='stx_dev_minor' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1152'>
|
||||
<var-decl name='stx_mnt_id' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1216'>
|
||||
<var-decl name='__spare2' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1280'>
|
||||
<var-decl name='__spare3' type-id='f63f23b9' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<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='720b04c5' size-in-bits='64' id='936b8e35'/>
|
||||
<qualified-type-def type-id='936b8e35' restrict='yes' id='31d265b7'/>
|
||||
<function-decl name='getmntent_r' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='e75a27e9'/>
|
||||
<parameter type-id='3cad23cd'/>
|
||||
|
|
@ -1463,6 +1566,14 @@
|
|||
<parameter type-id='822cd80b'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='statx' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='f0981eeb'/>
|
||||
<parameter type-id='31d265b7'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/timestamp.c' language='LANG_C99'>
|
||||
<typedef-decl name='nl_item' type-id='95e97e5e' id='03b79a94'/>
|
||||
|
|
@ -1487,6 +1598,89 @@
|
|||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/tunables.c' language='LANG_C99'>
|
||||
<enum-decl name='zfs_tunable_type_t' naming-typedef-id='f50b1525' id='56905369'>
|
||||
<underlying-type type-id='9cac1fee'/>
|
||||
<enumerator name='ZFS_TUNABLE_TYPE_INT' value='0'/>
|
||||
<enumerator name='ZFS_TUNABLE_TYPE_UINT' value='1'/>
|
||||
<enumerator name='ZFS_TUNABLE_TYPE_ULONG' value='2'/>
|
||||
<enumerator name='ZFS_TUNABLE_TYPE_U64' value='3'/>
|
||||
<enumerator name='ZFS_TUNABLE_TYPE_STRING' value='4'/>
|
||||
</enum-decl>
|
||||
<typedef-decl name='zfs_tunable_type_t' type-id='56905369' id='f50b1525'/>
|
||||
<enum-decl name='zfs_tunable_perm_t' naming-typedef-id='ada7336b' id='e80e6ebf'>
|
||||
<underlying-type type-id='9cac1fee'/>
|
||||
<enumerator name='ZFS_TUNABLE_PERM_ZMOD_RW' value='0'/>
|
||||
<enumerator name='ZFS_TUNABLE_PERM_ZMOD_RD' value='1'/>
|
||||
</enum-decl>
|
||||
<typedef-decl name='zfs_tunable_perm_t' type-id='e80e6ebf' id='ada7336b'/>
|
||||
<class-decl name='zfs_tunable' size-in-bits='320' is-struct='yes' visibility='default' id='1a97ee0e'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='zt_name' type-id='80f4b756' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='zt_varp' type-id='eaa32e2f' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<var-decl name='zt_varsz' type-id='b59d7dce' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='192'>
|
||||
<var-decl name='zt_type' type-id='f50b1525' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='224'>
|
||||
<var-decl name='zt_perm' type-id='ada7336b' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='256'>
|
||||
<var-decl name='zt_desc' type-id='80f4b756' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='zfs_tunable_t' type-id='1a97ee0e' id='12bf5c5e'/>
|
||||
<typedef-decl name='zfs_tunable_iter_t' type-id='7ef33f92' id='d8d5f4ab'/>
|
||||
<typedef-decl name='intmax_t' type-id='5b475db0' id='e104d842'/>
|
||||
<typedef-decl name='uintmax_t' type-id='04d82f4b' id='f8b828c9'/>
|
||||
<typedef-decl name='__intmax_t' type-id='bd54fe1a' id='5b475db0'/>
|
||||
<typedef-decl name='__uintmax_t' type-id='7359adad' id='04d82f4b'/>
|
||||
<qualified-type-def type-id='12bf5c5e' const='yes' id='180e47ee'/>
|
||||
<pointer-type-def type-id='180e47ee' size-in-bits='64' id='a27af98c'/>
|
||||
<pointer-type-def type-id='92f86508' size-in-bits='64' id='7ef33f92'/>
|
||||
<function-decl name='strtoimax' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='8c85230f'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='e104d842'/>
|
||||
</function-decl>
|
||||
<function-decl name='strtoumax' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='8c85230f'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='f8b828c9'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_tunable_lookup' mangled-name='zfs_tunable_lookup' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_lookup'>
|
||||
<parameter type-id='80f4b756' name='name'/>
|
||||
<return type-id='a27af98c'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_tunable_iter' mangled-name='zfs_tunable_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_iter'>
|
||||
<parameter type-id='d8d5f4ab' name='cb'/>
|
||||
<parameter type-id='eaa32e2f' name='arg'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_tunable_set' mangled-name='zfs_tunable_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_set'>
|
||||
<parameter type-id='a27af98c' name='zt'/>
|
||||
<parameter type-id='80f4b756' name='val'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_tunable_get' mangled-name='zfs_tunable_get' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_get'>
|
||||
<parameter type-id='a27af98c' name='zt'/>
|
||||
<parameter type-id='26a90f95' name='val'/>
|
||||
<parameter type-id='b59d7dce' name='valsz'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-type size-in-bits='64' id='92f86508'>
|
||||
<parameter type-id='a27af98c'/>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-type>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libtpool/thread_pool.c' language='LANG_C99'>
|
||||
<array-type-def dimensions='1' type-id='49ef3ffd' size-in-bits='1024' id='a14403f5'>
|
||||
<subrange length='16' type-id='7359adad' id='848d0938'/>
|
||||
|
|
@ -4135,13 +4329,6 @@
|
|||
<parameter type-id='58603c44'/>
|
||||
<return type-id='9c313c2d'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_prop_get_feature' mangled-name='zpool_prop_get_feature' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_get_feature'>
|
||||
<parameter type-id='4c81de99'/>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<parameter type-id='26a90f95'/>
|
||||
<parameter type-id='b59d7dce'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_iter_snapshots_v2' mangled-name='zfs_iter_snapshots_v2' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_snapshots_v2'>
|
||||
<parameter type-id='9200a744'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
|
|
@ -6210,7 +6397,10 @@
|
|||
<enumerator name='SPA_FEATURE_FAST_DEDUP' value='41'/>
|
||||
<enumerator name='SPA_FEATURE_LONGNAME' value='42'/>
|
||||
<enumerator name='SPA_FEATURE_LARGE_MICROZAP' value='43'/>
|
||||
<enumerator name='SPA_FEATURES' value='44'/>
|
||||
<enumerator name='SPA_FEATURE_DYNAMIC_GANG_HEADER' value='44'/>
|
||||
<enumerator name='SPA_FEATURE_BLOCK_CLONING_ENDIAN' value='45'/>
|
||||
<enumerator name='SPA_FEATURE_PHYSICAL_REWRITE' value='46'/>
|
||||
<enumerator name='SPA_FEATURES' value='47'/>
|
||||
</enum-decl>
|
||||
<typedef-decl name='spa_feature_t' type-id='33ecb627' id='d6618c78'/>
|
||||
<qualified-type-def type-id='80f4b756' const='yes' id='b99c00c9'/>
|
||||
|
|
@ -6629,6 +6819,13 @@
|
|||
<parameter type-id='e4378506' name='plp'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_prop_get_feature' mangled-name='zpool_prop_get_feature' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_get_feature'>
|
||||
<parameter type-id='4c81de99' name='zhp'/>
|
||||
<parameter type-id='80f4b756' name='propname'/>
|
||||
<parameter type-id='26a90f95' name='buf'/>
|
||||
<parameter type-id='b59d7dce' name='len'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_get_state' mangled-name='zpool_get_state' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_state'>
|
||||
<parameter type-id='4c81de99' name='zhp'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
|
|
@ -6710,6 +6907,11 @@
|
|||
<parameter type-id='95e97e5e' name='flags'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_initialize_one' mangled-name='zpool_initialize_one' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_initialize_one'>
|
||||
<parameter type-id='4c81de99' name='zhp'/>
|
||||
<parameter type-id='eaa32e2f' name='data'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_initialize' mangled-name='zpool_initialize' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_initialize'>
|
||||
<parameter type-id='4c81de99' name='zhp'/>
|
||||
<parameter type-id='7063e1ab' name='cmd_type'/>
|
||||
|
|
@ -6722,6 +6924,17 @@
|
|||
<parameter type-id='5ce45b60' name='vds'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_collect_leaves' mangled-name='zpool_collect_leaves' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_collect_leaves'>
|
||||
<parameter type-id='4c81de99' name='zhp'/>
|
||||
<parameter type-id='5ce45b60' name='nvroot'/>
|
||||
<parameter type-id='5ce45b60' name='res'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_trim_one' mangled-name='zpool_trim_one' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_trim_one'>
|
||||
<parameter type-id='4c81de99' name='zhp'/>
|
||||
<parameter type-id='eaa32e2f' name='data'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_trim' mangled-name='zpool_trim' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_trim'>
|
||||
<parameter type-id='4c81de99' name='zhp'/>
|
||||
<parameter type-id='b1146b8d' name='cmd_type'/>
|
||||
|
|
@ -6735,6 +6948,14 @@
|
|||
<parameter type-id='b51cf3c2' name='cmd'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_scan_range' mangled-name='zpool_scan_range' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_scan_range'>
|
||||
<parameter type-id='4c81de99' name='zhp'/>
|
||||
<parameter type-id='7313fbe2' name='func'/>
|
||||
<parameter type-id='b51cf3c2' name='cmd'/>
|
||||
<parameter type-id='c9d12d66' name='date_start'/>
|
||||
<parameter type-id='c9d12d66' name='date_end'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_find_vdev_by_physpath' mangled-name='zpool_find_vdev_by_physpath' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_find_vdev_by_physpath'>
|
||||
<parameter type-id='4c81de99' name='zhp'/>
|
||||
<parameter type-id='80f4b756' name='ppath'/>
|
||||
|
|
@ -9394,8 +9615,8 @@
|
|||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='module/zcommon/zfeature_common.c' language='LANG_C99'>
|
||||
<array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='19712' id='fd4573e5'>
|
||||
<subrange length='44' type-id='7359adad' id='cf8ba455'/>
|
||||
<array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='21056' id='fd43354e'>
|
||||
<subrange length='47' type-id='7359adad' id='8f8900fe'/>
|
||||
</array-type-def>
|
||||
<enum-decl name='zfeature_flags' id='6db816a4'>
|
||||
<underlying-type type-id='9cac1fee'/>
|
||||
|
|
@ -9403,6 +9624,7 @@
|
|||
<enumerator name='ZFEATURE_FLAG_MOS' value='2'/>
|
||||
<enumerator name='ZFEATURE_FLAG_ACTIVATE_ON_ENABLE' value='4'/>
|
||||
<enumerator name='ZFEATURE_FLAG_PER_DATASET' value='8'/>
|
||||
<enumerator name='ZFEATURE_FLAG_NO_UPGRADE' value='16'/>
|
||||
</enum-decl>
|
||||
<typedef-decl name='zfeature_flags_t' type-id='6db816a4' id='fc329033'/>
|
||||
<enum-decl name='zfeature_type' id='c4fa2355'>
|
||||
|
|
@ -9472,7 +9694,7 @@
|
|||
<pointer-type-def type-id='611586a1' size-in-bits='64' id='2e243169'/>
|
||||
<qualified-type-def type-id='eaa32e2f' const='yes' id='83be723c'/>
|
||||
<pointer-type-def type-id='83be723c' size-in-bits='64' id='7acd98a2'/>
|
||||
<var-decl name='spa_feature_table' type-id='fd4573e5' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
|
||||
<var-decl name='spa_feature_table' type-id='fd43354e' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
|
||||
<var-decl name='zfeature_checks_disable' type-id='c19b74c3' mangled-name='zfeature_checks_disable' visibility='default' elf-symbol-id='zfeature_checks_disable'/>
|
||||
<function-decl name='opendir' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='80f4b756'/>
|
||||
|
|
|
|||
|
|
@ -584,7 +584,7 @@ get_key_material_https(libzfs_handle_t *hdl, const char *uri,
|
|||
goto end;
|
||||
}
|
||||
|
||||
int kfd = -1;
|
||||
int kfd;
|
||||
#ifdef O_TMPFILE
|
||||
kfd = open(getenv("TMPDIR") ?: "/tmp",
|
||||
O_RDWR | O_TMPFILE | O_EXCL | O_CLOEXEC, 0600);
|
||||
|
|
|
|||
|
|
@ -1039,7 +1039,6 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
|
|||
nvlist_t *ret;
|
||||
int chosen_normal = -1;
|
||||
int chosen_utf = -1;
|
||||
int set_maxbs = 0;
|
||||
|
||||
if (nvlist_alloc(&ret, NV_UNIQUE_NAME, 0) != 0) {
|
||||
(void) no_memory(hdl);
|
||||
|
|
@ -1258,46 +1257,20 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
|
|||
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
|
||||
goto error;
|
||||
}
|
||||
/* save the ZFS_PROP_RECORDSIZE during create op */
|
||||
if (zpool_hdl == NULL && prop == ZFS_PROP_RECORDSIZE) {
|
||||
set_maxbs = intval;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ZFS_PROP_SPECIAL_SMALL_BLOCKS:
|
||||
{
|
||||
int maxbs =
|
||||
set_maxbs == 0 ? SPA_OLD_MAXBLOCKSIZE : set_maxbs;
|
||||
int maxbs = SPA_MAXBLOCKSIZE;
|
||||
char buf[64];
|
||||
|
||||
if (zpool_hdl != NULL) {
|
||||
char state[64] = "";
|
||||
|
||||
maxbs = zpool_get_prop_int(zpool_hdl,
|
||||
ZPOOL_PROP_MAXBLOCKSIZE, NULL);
|
||||
|
||||
/*
|
||||
* Issue a warning but do not fail so that
|
||||
* tests for settable properties succeed.
|
||||
*/
|
||||
if (zpool_prop_get_feature(zpool_hdl,
|
||||
"feature@allocation_classes", state,
|
||||
sizeof (state)) != 0 ||
|
||||
strcmp(state, ZFS_FEATURE_ACTIVE) != 0) {
|
||||
(void) fprintf(stderr, gettext(
|
||||
"%s: property requires a special "
|
||||
"device in the pool\n"), propname);
|
||||
}
|
||||
}
|
||||
if (intval != 0 &&
|
||||
(intval < SPA_MINBLOCKSIZE ||
|
||||
intval > maxbs || !ISP2(intval))) {
|
||||
if (intval > SPA_MAXBLOCKSIZE) {
|
||||
zfs_nicebytes(maxbs, buf, sizeof (buf));
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"invalid '%s=%llu' property: must be zero "
|
||||
"or a power of 2 from 512B to %s"),
|
||||
propname, (unsigned long long)intval, buf);
|
||||
"invalid '%s' property: must be between "
|
||||
"zero and %s"),
|
||||
propname, buf);
|
||||
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
|
||||
goto error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
* Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>
|
||||
* Copyright (c) 2021, Colm Buckley <colm@tuatha.org>
|
||||
* Copyright (c) 2021, 2023, Klara Inc.
|
||||
* Copyright (c) 2025 Hewlett Packard Enterprise Development LP.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
|
@ -896,7 +897,7 @@ int
|
|||
zpool_set_prop(zpool_handle_t *zhp, const char *propname, const char *propval)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
int ret = -1;
|
||||
int ret;
|
||||
char errbuf[ERRBUFLEN];
|
||||
nvlist_t *nvl = NULL;
|
||||
nvlist_t *realprops;
|
||||
|
|
@ -1421,30 +1422,6 @@ zpool_get_state(zpool_handle_t *zhp)
|
|||
return (zhp->zpool_state);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if vdev list contains a special vdev
|
||||
*/
|
||||
static boolean_t
|
||||
zpool_has_special_vdev(nvlist_t *nvroot)
|
||||
{
|
||||
nvlist_t **child;
|
||||
uint_t children;
|
||||
|
||||
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, &child,
|
||||
&children) == 0) {
|
||||
for (uint_t c = 0; c < children; c++) {
|
||||
const char *bias;
|
||||
|
||||
if (nvlist_lookup_string(child[c],
|
||||
ZPOOL_CONFIG_ALLOCATION_BIAS, &bias) == 0 &&
|
||||
strcmp(bias, VDEV_ALLOC_BIAS_SPECIAL) == 0) {
|
||||
return (B_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if vdev list contains a dRAID vdev
|
||||
*/
|
||||
|
|
@ -1548,16 +1525,6 @@ zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
|
|||
goto create_failed;
|
||||
}
|
||||
|
||||
if (nvlist_exists(zc_fsprops,
|
||||
zfs_prop_to_name(ZFS_PROP_SPECIAL_SMALL_BLOCKS)) &&
|
||||
!zpool_has_special_vdev(nvroot)) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"%s property requires a special vdev"),
|
||||
zfs_prop_to_name(ZFS_PROP_SPECIAL_SMALL_BLOCKS));
|
||||
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
|
||||
goto create_failed;
|
||||
}
|
||||
|
||||
if (!zc_props &&
|
||||
(nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) {
|
||||
goto create_failed;
|
||||
|
|
@ -2470,6 +2437,30 @@ xlate_init_err(int err)
|
|||
return (err);
|
||||
}
|
||||
|
||||
int
|
||||
zpool_initialize_one(zpool_handle_t *zhp, void *data)
|
||||
{
|
||||
int error;
|
||||
libzfs_handle_t *hdl = zpool_get_handle(zhp);
|
||||
const char *pool_name = zpool_get_name(zhp);
|
||||
if (zpool_open_silent(hdl, pool_name, &zhp) != 0)
|
||||
return (-1);
|
||||
initialize_cbdata_t *cb = data;
|
||||
nvlist_t *vdevs = fnvlist_alloc();
|
||||
|
||||
nvlist_t *config = zpool_get_config(zhp, NULL);
|
||||
nvlist_t *nvroot = fnvlist_lookup_nvlist(config,
|
||||
ZPOOL_CONFIG_VDEV_TREE);
|
||||
zpool_collect_leaves(zhp, nvroot, vdevs);
|
||||
if (cb->wait)
|
||||
error = zpool_initialize_wait(zhp, cb->cmd_type, vdevs);
|
||||
else
|
||||
error = zpool_initialize(zhp, cb->cmd_type, vdevs);
|
||||
fnvlist_free(vdevs);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Begin, suspend, cancel, or uninit (clear) the initialization (initializing
|
||||
* of all free blocks) for the given vdevs in the given pool.
|
||||
|
|
@ -2590,6 +2581,58 @@ xlate_trim_err(int err)
|
|||
return (err);
|
||||
}
|
||||
|
||||
void
|
||||
zpool_collect_leaves(zpool_handle_t *zhp, nvlist_t *nvroot, nvlist_t *res)
|
||||
{
|
||||
libzfs_handle_t *hdl = zhp->zpool_hdl;
|
||||
uint_t children = 0;
|
||||
nvlist_t **child;
|
||||
uint_t i;
|
||||
|
||||
(void) nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
|
||||
&child, &children);
|
||||
|
||||
if (children == 0) {
|
||||
char *path = zpool_vdev_name(hdl, zhp, nvroot,
|
||||
VDEV_NAME_PATH);
|
||||
|
||||
if (strcmp(path, VDEV_TYPE_INDIRECT) != 0 &&
|
||||
strcmp(path, VDEV_TYPE_HOLE) != 0)
|
||||
fnvlist_add_boolean(res, path);
|
||||
|
||||
free(path);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < children; i++) {
|
||||
zpool_collect_leaves(zhp, child[i], res);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
zpool_trim_one(zpool_handle_t *zhp, void *data)
|
||||
{
|
||||
int error;
|
||||
libzfs_handle_t *hdl = zpool_get_handle(zhp);
|
||||
const char *pool_name = zpool_get_name(zhp);
|
||||
if (zpool_open_silent(hdl, pool_name, &zhp) != 0)
|
||||
return (-1);
|
||||
|
||||
trim_cbdata_t *cb = data;
|
||||
nvlist_t *vdevs = fnvlist_alloc();
|
||||
|
||||
/* no individual leaf vdevs specified, so add them all */
|
||||
nvlist_t *config = zpool_get_config(zhp, NULL);
|
||||
nvlist_t *nvroot = fnvlist_lookup_nvlist(config,
|
||||
ZPOOL_CONFIG_VDEV_TREE);
|
||||
|
||||
zpool_collect_leaves(zhp, nvroot, vdevs);
|
||||
error = zpool_trim(zhp, cb->cmd_type, vdevs, &cb->trim_flags);
|
||||
fnvlist_free(vdevs);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
zpool_trim_wait(zpool_handle_t *zhp, nvlist_t *vdev_guids)
|
||||
{
|
||||
|
|
@ -2730,7 +2773,13 @@ out:
|
|||
* Scan the pool.
|
||||
*/
|
||||
int
|
||||
zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func, pool_scrub_cmd_t cmd)
|
||||
zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func, pool_scrub_cmd_t cmd) {
|
||||
return (zpool_scan_range(zhp, func, cmd, 0, 0));
|
||||
}
|
||||
|
||||
int
|
||||
zpool_scan_range(zpool_handle_t *zhp, pool_scan_func_t func,
|
||||
pool_scrub_cmd_t cmd, time_t date_start, time_t date_end)
|
||||
{
|
||||
char errbuf[ERRBUFLEN];
|
||||
int err;
|
||||
|
|
@ -2739,6 +2788,8 @@ zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func, pool_scrub_cmd_t cmd)
|
|||
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);
|
||||
|
||||
err = lzc_scrub(ZFS_IOC_POOL_SCRUB, zhp->zpool_name, args, NULL);
|
||||
fnvlist_free(args);
|
||||
|
|
@ -4344,7 +4395,7 @@ zpool_set_guid(zpool_handle_t *zhp, const uint64_t *guid)
|
|||
libzfs_handle_t *hdl = zhp->zpool_hdl;
|
||||
nvlist_t *nvl = NULL;
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
int error = -1;
|
||||
int error;
|
||||
|
||||
if (guid != NULL) {
|
||||
if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
|
||||
|
|
@ -5127,9 +5178,10 @@ zpool_load_compat(const char *compat, boolean_t *features, char *report,
|
|||
/* special cases (unset), "" and "off" => enable all features */
|
||||
if (compat == NULL || compat[0] == '\0' ||
|
||||
strcmp(compat, ZPOOL_COMPAT_OFF) == 0) {
|
||||
if (features != NULL)
|
||||
if (features != NULL) {
|
||||
for (uint_t i = 0; i < SPA_FEATURES; i++)
|
||||
features[i] = B_TRUE;
|
||||
}
|
||||
if (report != NULL)
|
||||
strlcpy(report, gettext("all features enabled"), rlen);
|
||||
return (ZPOOL_COMPATIBILITY_OK);
|
||||
|
|
|
|||
|
|
@ -484,7 +484,8 @@ check_status(nvlist_t *config, boolean_t isimport,
|
|||
}
|
||||
for (i = 0; i < SPA_FEATURES; i++) {
|
||||
zfeature_info_t *fi = &spa_feature_table[i];
|
||||
if (!fi->fi_zfs_mod_supported)
|
||||
if (!fi->fi_zfs_mod_supported ||
|
||||
(fi->fi_flags & ZFEATURE_FLAG_NO_UPGRADE))
|
||||
continue;
|
||||
if (c_features[i] && !nvlist_exists(feat, fi->fi_guid))
|
||||
return (ZPOOL_STATUS_FEAT_DISABLED);
|
||||
|
|
|
|||
|
|
@ -222,6 +222,10 @@
|
|||
<elf-symbol name='spl_pagesize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='strlcat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='strlcpy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_tunable_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_tunable_iter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_tunable_lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_tunable_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
</elf-function-symbols>
|
||||
<abi-instr address-size='64' path='lib/libspl/assert.c' language='LANG_C99'>
|
||||
<class-decl name='__va_list_tag' size-in-bits='192' is-struct='yes' visibility='default' id='d5027220'>
|
||||
|
|
@ -613,7 +617,6 @@
|
|||
<array-type-def dimensions='1' type-id='de572c22' size-in-bits='1472' id='6d3c2f42'>
|
||||
<subrange length='23' type-id='7359adad' id='fdd0f594'/>
|
||||
</array-type-def>
|
||||
<type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/>
|
||||
<array-type-def dimensions='1' type-id='3a47d82b' size-in-bits='256' id='a133ec23'>
|
||||
<subrange length='4' type-id='7359adad' id='16fe7105'/>
|
||||
</array-type-def>
|
||||
|
|
@ -974,8 +977,6 @@
|
|||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/os/linux/gethostid.c' language='LANG_C99'>
|
||||
<type-decl name='long long unsigned int' size-in-bits='64' id='3a47d82b'/>
|
||||
<pointer-type-def type-id='26a90f95' size-in-bits='64' id='9b23c9ad'/>
|
||||
<qualified-type-def type-id='9b23c9ad' restrict='yes' id='8c85230f'/>
|
||||
<function-decl name='strtoull' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='8c85230f'/>
|
||||
|
|
@ -987,6 +988,13 @@
|
|||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/os/linux/getmntany.c' language='LANG_C99'>
|
||||
<array-type-def dimensions='1' type-id='d315442e' size-in-bits='16' id='811205dc'>
|
||||
<subrange length='1' type-id='7359adad' id='52f813b4'/>
|
||||
</array-type-def>
|
||||
<array-type-def dimensions='1' type-id='d3130597' size-in-bits='768' id='f63f23b9'>
|
||||
<subrange length='12' type-id='7359adad' id='84827bdc'/>
|
||||
</array-type-def>
|
||||
<type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/>
|
||||
<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'/>
|
||||
|
|
@ -1021,6 +1029,93 @@
|
|||
<var-decl name='mnt_minor' type-id='3502e3ff' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='__u16' type-id='8efea9e5' id='d315442e'/>
|
||||
<typedef-decl name='__s32' type-id='95e97e5e' id='3158a266'/>
|
||||
<typedef-decl name='__u32' type-id='f0981eeb' id='3f1a6b60'/>
|
||||
<typedef-decl name='__s64' type-id='1eb56b1e' id='49659421'/>
|
||||
<typedef-decl name='__u64' type-id='3a47d82b' id='d3130597'/>
|
||||
<class-decl name='statx_timestamp' size-in-bits='128' is-struct='yes' visibility='default' id='94101016'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='tv_sec' type-id='49659421' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='tv_nsec' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='96'>
|
||||
<var-decl name='__reserved' type-id='3158a266' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='statx' size-in-bits='2048' is-struct='yes' visibility='default' id='720b04c5'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='stx_mask' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='32'>
|
||||
<var-decl name='stx_blksize' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='stx_attributes' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<var-decl name='stx_nlink' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='160'>
|
||||
<var-decl name='stx_uid' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='192'>
|
||||
<var-decl name='stx_gid' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='224'>
|
||||
<var-decl name='stx_mode' type-id='d315442e' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='240'>
|
||||
<var-decl name='__spare0' type-id='811205dc' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='256'>
|
||||
<var-decl name='stx_ino' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='320'>
|
||||
<var-decl name='stx_size' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='384'>
|
||||
<var-decl name='stx_blocks' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='448'>
|
||||
<var-decl name='stx_attributes_mask' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='512'>
|
||||
<var-decl name='stx_atime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='640'>
|
||||
<var-decl name='stx_btime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='768'>
|
||||
<var-decl name='stx_ctime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='896'>
|
||||
<var-decl name='stx_mtime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1024'>
|
||||
<var-decl name='stx_rdev_major' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1056'>
|
||||
<var-decl name='stx_rdev_minor' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1088'>
|
||||
<var-decl name='stx_dev_major' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1120'>
|
||||
<var-decl name='stx_dev_minor' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1152'>
|
||||
<var-decl name='stx_mnt_id' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1216'>
|
||||
<var-decl name='__spare2' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1280'>
|
||||
<var-decl name='__spare3' type-id='f63f23b9' 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'/>
|
||||
|
|
@ -1096,6 +1191,8 @@
|
|||
<pointer-type-def type-id='1b055409' size-in-bits='64' id='9d424d31'/>
|
||||
<pointer-type-def type-id='0bbec9cd' size-in-bits='64' id='62f7a03d'/>
|
||||
<qualified-type-def type-id='62f7a03d' restrict='yes' id='f1cadedf'/>
|
||||
<pointer-type-def type-id='720b04c5' size-in-bits='64' id='936b8e35'/>
|
||||
<qualified-type-def type-id='936b8e35' restrict='yes' id='31d265b7'/>
|
||||
<function-decl name='getmntent_r' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='e75a27e9'/>
|
||||
<parameter type-id='3cad23cd'/>
|
||||
|
|
@ -1107,15 +1204,18 @@
|
|||
<parameter type-id='822cd80b'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='strcmp' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='strerror' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='26a90f95'/>
|
||||
</function-decl>
|
||||
<function-decl name='statx' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='f0981eeb'/>
|
||||
<parameter type-id='31d265b7'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='stat64' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='f1cadedf'/>
|
||||
|
|
@ -1258,6 +1358,96 @@
|
|||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/tunables.c' language='LANG_C99'>
|
||||
<enum-decl name='zfs_tunable_type_t' naming-typedef-id='f50b1525' id='56905369'>
|
||||
<underlying-type type-id='9cac1fee'/>
|
||||
<enumerator name='ZFS_TUNABLE_TYPE_INT' value='0'/>
|
||||
<enumerator name='ZFS_TUNABLE_TYPE_UINT' value='1'/>
|
||||
<enumerator name='ZFS_TUNABLE_TYPE_ULONG' value='2'/>
|
||||
<enumerator name='ZFS_TUNABLE_TYPE_U64' value='3'/>
|
||||
<enumerator name='ZFS_TUNABLE_TYPE_STRING' value='4'/>
|
||||
</enum-decl>
|
||||
<typedef-decl name='zfs_tunable_type_t' type-id='56905369' id='f50b1525'/>
|
||||
<enum-decl name='zfs_tunable_perm_t' naming-typedef-id='ada7336b' id='e80e6ebf'>
|
||||
<underlying-type type-id='9cac1fee'/>
|
||||
<enumerator name='ZFS_TUNABLE_PERM_ZMOD_RW' value='0'/>
|
||||
<enumerator name='ZFS_TUNABLE_PERM_ZMOD_RD' value='1'/>
|
||||
</enum-decl>
|
||||
<typedef-decl name='zfs_tunable_perm_t' type-id='e80e6ebf' id='ada7336b'/>
|
||||
<class-decl name='zfs_tunable' size-in-bits='320' is-struct='yes' visibility='default' id='1a97ee0e'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='zt_name' type-id='80f4b756' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='zt_varp' type-id='eaa32e2f' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<var-decl name='zt_varsz' type-id='b59d7dce' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='192'>
|
||||
<var-decl name='zt_type' type-id='f50b1525' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='224'>
|
||||
<var-decl name='zt_perm' type-id='ada7336b' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='256'>
|
||||
<var-decl name='zt_desc' type-id='80f4b756' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='zfs_tunable_t' type-id='1a97ee0e' id='12bf5c5e'/>
|
||||
<typedef-decl name='zfs_tunable_iter_t' type-id='7ef33f92' id='d8d5f4ab'/>
|
||||
<typedef-decl name='intmax_t' type-id='5b475db0' id='e104d842'/>
|
||||
<typedef-decl name='uintmax_t' type-id='04d82f4b' id='f8b828c9'/>
|
||||
<typedef-decl name='__intmax_t' type-id='bd54fe1a' id='5b475db0'/>
|
||||
<typedef-decl name='__uintmax_t' type-id='7359adad' id='04d82f4b'/>
|
||||
<pointer-type-def type-id='26a90f95' size-in-bits='64' id='9b23c9ad'/>
|
||||
<qualified-type-def type-id='9b23c9ad' restrict='yes' id='8c85230f'/>
|
||||
<qualified-type-def type-id='12bf5c5e' const='yes' id='180e47ee'/>
|
||||
<pointer-type-def type-id='180e47ee' size-in-bits='64' id='a27af98c'/>
|
||||
<pointer-type-def type-id='92f86508' size-in-bits='64' id='7ef33f92'/>
|
||||
<function-decl name='strtoimax' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='8c85230f'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='e104d842'/>
|
||||
</function-decl>
|
||||
<function-decl name='strtoumax' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='8c85230f'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='f8b828c9'/>
|
||||
</function-decl>
|
||||
<function-decl name='strcmp' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_tunable_lookup' mangled-name='zfs_tunable_lookup' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_lookup'>
|
||||
<parameter type-id='80f4b756' name='name'/>
|
||||
<return type-id='a27af98c'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_tunable_iter' mangled-name='zfs_tunable_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_iter'>
|
||||
<parameter type-id='d8d5f4ab' name='cb'/>
|
||||
<parameter type-id='eaa32e2f' name='arg'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_tunable_set' mangled-name='zfs_tunable_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_set'>
|
||||
<parameter type-id='a27af98c' name='zt'/>
|
||||
<parameter type-id='80f4b756' name='val'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_tunable_get' mangled-name='zfs_tunable_get' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_get'>
|
||||
<parameter type-id='a27af98c' name='zt'/>
|
||||
<parameter type-id='26a90f95' name='val'/>
|
||||
<parameter type-id='b59d7dce' name='valsz'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-type size-in-bits='64' id='92f86508'>
|
||||
<parameter type-id='a27af98c'/>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-type>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libzfs_core/libzfs_core.c' language='LANG_C99'>
|
||||
<array-type-def dimensions='1' type-id='03085adc' size-in-bits='192' id='083f8d58'>
|
||||
<subrange length='3' type-id='7359adad' id='56f209d2'/>
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ nodist_libzpool_la_SOURCES = \
|
|||
module/zfs/zfs_byteswap.c \
|
||||
module/zfs/zfs_chksum.c \
|
||||
module/zfs/zfs_debug_common.c \
|
||||
module/zfs/zfs_crrd.c \
|
||||
module/zfs/zfs_fm.c \
|
||||
module/zfs/zfs_fuid.c \
|
||||
module/zfs/zfs_ratelimit.c \
|
||||
|
|
@ -199,7 +200,7 @@ libzpool_la_LIBADD = \
|
|||
libzstd.la \
|
||||
libzutil.la
|
||||
|
||||
libzpool_la_LIBADD += $(LIBCLOCK_GETTIME) $(ZLIB_LIBS) -ldl -lm
|
||||
libzpool_la_LIBADD += $(LIBCLOCK_GETTIME) $(ZLIB_LIBS) -lm
|
||||
|
||||
libzpool_la_LDFLAGS = -pthread
|
||||
|
||||
|
|
|
|||
|
|
@ -1024,12 +1024,6 @@ spl_fstrans_unmark(fstrans_cookie_t cookie)
|
|||
(void) cookie;
|
||||
}
|
||||
|
||||
int
|
||||
__spl_pf_fstrans_check(void)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
kmem_cache_reap_active(void)
|
||||
{
|
||||
|
|
@ -1037,13 +1031,7 @@ kmem_cache_reap_active(void)
|
|||
}
|
||||
|
||||
void
|
||||
zvol_create_minor(const char *name)
|
||||
{
|
||||
(void) name;
|
||||
}
|
||||
|
||||
void
|
||||
zvol_create_minors_recursive(const char *name)
|
||||
zvol_create_minors(const char *name)
|
||||
{
|
||||
(void) name;
|
||||
}
|
||||
|
|
@ -1073,8 +1061,8 @@ zvol_rename_minors(spa_t *spa, const char *oldname, const char *newname,
|
|||
int
|
||||
zfs_file_open(const char *path, int flags, int mode, zfs_file_t **fpp)
|
||||
{
|
||||
int fd = -1;
|
||||
int dump_fd = -1;
|
||||
int fd;
|
||||
int dump_fd;
|
||||
int err;
|
||||
int old_umask = 0;
|
||||
zfs_file_t *fp;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
#include <sys/fs/zfs.h>
|
||||
#include <sys/zfs_refcount.h>
|
||||
#include <sys/zfs_ioctl.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/tunables.h>
|
||||
#include <libzutil.h>
|
||||
|
||||
/*
|
||||
|
|
@ -151,97 +151,119 @@ show_pool_stats(spa_t *spa)
|
|||
nvlist_free(config);
|
||||
}
|
||||
|
||||
/* *k_out must be freed by the caller */
|
||||
static int
|
||||
set_global_var_parse_kv(const char *arg, char **k_out, u_longlong_t *v_out)
|
||||
{
|
||||
int err;
|
||||
VERIFY(arg);
|
||||
char *d = strdup(arg);
|
||||
|
||||
char *save = NULL;
|
||||
char *k = strtok_r(d, "=", &save);
|
||||
char *v_str = strtok_r(NULL, "=", &save);
|
||||
char *follow = strtok_r(NULL, "=", &save);
|
||||
if (k == NULL || v_str == NULL || follow != NULL) {
|
||||
err = EINVAL;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
u_longlong_t val = strtoull(v_str, NULL, 0);
|
||||
if (val > UINT32_MAX) {
|
||||
fprintf(stderr, "Value for global variable '%s' must "
|
||||
"be a 32-bit unsigned integer, got '%s'\n", k, v_str);
|
||||
err = EOVERFLOW;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
*k_out = strdup(k);
|
||||
*v_out = val;
|
||||
free(d);
|
||||
return (0);
|
||||
|
||||
err_free:
|
||||
free(d);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets given global variable in libzpool to given unsigned 32-bit value.
|
||||
* arg: "<variable>=<value>"
|
||||
* Common helper for working with libzpool tunables from the command line.
|
||||
*
|
||||
* Valid inputs:
|
||||
*
|
||||
* <name> show named tunable and value
|
||||
* <name>=<value> set tunable value
|
||||
*
|
||||
* show show all tunables and values
|
||||
* show=<name> show named tunable and value
|
||||
* info show info about all tunables
|
||||
* info=<name> show info about named tunable
|
||||
*/
|
||||
int
|
||||
set_global_var(char const *arg)
|
||||
|
||||
typedef enum { SHOW, INFO, SET } tunable_mode_t;
|
||||
|
||||
static int
|
||||
list_tunables_cb(const zfs_tunable_t *tunable, void *arg)
|
||||
{
|
||||
void *zpoolhdl;
|
||||
char *varname;
|
||||
u_longlong_t val;
|
||||
int ret;
|
||||
const tunable_mode_t *mode = arg;
|
||||
|
||||
#ifndef _ZFS_LITTLE_ENDIAN
|
||||
/*
|
||||
* On big endian systems changing a 64-bit variable would set the high
|
||||
* 32 bits instead of the low 32 bits, which could cause unexpected
|
||||
* results.
|
||||
*/
|
||||
fprintf(stderr, "Setting global variables is only supported on "
|
||||
"little-endian systems\n");
|
||||
ret = ENOTSUP;
|
||||
goto out_ret;
|
||||
#endif
|
||||
|
||||
if ((ret = set_global_var_parse_kv(arg, &varname, &val)) != 0) {
|
||||
goto out_ret;
|
||||
}
|
||||
|
||||
zpoolhdl = dlopen("libzpool.so", RTLD_LAZY);
|
||||
if (zpoolhdl != NULL) {
|
||||
uint32_t *var;
|
||||
var = dlsym(zpoolhdl, varname);
|
||||
if (var == NULL) {
|
||||
fprintf(stderr, "Global variable '%s' does not exist "
|
||||
"in libzpool.so\n", varname);
|
||||
ret = EINVAL;
|
||||
goto out_dlclose;
|
||||
}
|
||||
*var = (uint32_t)val;
|
||||
static const char *type[] = {
|
||||
"int", "uint", "ulong", "u64", "str",
|
||||
};
|
||||
static const char *perm[] = {
|
||||
"rw", "rd",
|
||||
};
|
||||
|
||||
if (*mode == SHOW) {
|
||||
char val[64];
|
||||
int err = zfs_tunable_get(tunable, val, sizeof (val));
|
||||
if (err == 0)
|
||||
printf("%s: %s\n", tunable->zt_name, val);
|
||||
else
|
||||
printf("%s: [error getting tunable value: %s]\n",
|
||||
tunable->zt_name, strerror(err));
|
||||
} else {
|
||||
fprintf(stderr, "Failed to open libzpool.so to set global "
|
||||
"variable\n");
|
||||
ret = EIO;
|
||||
goto out_free;
|
||||
printf("%s [%s %s]: %s\n", tunable->zt_name,
|
||||
type[tunable->zt_type], perm[tunable->zt_perm],
|
||||
tunable->zt_desc);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
return (0);
|
||||
}
|
||||
int
|
||||
handle_tunable_option(const char *_arg, boolean_t quiet)
|
||||
{
|
||||
int err = 0;
|
||||
char *arg = strdup(_arg);
|
||||
char *k, *v;
|
||||
|
||||
out_dlclose:
|
||||
dlclose(zpoolhdl);
|
||||
out_free:
|
||||
free(varname);
|
||||
out_ret:
|
||||
return (ret);
|
||||
v = arg;
|
||||
k = strsep(&v, "=");
|
||||
|
||||
tunable_mode_t mode;
|
||||
|
||||
if (strcmp(k, "show") == 0) {
|
||||
mode = SHOW;
|
||||
k = v;
|
||||
} else if (strcmp(k, "info") == 0) {
|
||||
mode = INFO;
|
||||
k = v;
|
||||
} else if (v == NULL) {
|
||||
mode = SHOW;
|
||||
} else {
|
||||
mode = SET;
|
||||
}
|
||||
|
||||
if (quiet && mode != SET) {
|
||||
err = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mode == SET) {
|
||||
const zfs_tunable_t *tunable = zfs_tunable_lookup(k);
|
||||
if (tunable == NULL) {
|
||||
err = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
char vold[256], vnew[256];
|
||||
if (zfs_tunable_get(tunable, vold, sizeof (vold)) != 0)
|
||||
strcpy(vold, "???");
|
||||
err = zfs_tunable_set(tunable, v);
|
||||
if (err != 0)
|
||||
goto out;
|
||||
if (zfs_tunable_get(tunable, vnew, sizeof (vnew)) != 0)
|
||||
strcpy(vnew, "???");
|
||||
|
||||
if (!quiet)
|
||||
printf("%s: %s -> %s\n", k, vold, vnew);
|
||||
} else if (k != NULL) {
|
||||
const zfs_tunable_t *tunable = zfs_tunable_lookup(k);
|
||||
if (tunable == NULL) {
|
||||
err = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
list_tunables_cb(tunable, &mode);
|
||||
} else {
|
||||
zfs_tunable_iter(list_tunables_cb, &mode);
|
||||
}
|
||||
|
||||
out:
|
||||
if (!quiet) {
|
||||
if (err == ENOENT)
|
||||
fprintf(stderr, "no such tunable: %s\n", k);
|
||||
else if (err != 0)
|
||||
fprintf(stderr, "couldn't set tunable '%s': %s\n",
|
||||
k, strerror(err));
|
||||
}
|
||||
|
||||
free(arg);
|
||||
return (err);
|
||||
}
|
||||
|
||||
static nvlist_t *
|
||||
|
|
|
|||
|
|
@ -188,12 +188,8 @@ i.e. given
|
|||
will be loaded.
|
||||
.It Fl C , -vdev-class-state Ns = Ns Sy on Ns | Ns Sy off Ns | Ns Sy random No (default : Sy random )
|
||||
The vdev allocation class state.
|
||||
.It Fl o , -option Ns = Ns Ar variable Ns = Ns Ar value
|
||||
Set global
|
||||
.Ar variable
|
||||
to an unsigned 32-bit integer
|
||||
.Ar value
|
||||
(little-endian only).
|
||||
.It Fl o , -option Ns = Ns Ar var Ns = Ns Ar value Ns …
|
||||
Set the given tunable to the provided value.
|
||||
.It Fl G , -dump-debug
|
||||
Dump zfs_dbgmsg buffer before exiting due to an error.
|
||||
.It Fl V , -verbose
|
||||
|
|
|
|||
|
|
@ -1399,14 +1399,15 @@ If this setting is 0, then even if feature@block_cloning is enabled,
|
|||
using functions and system calls that attempt to clone blocks will act as
|
||||
though the feature is disabled.
|
||||
.
|
||||
.It Sy zfs_bclone_wait_dirty Ns = Ns Sy 0 Ns | Ns 1 Pq int
|
||||
When set to 1 the FICLONE and FICLONERANGE ioctls wait for dirty data to be
|
||||
written to disk.
|
||||
This allows the clone operation to reliably succeed when a file is
|
||||
.It Sy zfs_bclone_wait_dirty Ns = Ns Sy 1 Ns | Ns 0 Pq int
|
||||
When set to 1 the FICLONE and FICLONERANGE ioctls will wait for any dirty
|
||||
data to be written to disk before proceeding.
|
||||
This ensures that the clone operation reliably succeeds, even if a file is
|
||||
modified and then immediately cloned.
|
||||
For small files this may be slower than making a copy of the file.
|
||||
Therefore, this setting defaults to 0 which causes a clone operation to
|
||||
immediately fail when encountering a dirty block.
|
||||
Note that for small files this may be slower than simply copying the file.
|
||||
When set to 0 the clone operation will immediately fail if it encounters
|
||||
any dirty blocks.
|
||||
By default waiting is enabled.
|
||||
.
|
||||
.It Sy zfs_blake3_impl Ns = Ns Sy fastest Pq string
|
||||
Select a BLAKE3 implementation.
|
||||
|
|
@ -1713,10 +1714,19 @@ Similar to
|
|||
but for cleanup of old indirection records for removed vdevs.
|
||||
.
|
||||
.It Sy zfs_immediate_write_sz Ns = Ns Sy 32768 Ns B Po 32 KiB Pc Pq s64
|
||||
Largest data block to write to the ZIL.
|
||||
Larger blocks will be treated as if the dataset being written to had the
|
||||
.Sy logbias Ns = Ns Sy throughput
|
||||
property set.
|
||||
Largest write size to store the data directly into the ZIL if
|
||||
.Sy logbias Ns = Ns Sy latency .
|
||||
Larger writes may be written indirectly similar to
|
||||
.Sy logbias Ns = Ns Sy throughput .
|
||||
In presence of SLOG this parameter is ignored, as if it was set to infinity,
|
||||
storing all written data into ZIL to not depend on regular vdev latency.
|
||||
.
|
||||
.It Sy zil_special_is_slog Ns = Ns Sy 1 Ns | Ns 0 Pq int
|
||||
When enabled, and written blocks go to normal vdevs, treat present special
|
||||
vdevs as SLOGs.
|
||||
Blocks that go to the special vdevs are still written indirectly, as with
|
||||
.Sy logbias Ns = Ns Sy throughput .
|
||||
This parameter is ignored if an SLOG is present.
|
||||
.
|
||||
.It Sy zfs_initialize_value Ns = Ns Sy 16045690984833335022 Po 0xDEADBEEFDEADBEEE Pc Pq u64
|
||||
Pattern written to vdev free space by
|
||||
|
|
@ -2237,6 +2247,21 @@ Defer frees starting in this pass.
|
|||
Maximum memory used for prefetching a checkpoint's space map on each
|
||||
vdev while discarding the checkpoint.
|
||||
.
|
||||
.It Sy zfs_spa_note_txg_time Ns = Ns Sy 600 Pq uint
|
||||
This parameter defines, in seconds, how often the TXG time database will record
|
||||
a new TXG if it has changed.
|
||||
After the specified time interval has passed, and if the TXG number has changed,
|
||||
the new value is recorded in the database.
|
||||
These timestamps can later be used for more granular operations, such as
|
||||
scrubbing.
|
||||
.
|
||||
.It Sy zfs_spa_flush_txg_time Ns = Ns Sy 600 Pq uint
|
||||
This parameter defines, in seconds, how often the ZFS will flush
|
||||
the TXG time database to disk.
|
||||
It ensures that the data is actually written to persistent storage, which helps
|
||||
preserve the database in case of unexpected shutdown.
|
||||
The database is also automatically flushed during the export sequence.
|
||||
.
|
||||
.It Sy zfs_special_class_metadata_reserve_pct Ns = Ns Sy 25 Ns % Pq uint
|
||||
Only allow small data blocks to be allocated on the special and dedup vdev
|
||||
types when the available free space percentage on these vdevs exceeds this
|
||||
|
|
@ -2462,8 +2487,8 @@ code for this record type.
|
|||
The tunable has no effect if the feature is disabled.
|
||||
.
|
||||
.It Sy zfs_embedded_slog_min_ms Ns = Ns Sy 64 Pq uint
|
||||
Usually, one metaslab from each normal-class vdev is dedicated for use by
|
||||
the ZIL to log synchronous writes.
|
||||
Usually, one metaslab from each normal and special class vdev is dedicated
|
||||
for use by the ZIL to log synchronous writes.
|
||||
However, if there are fewer than
|
||||
.Sy zfs_embedded_slog_min_ms
|
||||
metaslabs in the vdev, this functionality is disabled.
|
||||
|
|
|
|||
|
|
@ -541,10 +541,16 @@ The
|
|||
.Sy blocksize
|
||||
cannot be changed once the volume has been written, so it should be set at
|
||||
volume creation time.
|
||||
The default
|
||||
.Sy blocksize
|
||||
for volumes is 16 KiB.
|
||||
Any power of 2 from 512 bytes to 128 KiB is valid.
|
||||
The size specified must be a power of two greater than or equal to
|
||||
.Ar 512 B
|
||||
and less than or equal to
|
||||
.Ar 128 KiB .
|
||||
If the
|
||||
.Sy large_blocks
|
||||
feature is enabled on the pool, the size may be up to
|
||||
.Ar 16 MiB .
|
||||
The default size is
|
||||
.Ar 16 KiB .
|
||||
.Pp
|
||||
This property can also be referred to by its shortened column name,
|
||||
.Sy volblock .
|
||||
|
|
@ -1282,10 +1288,12 @@ This feature must be enabled to be used
|
|||
.It Sy special_small_blocks Ns = Ns Ar size
|
||||
This value represents the threshold block size for including small file
|
||||
or zvol blocks into the special allocation class.
|
||||
Blocks smaller than or equal to this
|
||||
value will be assigned to the special allocation class while greater blocks
|
||||
will be assigned to the regular class.
|
||||
Valid values are zero or a power of two from 512 up to 1048576 (1 MiB).
|
||||
Blocks smaller than or equal to this value after compression and encryption
|
||||
will be assigned to the special allocation class, while greater blocks will
|
||||
be assigned to the regular class.
|
||||
Valid values are from 0 to maximum block size (
|
||||
.Ar 16 MiB
|
||||
).
|
||||
The default size is 0 which means no small file or zvol blocks
|
||||
will be allocated in the special class.
|
||||
.Pp
|
||||
|
|
@ -1569,11 +1577,6 @@ See
|
|||
.Xr zpool-features 7
|
||||
for details on ZFS feature flags.
|
||||
.Pp
|
||||
However, blocks larger than
|
||||
.Ar 1 MiB
|
||||
can have an impact on i/o latency (e.g. tying up a spinning disk for
|
||||
~300ms), and also potentially on the memory allocator.
|
||||
.Pp
|
||||
Note that maximum size is still limited by default to
|
||||
.Ar 1 MiB
|
||||
on x86_32, see
|
||||
|
|
@ -1864,7 +1867,8 @@ property is updated with
|
|||
, the property is set to desired value, but the operation to share, reshare
|
||||
or unshare the the dataset is not performed.
|
||||
.It Sy logbias Ns = Ns Sy latency Ns | Ns Sy throughput
|
||||
Provide a hint to ZFS about handling of synchronous requests in this dataset.
|
||||
Provide a hint to ZFS about handling of synchronous write requests in this
|
||||
dataset.
|
||||
If
|
||||
.Sy logbias
|
||||
is set to
|
||||
|
|
@ -1872,12 +1876,12 @@ is set to
|
|||
.Pq the default ,
|
||||
ZFS will use pool log devices
|
||||
.Pq if configured
|
||||
to handle the requests at low latency.
|
||||
to handle the write requests at low latency.
|
||||
If
|
||||
.Sy logbias
|
||||
is set to
|
||||
.Sy throughput ,
|
||||
ZFS will not use configured pool log devices.
|
||||
ZFS will not use configured pool log devices to store written data.
|
||||
ZFS will instead optimize synchronous operations for global pool throughput and
|
||||
efficient use of resources.
|
||||
.It Sy snapdev Ns = Ns Sy hidden Ns | Ns Sy visible
|
||||
|
|
|
|||
|
|
@ -401,6 +401,17 @@ This feature becomes
|
|||
.Sy active
|
||||
when first block is cloned.
|
||||
When the last cloned block is freed, it goes back to the enabled state.
|
||||
.feature com.truenas block_cloning_endian yes
|
||||
This feature corrects ZAP entry endianness issues in the Block Reference
|
||||
Table (BRT) used by block cloning.
|
||||
During the original block cloning implementation, BRT ZAP entries were
|
||||
mistakenly stored as arrays of 8 single-byte entries instead of single
|
||||
8-byte entries, making pools non-endian-safe.
|
||||
.Pp
|
||||
This feature is activated when the first BRT ZAP is created (that way
|
||||
ensuring compatibility with existing pools).
|
||||
When active, new BRT entries are stored in the correct endian-safe format.
|
||||
The feature becomes inactive when all BRT ZAPs are destroyed.
|
||||
.feature com.delphix bookmarks yes extensible_dataset
|
||||
This feature enables use of the
|
||||
.Nm zfs Cm bookmark
|
||||
|
|
@ -493,6 +504,19 @@ vdev type, or when adding a new
|
|||
.Sy draid
|
||||
vdev to an existing pool.
|
||||
.
|
||||
.feature com.klarasystems dynamic_gang_header no
|
||||
This feature enables larger gang headers based on the sector size of the pool.
|
||||
When enabled, gang headers will use the entire space allocated for them, instead
|
||||
of always restricting themselves to 512 bytes.
|
||||
This can reduce the need for nested gang trees in extreme fragmentation
|
||||
scenarios.
|
||||
.Pp
|
||||
This feature becomes active when a gang header is written that is larger than
|
||||
512 bytes.
|
||||
This feature is not enabled by
|
||||
.Xr zpool-upgrade 8 .
|
||||
Instead, it must be manually enabled, or be part of a compatibility file.
|
||||
.
|
||||
.feature org.illumos edonr no extensible_dataset
|
||||
This feature enables the use of the Edon-R hash algorithm for checksum,
|
||||
including for nopwrite
|
||||
|
|
@ -829,6 +853,23 @@ when the
|
|||
command is used on a top-level vdev, and will never return to being
|
||||
.Sy enabled .
|
||||
.
|
||||
.feature com.truenas physical_rewrite yes extensible_dataset
|
||||
This feature enables physical block rewriting that preserves logical birth
|
||||
times, avoiding unnecessary inclusion of rewritten blocks in incremental
|
||||
.Nm zfs Cm send
|
||||
streams.
|
||||
When enabled, the
|
||||
.Nm zfs Cm rewrite Fl P
|
||||
command can be used.
|
||||
.Pp
|
||||
This feature becomes
|
||||
.Sy active
|
||||
the first time
|
||||
.Nm zfs Cm rewrite Fl P
|
||||
is used on any dataset, and will return to being
|
||||
.Sy enabled
|
||||
once all datasets that have ever used physical rewrite are destroyed.
|
||||
.
|
||||
.feature org.zfsonlinux project_quota yes extensible_dataset
|
||||
This feature allows administrators to account the spaces and objects usage
|
||||
information against the project identifier
|
||||
|
|
|
|||
|
|
@ -390,11 +390,6 @@ Multiple log devices can also be specified, and they can be mirrored.
|
|||
See the
|
||||
.Sx EXAMPLES
|
||||
section for an example of mirroring multiple log devices.
|
||||
.Pp
|
||||
Log devices can be added, replaced, attached, detached, and removed.
|
||||
In addition, log devices are imported and exported as part of the pool
|
||||
that contains them.
|
||||
Mirrored devices can be removed by specifying the top-level mirror vdev.
|
||||
.
|
||||
.Ss Cache Devices
|
||||
Devices can be added to a storage pool as
|
||||
|
|
@ -486,8 +481,8 @@ current state of the pool won't be scanned during a scrub.
|
|||
.
|
||||
.Ss Special Allocation Class
|
||||
Allocations in the special class are dedicated to specific block types.
|
||||
By default, this includes all metadata, the indirect blocks of user data, and
|
||||
any deduplication tables.
|
||||
By default, this includes all metadata, the indirect blocks of user data,
|
||||
intent log (in absence of separate log device), and deduplication tables.
|
||||
The class can also be provisioned to accept small file blocks or zvol blocks
|
||||
on a per dataset granularity.
|
||||
.Pp
|
||||
|
|
|
|||
|
|
@ -474,10 +474,15 @@ as it runs.
|
|||
Exercise extreme caution when using this option in shared or uncontrolled
|
||||
environments.
|
||||
.It Fl o , -option Ns = Ns Ar var Ns = Ns Ar value Ns …
|
||||
Set the given global libzpool variable to the provided value.
|
||||
The value must be an unsigned 32-bit integer.
|
||||
Currently only little-endian systems are supported to avoid accidentally setting
|
||||
the high 32 bits of 64-bit variables.
|
||||
Set the given tunable to the provided value.
|
||||
.It Fl o , -option Ns = Ns Ar var Ns …
|
||||
Show the value of the given tunable.
|
||||
.It Fl o , -option Ns = Ns show
|
||||
Show all tunables and their values.
|
||||
.It Fl o , -option Ns = Ns info Ns = Ns Ar value Ns …
|
||||
Show info about a tunable, including their name, type and description.
|
||||
.It Fl o , -option Ns = Ns info
|
||||
Show info about all tunables.
|
||||
.It Fl P , -parseable
|
||||
Print numbers in an unscaled form more amenable to parsing, e.g.\&
|
||||
.Sy 1000000
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
.Sh SYNOPSIS
|
||||
.Nm zfs
|
||||
.Cm rewrite
|
||||
.Oo Fl rvx Ns Oc
|
||||
.Oo Fl Prvx Ns Oc
|
||||
.Op Fl l Ar length
|
||||
.Op Fl o Ar offset
|
||||
.Ar file Ns | Ns Ar directory Ns …
|
||||
|
|
@ -43,6 +43,15 @@ as is without modification at a new location and possibly with new
|
|||
properties, such as checksum, compression, dedup, copies, etc,
|
||||
as if they were atomically read and written back.
|
||||
.Bl -tag -width "-r"
|
||||
.It Fl P
|
||||
Perform physical rewrite, preserving logical birth time of blocks.
|
||||
By default, rewrite updates logical birth times, making blocks appear
|
||||
as modified in snapshots and incremental send streams.
|
||||
Physical rewrite preserves logical birth times, avoiding unnecessary
|
||||
inclusion in incremental streams.
|
||||
Physical rewrite requires the
|
||||
.Sy physical_rewrite
|
||||
feature to be enabled on the pool.
|
||||
.It Fl l Ar length
|
||||
Rewrite at most this number of bytes.
|
||||
.It Fl o Ar offset
|
||||
|
|
@ -60,17 +69,22 @@ same as some property changes may increase pool space usage.
|
|||
Holes that were never written or were previously zero-compressed are
|
||||
not rewritten and will remain holes even if compression is disabled.
|
||||
.Pp
|
||||
Rewritten blocks will be seen as modified in next snapshot and as such
|
||||
included into the incremental
|
||||
.Nm zfs Cm send
|
||||
stream.
|
||||
.Pp
|
||||
If a
|
||||
.Fl l
|
||||
or
|
||||
.Fl o
|
||||
value request a rewrite to regions past the end of the file, then those
|
||||
regions are silently ignored, and no error is reported.
|
||||
.Pp
|
||||
By default, rewritten blocks update their logical birth time,
|
||||
meaning they will be included in incremental
|
||||
.Nm zfs Cm send
|
||||
streams as modified data.
|
||||
When the
|
||||
.Fl P
|
||||
flag is used, rewritten blocks preserve their logical birth time, since
|
||||
there are no user data changes.
|
||||
.
|
||||
.Sh SEE ALSO
|
||||
.Xr zfsprops 7
|
||||
.Xr zfsprops 7 ,
|
||||
.Xr zpool-features 7
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
.\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
|
||||
.\" Copyright (c) 2024, 2025, Klara, Inc.
|
||||
.\"
|
||||
.Dd May 27, 2025
|
||||
.Dd July 3, 2025
|
||||
.Dt ZPOOL-EVENTS 8
|
||||
.Os
|
||||
.
|
||||
|
|
@ -465,7 +465,7 @@ ZIO_FLAG_DONT_RETRY:0x00000400
|
|||
ZIO_FLAG_NODATA:0x00001000
|
||||
ZIO_FLAG_INDUCE_DAMAGE:0x00002000
|
||||
|
||||
ZIO_FLAG_IO_ALLOCATING:0x00004000
|
||||
ZIO_FLAG_ALLOC_THROTTLED:0x00004000
|
||||
ZIO_FLAG_IO_RETRY:0x00008000
|
||||
ZIO_FLAG_PROBE:0x00010000
|
||||
ZIO_FLAG_TRYHARD:0x00020000
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
.\" Copyright (c) 2018 George Melikov. All Rights Reserved.
|
||||
.\" Copyright 2017 Nexenta Systems, Inc.
|
||||
.\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
|
||||
.\" Copyright (c) 2025 Hewlett Packard Enterprise Development LP.
|
||||
.\"
|
||||
.Dd May 27, 2021
|
||||
.Dt ZPOOL-INITIALIZE 8
|
||||
|
|
@ -39,7 +40,7 @@
|
|||
.Cm initialize
|
||||
.Op Fl c Ns | Ns Fl s | Ns Fl u
|
||||
.Op Fl w
|
||||
.Ar pool
|
||||
.Fl a Ns | Ns Ar pool
|
||||
.Oo Ar device Oc Ns …
|
||||
.
|
||||
.Sh DESCRIPTION
|
||||
|
|
@ -48,6 +49,10 @@ devices, or all eligible devices in the pool if no individual devices are
|
|||
specified.
|
||||
Only leaf data or log devices may be initialized.
|
||||
.Bl -tag -width Ds
|
||||
.It Fl a , -all
|
||||
Begin, cancel, suspend initializing on
|
||||
all
|
||||
pools.
|
||||
.It Fl c , -cancel
|
||||
Cancel initializing on the specified devices, or all eligible devices if none
|
||||
are specified.
|
||||
|
|
|
|||
|
|
@ -26,8 +26,9 @@
|
|||
.\" Copyright (c) 2018, 2021 George Melikov. All Rights Reserved.
|
||||
.\" Copyright 2017 Nexenta Systems, Inc.
|
||||
.\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
|
||||
.\" Copyright (c) 2025 Hewlett Packard Enterprise Development LP.
|
||||
.\"
|
||||
.Dd November 18, 2024
|
||||
.Dd December 11, 2024
|
||||
.Dt ZPOOL-SCRUB 8
|
||||
.Os
|
||||
.
|
||||
|
|
@ -39,7 +40,9 @@
|
|||
.Cm scrub
|
||||
.Op Ns Fl e | Ns Fl p | Fl s Ns | Fl C Ns
|
||||
.Op Fl w
|
||||
.Ar pool Ns …
|
||||
.Op Fl S Ar date
|
||||
.Op Fl E Ar date
|
||||
.Fl a Ns | Ns Ar pool Ns …
|
||||
.
|
||||
.Sh DESCRIPTION
|
||||
Begins a scrub or resumes a paused scrub.
|
||||
|
|
@ -89,6 +92,12 @@ During this period, no completion time estimate will be provided.
|
|||
.
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -width "-s"
|
||||
.It Fl a , -all
|
||||
Begin, pause, stop scrub on
|
||||
all
|
||||
pools.
|
||||
Initiating scrubs on multiple pools can put considerable load and memory
|
||||
pressure on the system, so this operation should be performed with caution.
|
||||
.It Fl s
|
||||
Stop scrubbing.
|
||||
.It Fl p
|
||||
|
|
@ -118,6 +127,44 @@ resilvering, nor can it be run when a regular scrub is paused.
|
|||
Continue scrub from last saved txg (see zpool
|
||||
.Sy last_scrubbed_txg
|
||||
property).
|
||||
.It Fl S Ar date , Fl E Ar date
|
||||
Allows specifying the date range for blocks created between these dates.
|
||||
.Bl -bullet -compact -offset indent
|
||||
.It
|
||||
.Fl S
|
||||
Defines a start date.
|
||||
If not specified, scrubbing begins from the start of the pool's
|
||||
existence.
|
||||
.It
|
||||
.Fl E
|
||||
Defines an end date.
|
||||
If not specified, scrubbing continues up to the most recent data.
|
||||
.El
|
||||
The provided date should be in the format:
|
||||
.Dq YYYY-MM-DD HH:MM .
|
||||
Where:
|
||||
.Bl -bullet -compact -offset indent
|
||||
.It
|
||||
.Dq YYYY
|
||||
is the year.
|
||||
.It
|
||||
.Dq MM
|
||||
is the numeric representation of the month.
|
||||
.It
|
||||
.Dq DD
|
||||
is the day of the month.
|
||||
.It
|
||||
.Dq HH
|
||||
is the hour.
|
||||
.It
|
||||
.Dq MM
|
||||
is the minutes.
|
||||
.El
|
||||
The hour and minutes parameters can be omitted.
|
||||
The time should be provided in machine local time zone.
|
||||
Specifying dates prior to enabling this feature will result in scrubbing
|
||||
starting from the date the pool was created.
|
||||
If the time was moved backward manually the data range may become inaccurate.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
.Ss Example 1
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
.\" Copyright (c) 2018 George Melikov. All Rights Reserved.
|
||||
.\" Copyright 2017 Nexenta Systems, Inc.
|
||||
.\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
|
||||
.\" Copyright (c) 2025 Hewlett Packard Enterprise Development LP.
|
||||
.\"
|
||||
.Dd May 27, 2021
|
||||
.Dt ZPOOL-TRIM 8
|
||||
|
|
@ -40,7 +41,7 @@
|
|||
.Op Fl dw
|
||||
.Op Fl r Ar rate
|
||||
.Op Fl c Ns | Ns Fl s
|
||||
.Ar pool
|
||||
.Fl a Ns | Ns Ar pool
|
||||
.Oo Ar device Ns Oc Ns …
|
||||
.
|
||||
.Sh DESCRIPTION
|
||||
|
|
@ -57,6 +58,10 @@ See the documentation for the
|
|||
.Sy autotrim
|
||||
property above for the types of vdev devices which can be trimmed.
|
||||
.Bl -tag -width Ds
|
||||
.It Fl a , -all
|
||||
Perform TRIM operation on
|
||||
all
|
||||
pools.
|
||||
.It Fl d , -secure
|
||||
Causes a secure TRIM to be initiated.
|
||||
When performing a secure TRIM, the
|
||||
|
|
|
|||
|
|
@ -406,6 +406,7 @@ ZFS_OBJS := \
|
|||
zfs_byteswap.o \
|
||||
zfs_chksum.o \
|
||||
zfs_debug_common.o \
|
||||
zfs_crrd.o \
|
||||
zfs_fm.o \
|
||||
zfs_fuid.o \
|
||||
zfs_impl.o \
|
||||
|
|
@ -494,3 +495,34 @@ UBSAN_SANITIZE_zfs/sa.o := n
|
|||
ifeq ($(CONFIG_ALTIVEC),y)
|
||||
$(obj)/zfs/vdev_raidz_math_powerpc_altivec.o : c_flags += -maltivec
|
||||
endif
|
||||
|
||||
# The following recipes attempt to fix out of src-tree builds, where $(src) != $(obj), so that the
|
||||
# subdir %.c/%.S -> %.o targets will work as expected. The in-kernel pattern targets do not seem to
|
||||
# be working on subdirs since about ~6.10
|
||||
zobjdirs = $(dir $(zfs-objs)) $(dir $(spl-objs)) \
|
||||
$(dir $(zfs-$(CONFIG_X86))) $(dir $(zfs-$(CONFIG_UML_X86))) $(dir $(zfs-$(CONFIG_ARM64))) \
|
||||
$(dir $(zfs-$(CONFIG_PPC64))) $(dir $(zfs-$(CONFIG_PPC)))
|
||||
|
||||
z_cdirs = $(sort $(filter-out lua/setjmp/ $(addprefix icp/asm-aarch64/, aes/ blake3/ modes/ sha2/) \
|
||||
$(addprefix icp/asm-x86_64/, aes/ blake3/ modes/ sha2/) \
|
||||
$(addprefix icp/asm-ppc/, aes/ blake3/ modes/ sha2/) \
|
||||
$(addprefix icp/asm-ppc64/, aes/ blake3/ modes/ sha2/), $(zobjdirs)))
|
||||
z_sdirs = $(sort $(filter lua/setjmp/ $(addprefix icp/asm-aarch64/, aes/ blake3/ modes/ sha2/) \
|
||||
$(addprefix icp/asm-x86_64/, aes/ blake3/ modes/ sha2/) \
|
||||
$(addprefix icp/asm-ppc/, aes/ blake3/ modes/ sha2/) \
|
||||
$(addprefix icp/asm-ppc64/, aes/ blake3/ modes/ sha2/), $(zobjdirs)))
|
||||
|
||||
define ZKMOD_C_O_MAKE_TARGET
|
||||
$1%.o: $(src)/$1%.c FORCE
|
||||
$$(call if_changed_rule,cc_o_c)
|
||||
$$(call cmd,force_checksrc)
|
||||
endef
|
||||
|
||||
define ZKMOD_S_O_MAKE_TARGET
|
||||
$1%.o: $(src)/$1%.S FORCE
|
||||
$$(call if_changed_rule,as_o_S)
|
||||
$$(call cmd,force_checksrc)
|
||||
endef
|
||||
|
||||
$(foreach target,$(z_cdirs), $(eval $(call ZKMOD_C_O_MAKE_TARGET,$(target))))
|
||||
$(foreach target,$(z_sdirs), $(eval $(call ZKMOD_S_O_MAKE_TARGET,$(target))))
|
||||
|
|
|
|||
|
|
@ -217,6 +217,7 @@ SRCS+= abd_os.c \
|
|||
vdev_label_os.c \
|
||||
zfs_acl.c \
|
||||
zfs_ctldir.c \
|
||||
zfs_crrd.c \
|
||||
zfs_debug.c \
|
||||
zfs_dir.c \
|
||||
zfs_file_os.c \
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue