1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-03 09:00:21 +00:00

zfs: merge OpenZFS master-436ab35a5

- speed up writing to ZFS pools without ZIL devices (aa755b3)
- speed up importing ZFS pools (2d8f72d, a0e0199, cf0977a)
...

MFC after:		2 weeks
Reviewed by:		mjg (partial)
Tested by:		pho
Differential Revision:	https://reviews.freebsd.org/D28677
This commit is contained in:
Martin Matuska 2021-02-16 01:39:34 +01:00
commit 184c1b9439
231 changed files with 3259 additions and 1779 deletions

View File

@ -67,7 +67,6 @@ KERNEL_C = \
zfs_fletcher_superscalar4.c \
zfs_namecheck.c \
zfs_prop.c \
zfs_uio.c \
zpool_prop.c \
zprop_common.c

View File

@ -46,7 +46,6 @@ KERNEL_C = \
zfs_fletcher_superscalar4.c \
zfs_namecheck.c \
zfs_prop.c \
zfs_uio.c \
zfs_zstd.c \
zpool_prop.c \
zprop_common.c \

View File

@ -0,0 +1,42 @@
<!--- Please fill out the following template, which will help other contributors review your Pull Request. -->
<!--- Provide a general summary of your changes in the Title above -->
<!---
Documentation on ZFS Buildbot options can be found at
https://openzfs.github.io/openzfs-docs/Developer%20Resources/Buildbot%20Options.html
-->
### Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
### Description
<!--- Describe your changes in detail -->
### How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->
<!--- If your change is a performance enhancement, please provide benchmarks here. -->
<!--- Please think about using the draft PR feature if appropriate -->
### Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Performance enhancement (non-breaking change which improves efficiency)
- [ ] Code cleanup (non-breaking change which makes code smaller or more readable)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Library ABI change (libzfs, libzfs\_core, libnvpair, libuutil and libzfsbootenv)
- [ ] Documentation (a change to man pages or other documentation)
### Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [ ] My code follows the OpenZFS [code style requirements](https://github.com/openzfs/zfs/blob/master/.github/CONTRIBUTING.md#coding-conventions).
- [ ] I have updated the documentation accordingly.
- [ ] I have read the [**contributing** document](https://github.com/openzfs/zfs/blob/master/.github/CONTRIBUTING.md).
- [ ] I have added [tests](https://github.com/openzfs/zfs/tree/master/tests) to cover my changes.
- [ ] I have run the ZFS Test Suite with this change applied.
- [ ] All commit messages are properly formatted and contain [`Signed-off-by`](https://github.com/openzfs/zfs/blob/master/.github/CONTRIBUTING.md#signed-off-by).

View File

@ -0,0 +1,64 @@
name: zfs-tests-functional
on:
push:
pull_request:
jobs:
tests-functional-ubuntu:
strategy:
fail-fast: false
matrix:
os: [18.04, 20.04]
runs-on: ubuntu-${{ matrix.os }}
steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install --yes -qq build-essential autoconf libtool gdb lcov \
git alien fakeroot wget curl bc fio acl \
sysstat mdadm lsscsi parted gdebi attr dbench watchdog ksh \
nfs-kernel-server samba rng-tools xz-utils \
zlib1g-dev uuid-dev libblkid-dev libselinux-dev \
xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \
libssl-dev libffi-dev libaio-dev libelf-dev libmount-dev \
libpam0g-dev pamtester python-dev python-setuptools python-cffi \
python3 python3-dev python3-setuptools python3-cffi
- name: Autogen.sh
run: |
sh autogen.sh
- name: Configure
run: |
./configure --enable-debug --enable-debuginfo
- name: Make
run: |
make --no-print-directory -s pkg-utils pkg-kmod
- name: Install
run: |
sudo dpkg -i *.deb
# Update order of directories to search for modules, otherwise
# Ubuntu will load kernel-shipped ones.
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
sudo depmod
sudo modprobe zfs
- name: Tests
run: |
/usr/share/zfs/zfs-tests.sh -v -s 3G
- name: Prepare artifacts
if: failure()
run: |
RESULTS_PATH=$(readlink -f /var/tmp/test_results/current)
sudo dmesg > $RESULTS_PATH/dmesg
sudo cp /var/log/syslog $RESULTS_PATH/
sudo chmod +r $RESULTS_PATH/*
# Replace ':' in dir names, actions/upload-artifact doesn't support it
for f in $(find $RESULTS_PATH -name '*:*'); do mv "$f" "${f//:/__}"; done
- uses: actions/upload-artifact@v2
if: failure()
with:
name: Test logs Ubuntu-${{ matrix.os }}
path: /var/tmp/test_results/20*/
if-no-files-found: ignore

View File

@ -0,0 +1,60 @@
name: zfs-tests-sanity
on:
push:
pull_request:
jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install --yes -qq build-essential autoconf libtool gdb lcov \
git alien fakeroot wget curl bc fio acl \
sysstat mdadm lsscsi parted gdebi attr dbench watchdog ksh \
nfs-kernel-server samba rng-tools xz-utils \
zlib1g-dev uuid-dev libblkid-dev libselinux-dev \
xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \
libssl-dev libffi-dev libaio-dev libelf-dev libmount-dev \
libpam0g-dev pamtester python-dev python-setuptools python-cffi \
python3 python3-dev python3-setuptools python3-cffi
- name: Autogen.sh
run: |
sh autogen.sh
- name: Configure
run: |
./configure --enable-debug --enable-debuginfo
- name: Make
run: |
make --no-print-directory -s pkg-utils pkg-kmod
- name: Install
run: |
sudo dpkg -i *.deb
# Update order of directories to search for modules, otherwise
# Ubuntu will load kernel-shipped ones.
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
sudo depmod
sudo modprobe zfs
- name: Tests
run: |
/usr/share/zfs/zfs-tests.sh -v -s 3G -r sanity
- name: Prepare artifacts
if: failure()
run: |
RESULTS_PATH=$(readlink -f /var/tmp/test_results/current)
sudo dmesg > $RESULTS_PATH/dmesg
sudo cp /var/log/syslog $RESULTS_PATH/
sudo chmod +r $RESULTS_PATH/*
# Replace ':' in dir names, actions/upload-artifact doesn't support it
for f in $(find $RESULTS_PATH -name '*:*'); do mv "$f" "${f//:/__}"; done
- uses: actions/upload-artifact@v2
if: failure()
with:
name: Test logs
path: /var/tmp/test_results/20*/
if-no-files-found: ignore

View File

@ -6,5 +6,5 @@ Release: rc1
Release-Tags: relext
License: CDDL
Author: OpenZFS
Linux-Maximum: 5.10
Linux-Maximum: 5.11
Linux-Minimum: 3.10

View File

@ -25,7 +25,6 @@ endif
AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = autogen.sh copy-builtin
EXTRA_DIST += cppcheck-suppressions.txt
EXTRA_DIST += config/config.awk config/rpm.am config/deb.am config/tgz.am
EXTRA_DIST += META AUTHORS COPYRIGHT LICENSE NEWS NOTICE README.md
EXTRA_DIST += CODE_OF_CONDUCT.md
@ -204,13 +203,13 @@ vcscheck:
PHONY += lint
lint: cppcheck paxcheck
CPPCHECKDIRS = cmd lib module
PHONY += cppcheck
cppcheck:
@if type cppcheck > /dev/null 2>&1; then \
cppcheck --quiet --force --error-exitcode=2 --inline-suppr \
--suppressions-list=${top_srcdir}/cppcheck-suppressions.txt \
-UHAVE_SSE2 -UHAVE_AVX512F -UHAVE_UIO_ZEROCOPY \
${top_srcdir}; \
cppcheck: $(CPPCHECKDIRS)
@if test -n "$(CPPCHECK)"; then \
set -e ; for dir in $(CPPCHECKDIRS) ; do \
$(MAKE) -C $$dir cppcheck ; \
done \
else \
echo "skipping cppcheck because cppcheck is not installed"; \
fi

View File

@ -2,10 +2,20 @@ SUBDIRS = zfs zpool zdb zhack zinject zstream zstreamdump ztest
SUBDIRS += fsck_zfs vdev_id raidz_test zfs_ids_to_path
SUBDIRS += zpool_influxdb
CPPCHECKDIRS = zfs zpool zdb zhack zinject zstream ztest
CPPCHECKDIRS += raidz_test zfs_ids_to_path zpool_influxdb
if USING_PYTHON
SUBDIRS += arcstat arc_summary dbufstat
endif
if BUILD_LINUX
SUBDIRS += mount_zfs zed zgenhostid zvol_id zvol_wait
CPPCHECKDIRS += mount_zfs zed zgenhostid zvol_id
endif
PHONY = cppcheck
cppcheck: $(CPPCHECKDIRS)
set -e ; for dir in $(CPPCHECKDIRS) ; do \
$(MAKE) -C $$dir cppcheck ; \
done

View File

@ -18,3 +18,5 @@ mount_zfs_LDADD = \
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
mount_zfs_LDADD += $(LTLIBINTL)
include $(top_srcdir)/config/CppCheck.am

View File

@ -50,6 +50,21 @@ libzfs_handle_t *g_zfs;
static void
parse_dataset(const char *target, char **dataset)
{
/*
* Prior to util-linux 2.36.2, if a file or directory in the
* current working directory was named 'dataset' then mount(8)
* would prepend the current working directory to the dataset.
* Check for it and strip the prepended path when it is added.
*/
char cwd[PATH_MAX];
if (getcwd(cwd, PATH_MAX) == NULL) {
perror("getcwd");
return;
}
int len = strlen(cwd);
if (strncmp(cwd, target, len) == 0)
target += len;
/* Assume pool/dataset is more likely */
strlcpy(*dataset, target, PATH_MAX);

View File

@ -18,3 +18,5 @@ raidz_test_LDADD = \
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la
raidz_test_LDADD += -lm
include $(top_srcdir)/config/CppCheck.am

View File

@ -492,8 +492,9 @@ vdev_raidz_map_alloc_expanded(abd_t *abd, uint64_t size, uint64_t offset,
(dc - r) * (rows - 1) + row;
}
rr->rr_col[c].rc_size = 1ULL << ashift;
rr->rr_col[c].rc_abd =
abd_get_offset(abd, off << ashift);
rr->rr_col[c].rc_abd = abd_get_offset_struct(
&rr->rr_col[c].rc_abdstruct,
abd, off << ashift, 1 << ashift);
}
asize += rr->rr_col[c].rc_size;

View File

@ -79,6 +79,34 @@
# channel 86:00.0 1 A
# channel 86:00.0 0 B
# #
# # Example vdev_id.conf - multipath / multijbod-daisychaining
# #
#
# multipath yes
# multijbod yes
#
# # PCI_ID HBA PORT CHANNEL NAME
# channel 85:00.0 1 A
# channel 85:00.0 0 B
# channel 86:00.0 1 A
# channel 86:00.0 0 B
# #
# # Example vdev_id.conf - multipath / mixed
# #
#
# multipath yes
# slot mix
#
# # PCI_ID HBA PORT CHANNEL NAME
# channel 85:00.0 3 A
# channel 85:00.0 2 B
# channel 86:00.0 3 A
# channel 86:00.0 2 B
# channel af:00.0 0 C
# channel af:00.0 1 C
# #
# # Example vdev_id.conf - alias
# #
@ -92,9 +120,10 @@ PATH=/bin:/sbin:/usr/bin:/usr/sbin
CONFIG=/etc/zfs/vdev_id.conf
PHYS_PER_PORT=
DEV=
MULTIPATH=
TOPOLOGY=
BAY=
ENCL_ID=""
UNIQ_ENCL_ID=""
usage() {
cat << EOF
@ -107,6 +136,7 @@ Usage: vdev_id [-h]
-e Create enclose device symlinks only (/dev/by-enclosure)
-g Storage network topology [default="$TOPOLOGY"]
-m Run in multipath mode
-j Run in multijbod mode
-p number of phy's per switch port [default=$PHYS_PER_PORT]
-h show this summary
EOF
@ -117,12 +147,12 @@ map_slot() {
LINUX_SLOT=$1
CHANNEL=$2
MAPPED_SLOT=`awk "\\$1 == \"slot\" && \\$2 == ${LINUX_SLOT} && \
\\$4 ~ /^${CHANNEL}$|^$/ { print \\$3; exit }" $CONFIG`
MAPPED_SLOT=$(awk '$1 == "slot" && $2 == "${LINUX_SLOT}" && \
$4 ~ /^${CHANNEL}$|^$/ { print $3; exit}' $CONFIG)
if [ -z "$MAPPED_SLOT" ] ; then
MAPPED_SLOT=$LINUX_SLOT
fi
printf "%d" ${MAPPED_SLOT}
printf "%d" "${MAPPED_SLOT}"
}
map_channel() {
@ -132,40 +162,120 @@ map_channel() {
case $TOPOLOGY in
"sas_switch")
MAPPED_CHAN=`awk "\\$1 == \"channel\" && \\$2 == ${PORT} \
{ print \\$3; exit }" $CONFIG`
MAPPED_CHAN=$(awk -v port="$PORT" \
'$1 == "channel" && $2 == ${PORT} \
{ print $3; exit }' $CONFIG)
;;
"sas_direct"|"scsi")
MAPPED_CHAN=`awk "\\$1 == \"channel\" && \
\\$2 == \"${PCI_ID}\" && \\$3 == ${PORT} \
{ print \\$4; exit }" $CONFIG`
MAPPED_CHAN=$(awk -v pciID="$PCI_ID" -v port="$PORT" \
'$1 == "channel" && $2 == pciID && $3 == port \
{print $4}' $CONFIG)
;;
esac
printf "%s" ${MAPPED_CHAN}
printf "%s" "${MAPPED_CHAN}"
}
get_encl_id() {
set -- $(echo $1)
count=$#
i=1
while [ $i -le $count ] ; do
d=$(eval echo '$'{$i})
id=$(cat "/sys/class/enclosure/${d}/id")
ENCL_ID="${ENCL_ID} $id"
i=$((i + 1))
done
}
get_uniq_encl_id() {
for uuid in ${ENCL_ID}; do
found=0
for count in ${UNIQ_ENCL_ID}; do
if [ $count = $uuid ]; then
found=1
break
fi
done
if [ $found -eq 0 ]; then
UNIQ_ENCL_ID="${UNIQ_ENCL_ID} $uuid"
fi
done
}
# map_jbod explainer: The bsg driver knows the difference between a SAS
# expander and fanout expander. Use hostX instance along with top-level
# (whole enclosure) expander instances in /sys/class/enclosure and
# matching a field in an array of expanders, using the index of the
# matched array field as the enclosure instance, thereby making jbod IDs
# dynamic. Avoids reliance on high overhead userspace commands like
# multipath and lsscsi and instead uses existing sysfs data. $HOSTCHAN
# variable derived from devpath gymnastics in sas_handler() function.
map_jbod() {
DEVEXP=$(ls -l "/sys/block/$DEV/device/" | grep enclos | awk -F/ '{print $(NF-1) }')
DEV=$1
# Use "set --" to create index values (Arrays)
set -- $(ls -l /sys/class/enclosure | grep -v "^total" | awk '{print $9}')
# Get count of total elements
JBOD_COUNT=$#
JBOD_ITEM=$*
# Build JBODs (enclosure) id from sys/class/enclosure/<dev>/id
get_encl_id "$JBOD_ITEM"
# Different expander instances for each paths.
# Filter out and keep only unique id.
get_uniq_encl_id
# Identify final 'mapped jbod'
j=0
for count in ${UNIQ_ENCL_ID}; do
i=1
j=$((j + 1))
while [ $i -le $JBOD_COUNT ] ; do
d=$(eval echo '$'{$i})
id=$(cat "/sys/class/enclosure/${d}/id")
if [ "$d" = "$DEVEXP" ] && [ $id = $count ] ; then
MAPPED_JBOD=$j
break
fi
i=$((i + 1))
done
done
printf "%d" "${MAPPED_JBOD}"
}
sas_handler() {
if [ -z "$PHYS_PER_PORT" ] ; then
PHYS_PER_PORT=`awk "\\$1 == \"phys_per_port\" \
{print \\$2; exit}" $CONFIG`
PHYS_PER_PORT=$(awk '$1 == "phys_per_port" \
{print $2; exit}' $CONFIG)
fi
PHYS_PER_PORT=${PHYS_PER_PORT:-4}
if ! echo $PHYS_PER_PORT | grep -q -E '^[0-9]+$' ; then
if ! echo "$PHYS_PER_PORT" | grep -q -E '^[0-9]+$' ; then
echo "Error: phys_per_port value $PHYS_PER_PORT is non-numeric"
exit 1
fi
if [ -z "$MULTIPATH_MODE" ] ; then
MULTIPATH_MODE=`awk "\\$1 == \"multipath\" \
{print \\$2; exit}" $CONFIG`
MULTIPATH_MODE=$(awk '$1 == "multipath" \
{print $2; exit}' $CONFIG)
fi
if [ -z "$MULTIJBOD_MODE" ] ; then
MULTIJBOD_MODE=$(awk '$1 == "multijbod" \
{print $2; exit}' $CONFIG)
fi
# Use first running component device if we're handling a dm-mpath device
if [ "$MULTIPATH_MODE" = "yes" ] ; then
# If udev didn't tell us the UUID via DM_NAME, check /dev/mapper
if [ -z "$DM_NAME" ] ; then
DM_NAME=`ls -l --full-time /dev/mapper |
awk "/\/$DEV$/{print \\$9}"`
DM_NAME=$(ls -l --full-time /dev/mapper |
grep "$DEV"$ | awk '{print $9}')
fi
# For raw disks udev exports DEVTYPE=partition when
@ -175,28 +285,41 @@ sas_handler() {
# we have to append the -part suffix directly in the
# helper.
if [ "$DEVTYPE" != "partition" ] ; then
PART=`echo $DM_NAME | awk -Fp '/p/{print "-part"$2}'`
PART=$(echo "$DM_NAME" | awk -Fp '/p/{print "-part"$2}')
fi
# Strip off partition information.
DM_NAME=`echo $DM_NAME | sed 's/p[0-9][0-9]*$//'`
DM_NAME=$(echo "$DM_NAME" | sed 's/p[0-9][0-9]*$//')
if [ -z "$DM_NAME" ] ; then
return
fi
# Get the raw scsi device name from multipath -ll. Strip off
# leading pipe symbols to make field numbering consistent.
DEV=`multipath -ll $DM_NAME |
awk '/running/{gsub("^[|]"," "); print $3 ; exit}'`
# Utilize DM device name to gather subordinate block devices
# using sysfs to avoid userspace utilities
DMDEV=$(ls -l --full-time /dev/mapper | grep $DM_NAME |
awk '{gsub("../", " "); print $NF}')
# Use sysfs pointers in /sys/block/dm-X/slaves because using
# userspace tools creates lots of overhead and should be avoided
# whenever possible. Use awk to isolate lowest instance of
# sd device member in dm device group regardless of string
# length.
DEV=$(ls "/sys/block/$DMDEV/slaves" | awk '
{ len=sprintf ("%20s",length($0)); gsub(/ /,0,str); a[NR]=len "_" $0; }
END {
asort(a)
print substr(a[1],22)
}')
if [ -z "$DEV" ] ; then
return
fi
fi
if echo $DEV | grep -q ^/devices/ ; then
if echo "$DEV" | grep -q ^/devices/ ; then
sys_path=$DEV
else
sys_path=`udevadm info -q path -p /sys/block/$DEV 2>/dev/null`
sys_path=$(udevadm info -q path -p "/sys/block/$DEV" 2>/dev/null)
fi
# Use positional parameters as an ad-hoc array
@ -206,84 +329,104 @@ sas_handler() {
# Get path up to /sys/.../hostX
i=1
while [ $i -le $num_dirs ] ; do
d=$(eval echo \${$i})
while [ $i -le "$num_dirs" ] ; do
d=$(eval echo '$'{$i})
scsi_host_dir="$scsi_host_dir/$d"
echo $d | grep -q -E '^host[0-9]+$' && break
i=$(($i + 1))
echo "$d" | grep -q -E '^host[0-9]+$' && break
i=$((i + 1))
done
if [ $i = $num_dirs ] ; then
# Lets grab the SAS host channel number and save it for JBOD sorting later
HOSTCHAN=$(echo "$d" | awk -F/ '{ gsub("host","",$NF); print $NF}')
if [ $i = "$num_dirs" ] ; then
return
fi
PCI_ID=$(eval echo \${$(($i -1))} | awk -F: '{print $2":"$3}')
PCI_ID=$(eval echo '$'{$((i -1))} | awk -F: '{print $2":"$3}')
# In sas_switch mode, the directory four levels beneath
# /sys/.../hostX contains symlinks to phy devices that reveal
# the switch port number. In sas_direct mode, the phy links one
# directory down reveal the HBA port.
port_dir=$scsi_host_dir
case $TOPOLOGY in
"sas_switch") j=$(($i + 4)) ;;
"sas_direct") j=$(($i + 1)) ;;
"sas_switch") j=$((i + 4)) ;;
"sas_direct") j=$((i + 1)) ;;
esac
i=$(($i + 1))
i=$((i + 1))
while [ $i -le $j ] ; do
port_dir="$port_dir/$(eval echo \${$i})"
i=$(($i + 1))
port_dir="$port_dir/$(eval echo '$'{$i})"
i=$((i + 1))
done
PHY=`ls -d $port_dir/phy* 2>/dev/null | head -1 | awk -F: '{print $NF}'`
PHY=$(ls -d "$port_dir"/phy* 2>/dev/null | head -1 | awk -F: '{print $NF}')
if [ -z "$PHY" ] ; then
PHY=0
fi
PORT=$(( $PHY / $PHYS_PER_PORT ))
PORT=$((PHY / PHYS_PER_PORT))
# Look in /sys/.../sas_device/end_device-X for the bay_identifier
# attribute.
end_device_dir=$port_dir
while [ $i -lt $num_dirs ] ; do
d=$(eval echo \${$i})
while [ $i -lt "$num_dirs" ] ; do
d=$(eval echo '$'{$i})
end_device_dir="$end_device_dir/$d"
if echo $d | grep -q '^end_device' ; then
if echo "$d" | grep -q '^end_device' ; then
end_device_dir="$end_device_dir/sas_device/$d"
break
fi
i=$(($i + 1))
i=$((i + 1))
done
# Add 'mix' slot type for environments where dm-multipath devices
# include end-devices connected via SAS expanders or direct connection
# to SAS HBA. A mixed connectivity environment such as pool devices
# contained in a SAS JBOD and spare drives or log devices directly
# connected in a server backplane without expanders in the I/O path.
SLOT=
case $BAY in
"bay")
SLOT=`cat $end_device_dir/bay_identifier 2>/dev/null`
SLOT=$(cat "$end_device_dir/bay_identifier" 2>/dev/null)
;;
"mix")
if [ $(cat "$end_device_dir/bay_identifier" 2>/dev/null) ] ; then
SLOT=$(cat "$end_device_dir/bay_identifier" 2>/dev/null)
else
SLOT=$(cat "$end_device_dir/phy_identifier" 2>/dev/null)
fi
;;
"phy")
SLOT=`cat $end_device_dir/phy_identifier 2>/dev/null`
SLOT=$(cat "$end_device_dir/phy_identifier" 2>/dev/null)
;;
"port")
d=$(eval echo \${$i})
SLOT=`echo $d | sed -e 's/^.*://'`
d=$(eval echo '$'{$i})
SLOT=$(echo "$d" | sed -e 's/^.*://')
;;
"id")
i=$(($i + 1))
d=$(eval echo \${$i})
SLOT=`echo $d | sed -e 's/^.*://'`
i=$((i + 1))
d=$(eval echo '$'{$i})
SLOT=$(echo "$d" | sed -e 's/^.*://')
;;
"lun")
i=$(($i + 2))
d=$(eval echo \${$i})
SLOT=`echo $d | sed -e 's/^.*://'`
i=$((i + 2))
d=$(eval echo '$'{$i})
SLOT=$(echo "$d" | sed -e 's/^.*://')
;;
"ses")
# look for this SAS path in all SCSI Enclosure Services
# (SES) enclosures
sas_address=`cat $end_device_dir/sas_address 2>/dev/null`
enclosures=`lsscsi -g | \
sed -n -e '/enclosu/s/^.* \([^ ][^ ]*\) *$/\1/p'`
sas_address=$(cat "$end_device_dir/sas_address" 2>/dev/null)
enclosures=$(lsscsi -g | \
sed -n -e '/enclosu/s/^.* \([^ ][^ ]*\) *$/\1/p')
for enclosure in $enclosures; do
set -- $(sg_ses -p aes $enclosure | \
set -- $(sg_ses -p aes "$enclosure" | \
awk "/device slot number:/{slot=\$12} \
/SAS address: $sas_address/\
{print slot}")
@ -298,42 +441,55 @@ sas_handler() {
return
fi
CHAN=`map_channel $PCI_ID $PORT`
SLOT=`map_slot $SLOT $CHAN`
if [ -z "$CHAN" ] ; then
return
if [ "$MULTIJBOD_MODE" = "yes" ] ; then
CHAN=$(map_channel "$PCI_ID" "$PORT")
SLOT=$(map_slot "$SLOT" "$CHAN")
JBOD=$(map_jbod "$DEV")
if [ -z "$CHAN" ] ; then
return
fi
echo "${CHAN}"-"${JBOD}"-"${SLOT}${PART}"
else
CHAN=$(map_channel "$PCI_ID" "$PORT")
SLOT=$(map_slot "$SLOT" "$CHAN")
if [ -z "$CHAN" ] ; then
return
fi
echo "${CHAN}${SLOT}${PART}"
fi
echo ${CHAN}${SLOT}${PART}
}
scsi_handler() {
if [ -z "$FIRST_BAY_NUMBER" ] ; then
FIRST_BAY_NUMBER=`awk "\\$1 == \"first_bay_number\" \
{print \\$2; exit}" $CONFIG`
FIRST_BAY_NUMBER=$(awk '$1 == "first_bay_number" \
{print $2; exit}' $CONFIG)
fi
FIRST_BAY_NUMBER=${FIRST_BAY_NUMBER:-0}
if [ -z "$PHYS_PER_PORT" ] ; then
PHYS_PER_PORT=`awk "\\$1 == \"phys_per_port\" \
{print \\$2; exit}" $CONFIG`
PHYS_PER_PORT=$(awk '$1 == "phys_per_port" \
{print $2; exit}' $CONFIG)
fi
PHYS_PER_PORT=${PHYS_PER_PORT:-4}
if ! echo $PHYS_PER_PORT | grep -q -E '^[0-9]+$' ; then
if ! echo "$PHYS_PER_PORT" | grep -q -E '^[0-9]+$' ; then
echo "Error: phys_per_port value $PHYS_PER_PORT is non-numeric"
exit 1
fi
if [ -z "$MULTIPATH_MODE" ] ; then
MULTIPATH_MODE=`awk "\\$1 == \"multipath\" \
{print \\$2; exit}" $CONFIG`
MULTIPATH_MODE=$(awk '$1 == "multipath" \
{print $2; exit}' $CONFIG)
fi
# Use first running component device if we're handling a dm-mpath device
if [ "$MULTIPATH_MODE" = "yes" ] ; then
# If udev didn't tell us the UUID via DM_NAME, check /dev/mapper
if [ -z "$DM_NAME" ] ; then
DM_NAME=`ls -l --full-time /dev/mapper |
awk "/\/$DEV$/{print \\$9}"`
DM_NAME=$(ls -l --full-time /dev/mapper |
grep "$DEV"$ | awk '{print $9}')
fi
# For raw disks udev exports DEVTYPE=partition when
@ -343,28 +499,28 @@ scsi_handler() {
# we have to append the -part suffix directly in the
# helper.
if [ "$DEVTYPE" != "partition" ] ; then
PART=`echo $DM_NAME | awk -Fp '/p/{print "-part"$2}'`
PART=$(echo "$DM_NAME" | awk -Fp '/p/{print "-part"$2}')
fi
# Strip off partition information.
DM_NAME=`echo $DM_NAME | sed 's/p[0-9][0-9]*$//'`
DM_NAME=$(echo "$DM_NAME" | sed 's/p[0-9][0-9]*$//')
if [ -z "$DM_NAME" ] ; then
return
fi
# Get the raw scsi device name from multipath -ll. Strip off
# leading pipe symbols to make field numbering consistent.
DEV=`multipath -ll $DM_NAME |
awk '/running/{gsub("^[|]"," "); print $3 ; exit}'`
DEV=$(multipath -ll "$DM_NAME" |
awk '/running/{gsub("^[|]"," "); print $3 ; exit}')
if [ -z "$DEV" ] ; then
return
fi
fi
if echo $DEV | grep -q ^/devices/ ; then
if echo "$DEV" | grep -q ^/devices/ ; then
sys_path=$DEV
else
sys_path=`udevadm info -q path -p /sys/block/$DEV 2>/dev/null`
sys_path=$(udevadm info -q path -p "/sys/block/$DEV" 2>/dev/null)
fi
# expect sys_path like this, for example:
@ -377,44 +533,47 @@ scsi_handler() {
# Get path up to /sys/.../hostX
i=1
while [ $i -le $num_dirs ] ; do
d=$(eval echo \${$i})
while [ $i -le "$num_dirs" ] ; do
d=$(eval echo '$'{$i})
scsi_host_dir="$scsi_host_dir/$d"
echo $d | grep -q -E '^host[0-9]+$' && break
i=$(($i + 1))
echo "$d" | grep -q -E '^host[0-9]+$' && break
i=$((i + 1))
done
if [ $i = $num_dirs ] ; then
if [ $i = "$num_dirs" ] ; then
return
fi
PCI_ID=$(eval echo \${$(($i -1))} | awk -F: '{print $2":"$3}')
PCI_ID=$(eval echo '$'{$((i -1))} | awk -F: '{print $2":"$3}')
# In scsi mode, the directory two levels beneath
# /sys/.../hostX reveals the port and slot.
port_dir=$scsi_host_dir
j=$(($i + 2))
j=$((i + 2))
i=$(($i + 1))
i=$((i + 1))
while [ $i -le $j ] ; do
port_dir="$port_dir/$(eval echo \${$i})"
i=$(($i + 1))
port_dir="$port_dir/$(eval echo '$'{$i})"
i=$((i + 1))
done
set -- $(echo $port_dir | sed -e 's/^.*:\([^:]*\):\([^:]*\)$/\1 \2/')
set -- $(echo "$port_dir" | sed -e 's/^.*:\([^:]*\):\([^:]*\)$/\1 \2/')
PORT=$1
SLOT=$(($2 + $FIRST_BAY_NUMBER))
SLOT=$(($2 + FIRST_BAY_NUMBER))
if [ -z "$SLOT" ] ; then
return
fi
CHAN=`map_channel $PCI_ID $PORT`
SLOT=`map_slot $SLOT $CHAN`
CHAN=$(map_channel "$PCI_ID" "$PORT")
SLOT=$(map_slot "$SLOT" "$CHAN")
if [ -z "$CHAN" ] ; then
return
fi
echo ${CHAN}${SLOT}${PART}
echo "${CHAN}${SLOT}${PART}"
}
# Figure out the name for the enclosure symlink
@ -425,7 +584,7 @@ enclosure_handler () {
# Get the enclosure ID ("0:0:0:0")
ENC=$(basename $(readlink -m "/sys/$DEVPATH/../.."))
if [ ! -d /sys/class/enclosure/$ENC ] ; then
if [ ! -d "/sys/class/enclosure/$ENC" ] ; then
# Not an enclosure, bail out
return
fi
@ -433,14 +592,14 @@ enclosure_handler () {
# Get the long sysfs device path to our enclosure. Looks like:
# /devices/pci0000:00/0000:00:03.0/0000:05:00.0/host0/port-0:0/ ... /enclosure/0:0:0:0
ENC_DEVICE=$(readlink /sys/class/enclosure/$ENC)
ENC_DEVICE=$(readlink "/sys/class/enclosure/$ENC")
# Grab the full path to the hosts port dir:
# /devices/pci0000:00/0000:00:03.0/0000:05:00.0/host0/port-0:0
PORT_DIR=$(echo $ENC_DEVICE | grep -Eo '.+host[0-9]+/port-[0-9]+:[0-9]+')
PORT_DIR=$(echo "$ENC_DEVICE" | grep -Eo '.+host[0-9]+/port-[0-9]+:[0-9]+')
# Get the port number
PORT_ID=$(echo $PORT_DIR | grep -Eo "[0-9]+$")
PORT_ID=$(echo "$PORT_DIR" | grep -Eo "[0-9]+$")
# The PCI directory is two directories up from the port directory
# /sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0
@ -450,8 +609,8 @@ enclosure_handler () {
PCI_ID=$(echo "$PCI_ID_LONG" | sed -r 's/^[0-9]+://g')
# Name our device according to vdev_id.conf (like "L0" or "U1").
NAME=$(awk "/channel/{if (\$1 == \"channel\" && \$2 == \"$PCI_ID\" && \
\$3 == \"$PORT_ID\") {print \$4int(count[\$4])}; count[\$4]++}" $CONFIG)
NAME=$(awk '/channel/{if ($1 == "channel" && $2 == "$PCI_ID" && \
$3 == "$PORT_ID") {print ${4}int(count[$4])}; count[$4]++}' $CONFIG)
echo "${NAME}"
}
@ -487,9 +646,9 @@ alias_handler () {
# ambiguity seems unavoidable, so devices using this facility
# must not use such names.
DM_PART=
if echo $DM_NAME | grep -q -E 'p[0-9][0-9]*$' ; then
if echo "$DM_NAME" | grep -q -E 'p[0-9][0-9]*$' ; then
if [ "$DEVTYPE" != "partition" ] ; then
DM_PART=`echo $DM_NAME | awk -Fp '/p/{print "-part"$2}'`
DM_PART=$(echo "$DM_NAME" | awk -Fp '/p/{print "-part"$2}')
fi
fi
@ -497,21 +656,25 @@ alias_handler () {
for link in $DEVLINKS ; do
# Remove partition information to match key of top-level device.
if [ -n "$DM_PART" ] ; then
link=`echo $link | sed 's/p[0-9][0-9]*$//'`
link=$(echo "$link" | sed 's/p[0-9][0-9]*$//')
fi
# Check both the fully qualified and the base name of link.
for l in $link `basename $link` ; do
alias=`awk "\\$1 == \"alias\" && \\$3 == \"${l}\" \
{ print \\$2; exit }" $CONFIG`
if [ -n "$alias" ] ; then
echo ${alias}${DM_PART}
return
for l in $link $(basename "$link") ; do
if [ ! -z "$l" ]; then
alias=$(awk -v var="$l" '($1 == "alias") && \
($3 == var) \
{ print $2; exit }' $CONFIG)
if [ -n "$alias" ] ; then
echo "${alias}${DM_PART}"
return
fi
fi
done
done
}
while getopts 'c:d:eg:mp:h' OPTION; do
# main
while getopts 'c:d:eg:jmp:h' OPTION; do
case ${OPTION} in
c)
CONFIG=${OPTARG}
@ -524,7 +687,9 @@ while getopts 'c:d:eg:mp:h' OPTION; do
# create the enclosure device symlinks only. We also need
# "enclosure_symlinks yes" set in vdev_id.config to actually create the
# symlink.
ENCLOSURE_MODE=$(awk '{if ($1 == "enclosure_symlinks") print $2}' $CONFIG)
ENCLOSURE_MODE=$(awk '{if ($1 == "enclosure_symlinks") \
print $2}' "$CONFIG")
if [ "$ENCLOSURE_MODE" != "yes" ] ; then
exit 0
fi
@ -535,6 +700,9 @@ while getopts 'c:d:eg:mp:h' OPTION; do
p)
PHYS_PER_PORT=${OPTARG}
;;
j)
MULTIJBOD_MODE=yes
;;
m)
MULTIPATH_MODE=yes
;;
@ -544,7 +712,8 @@ while getopts 'c:d:eg:mp:h' OPTION; do
esac
done
if [ ! -r $CONFIG ] ; then
if [ ! -r "$CONFIG" ] ; then
echo "Error: Config file \"$CONFIG\" not found"
exit 0
fi
@ -554,11 +723,11 @@ if [ -z "$DEV" ] && [ -z "$ENCLOSURE_MODE" ] ; then
fi
if [ -z "$TOPOLOGY" ] ; then
TOPOLOGY=`awk "\\$1 == \"topology\" {print \\$2; exit}" $CONFIG`
TOPOLOGY=$(awk '($1 == "topology") {print $2; exit}' "$CONFIG")
fi
if [ -z "$BAY" ] ; then
BAY=`awk "\\$1 == \"slot\" {print \\$2; exit}" $CONFIG`
BAY=$(awk '($1 == "slot") {print $2; exit}' "$CONFIG")
fi
TOPOLOGY=${TOPOLOGY:-sas_direct}
@ -571,7 +740,7 @@ if [ "$ENCLOSURE_MODE" = "yes" ] && [ "$TOPOLOGY" = "sas_direct" ] ; then
fi
# Just create the symlinks to the enclosure devices and then exit.
ENCLOSURE_PREFIX=$(awk '/enclosure_symlinks_prefix/{print $2}' $CONFIG)
ENCLOSURE_PREFIX=$(awk '/enclosure_symlinks_prefix/{print $2}' "$CONFIG")
if [ -z "$ENCLOSURE_PREFIX" ] ; then
ENCLOSURE_PREFIX="enc"
fi
@ -581,16 +750,16 @@ if [ "$ENCLOSURE_MODE" = "yes" ] && [ "$TOPOLOGY" = "sas_direct" ] ; then
fi
# First check if an alias was defined for this device.
ID_VDEV=`alias_handler`
ID_VDEV=$(alias_handler)
if [ -z "$ID_VDEV" ] ; then
BAY=${BAY:-bay}
case $TOPOLOGY in
sas_direct|sas_switch)
ID_VDEV=`sas_handler`
ID_VDEV=$(sas_handler)
;;
scsi)
ID_VDEV=`scsi_handler`
ID_VDEV=$(scsi_handler)
;;
*)
echo "Error: unknown topology $TOPOLOGY"

View File

@ -14,3 +14,5 @@ zdb_LDADD = \
$(abs_top_builddir)/lib/libzpool/libzpool.la \
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
include $(top_srcdir)/config/CppCheck.am

View File

@ -31,6 +31,7 @@
*
* [1] Portions of this software were developed by Allan Jude
* under sponsorship from the FreeBSD Foundation.
* Copyright (c) 2021 Allan Jude
*/
#include <stdio.h>
@ -755,13 +756,14 @@ usage(void)
"\t%s -m [-AFLPX] [-e [-V] [-p <path> ...]] [-t <txg>] "
"[-U <cache>]\n\t\t<poolname> [<vdev> [<metaslab> ...]]\n"
"\t%s -O <dataset> <path>\n"
"\t%s -r <dataset> <path> <destination>\n"
"\t%s -R [-A] [-e [-V] [-p <path> ...]] [-U <cache>]\n"
"\t\t<poolname> <vdev>:<offset>:<size>[:<flags>]\n"
"\t%s -E [-A] word0:word1:...:word15\n"
"\t%s -S [-AP] [-e [-V] [-p <path> ...]] [-U <cache>] "
"<poolname>\n\n",
cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname,
cmdname, cmdname, cmdname);
cmdname, cmdname, cmdname, cmdname);
(void) fprintf(stderr, " Dataset name must include at least one "
"separator character '/' or '@'\n");
@ -800,6 +802,7 @@ usage(void)
(void) fprintf(stderr, " -m metaslabs\n");
(void) fprintf(stderr, " -M metaslab groups\n");
(void) fprintf(stderr, " -O perform object lookups by path\n");
(void) fprintf(stderr, " -r copy an object by path to file\n");
(void) fprintf(stderr, " -R read and display block from a "
"device\n");
(void) fprintf(stderr, " -s report stats on zdb's I/O\n");
@ -4490,7 +4493,7 @@ static char curpath[PATH_MAX];
* for the last one.
*/
static int
dump_path_impl(objset_t *os, uint64_t obj, char *name)
dump_path_impl(objset_t *os, uint64_t obj, char *name, uint64_t *retobj)
{
int err;
boolean_t header = B_TRUE;
@ -4540,10 +4543,15 @@ dump_path_impl(objset_t *os, uint64_t obj, char *name)
switch (doi.doi_type) {
case DMU_OT_DIRECTORY_CONTENTS:
if (s != NULL && *(s + 1) != '\0')
return (dump_path_impl(os, child_obj, s + 1));
return (dump_path_impl(os, child_obj, s + 1, retobj));
/*FALLTHROUGH*/
case DMU_OT_PLAIN_FILE_CONTENTS:
dump_object(os, child_obj, dump_opt['v'], &header, NULL, 0);
if (retobj != NULL) {
*retobj = child_obj;
} else {
dump_object(os, child_obj, dump_opt['v'], &header,
NULL, 0);
}
return (0);
default:
(void) fprintf(stderr, "object %llu has non-file/directory "
@ -4558,7 +4566,7 @@ dump_path_impl(objset_t *os, uint64_t obj, char *name)
* Dump the blocks for the object specified by path inside the dataset.
*/
static int
dump_path(char *ds, char *path)
dump_path(char *ds, char *path, uint64_t *retobj)
{
int err;
objset_t *os;
@ -4578,12 +4586,89 @@ dump_path(char *ds, char *path)
(void) snprintf(curpath, sizeof (curpath), "dataset=%s path=/", ds);
err = dump_path_impl(os, root_obj, path);
err = dump_path_impl(os, root_obj, path, retobj);
close_objset(os, FTAG);
return (err);
}
static int
zdb_copy_object(objset_t *os, uint64_t srcobj, char *destfile)
{
int err = 0;
uint64_t size, readsize, oursize, offset;
ssize_t writesize;
sa_handle_t *hdl;
(void) printf("Copying object %" PRIu64 " to file %s\n", srcobj,
destfile);
VERIFY3P(os, ==, sa_os);
if ((err = sa_handle_get(os, srcobj, NULL, SA_HDL_PRIVATE, &hdl))) {
(void) printf("Failed to get handle for SA znode\n");
return (err);
}
if ((err = sa_lookup(hdl, sa_attr_table[ZPL_SIZE], &size, 8))) {
(void) sa_handle_destroy(hdl);
return (err);
}
(void) sa_handle_destroy(hdl);
(void) printf("Object %" PRIu64 " is %" PRIu64 " bytes\n", srcobj,
size);
if (size == 0) {
return (EINVAL);
}
int fd = open(destfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
/*
* We cap the size at 1 mebibyte here to prevent
* allocation failures and nigh-infinite printing if the
* object is extremely large.
*/
oursize = MIN(size, 1 << 20);
offset = 0;
char *buf = kmem_alloc(oursize, KM_NOSLEEP);
if (buf == NULL) {
return (ENOMEM);
}
while (offset < size) {
readsize = MIN(size - offset, 1 << 20);
err = dmu_read(os, srcobj, offset, readsize, buf, 0);
if (err != 0) {
(void) printf("got error %u from dmu_read\n", err);
kmem_free(buf, oursize);
return (err);
}
if (dump_opt['v'] > 3) {
(void) printf("Read offset=%" PRIu64 " size=%" PRIu64
" error=%d\n", offset, readsize, err);
}
writesize = write(fd, buf, readsize);
if (writesize < 0) {
err = errno;
break;
} else if (writesize != readsize) {
/* Incomplete write */
(void) fprintf(stderr, "Short write, only wrote %llu of"
" %" PRIu64 " bytes, exiting...\n",
(u_longlong_t)writesize, readsize);
break;
}
offset += readsize;
}
(void) close(fd);
if (buf != NULL)
kmem_free(buf, oursize);
return (err);
}
static int
dump_label(const char *dev)
{
@ -5844,6 +5929,7 @@ zdb_leak_init_prepare_indirect_vdevs(spa_t *spa, zdb_cb_t *zcb)
* metaslabs. We want to set them up for
* zio_claim().
*/
vdev_metaslab_group_create(vd);
VERIFY0(vdev_metaslab_init(vd, 0));
vdev_indirect_mapping_t *vim = vd->vdev_indirect_mapping;
@ -5882,6 +5968,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;
zcb->zcb_vd_obsolete_counts =
umem_zalloc(rvd->vdev_children * sizeof (uint32_t *),
@ -6015,7 +6102,6 @@ zdb_leak_fini(spa_t *spa, zdb_cb_t *zcb)
vdev_t *rvd = spa->spa_root_vdev;
for (unsigned c = 0; c < rvd->vdev_children; c++) {
vdev_t *vd = rvd->vdev_child[c];
metaslab_group_t *mg __maybe_unused = vd->vdev_mg;
if (zcb->zcb_vd_obsolete_counts[c] != NULL) {
leaks |= zdb_check_for_obsolete_leaks(vd, zcb);
@ -6023,7 +6109,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(mg, ==, msp->ms_group);
ASSERT3P(msp->ms_group, ==, (msp->ms_group->mg_class ==
spa_embedded_log_class(spa)) ?
vd->vdev_log_mg : vd->vdev_mg);
/*
* ms_allocatable has been overloaded
@ -6230,6 +6318,8 @@ dump_block_stats(spa_t *spa)
zcb.zcb_totalasize = metaslab_class_get_alloc(spa_normal_class(spa));
zcb.zcb_totalasize += metaslab_class_get_alloc(spa_special_class(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_start = zcb.zcb_lastprint = gethrtime();
err = traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
@ -6277,6 +6367,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_class(spa)) +
metaslab_class_get_alloc(spa_dedup_class(spa)) +
get_unflushed_alloc_space(spa);
@ -6344,6 +6435,17 @@ dump_block_stats(spa_t *spa)
100.0 * alloc / space);
}
if (spa_embedded_log_class(spa)->mc_allocator[0].mca_rotor != NULL) {
uint64_t alloc = metaslab_class_get_alloc(
spa_embedded_log_class(spa));
uint64_t space = metaslab_class_get_space(
spa_embedded_log_class(spa));
(void) printf("\t%-16s %14llu used: %5.2f%%\n",
"Embedded log class", (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;
@ -8150,6 +8252,7 @@ main(int argc, char **argv)
nvlist_t *policy = NULL;
uint64_t max_txg = UINT64_MAX;
int64_t objset_id = -1;
uint64_t object;
int flags = ZFS_IMPORT_MISSING_LOG;
int rewind = ZPOOL_NEVER_REWIND;
char *spa_config_path_env, *objset_str;
@ -8178,7 +8281,7 @@ main(int argc, char **argv)
zfs_btree_verify_intensity = 3;
while ((c = getopt(argc, argv,
"AbcCdDeEFGhiI:klLmMo:Op:PqRsSt:uU:vVx:XYyZ")) != -1) {
"AbcCdDeEFGhiI:klLmMo:Op:PqrRsSt:uU:vVx:XYyZ")) != -1) {
switch (c) {
case 'b':
case 'c':
@ -8193,6 +8296,7 @@ main(int argc, char **argv)
case 'm':
case 'M':
case 'O':
case 'r':
case 'R':
case 's':
case 'S':
@ -8282,7 +8386,7 @@ main(int argc, char **argv)
(void) fprintf(stderr, "-p option requires use of -e\n");
usage();
}
if (dump_opt['d']) {
if (dump_opt['d'] || dump_opt['r']) {
/* <pool>[/<dataset | objset id> is accepted */
if (argv[2] && (objset_str = strchr(argv[2], '/')) != NULL &&
objset_str++ != NULL) {
@ -8341,7 +8445,7 @@ main(int argc, char **argv)
verbose = MAX(verbose, 1);
for (c = 0; c < 256; c++) {
if (dump_all && strchr("AeEFklLOPRSXy", c) == NULL)
if (dump_all && strchr("AeEFklLOPrRSXy", c) == NULL)
dump_opt[c] = 1;
if (dump_opt[c])
dump_opt[c] += verbose;
@ -8377,7 +8481,13 @@ main(int argc, char **argv)
if (argc != 2)
usage();
dump_opt['v'] = verbose + 3;
return (dump_path(argv[0], argv[1]));
return (dump_path(argv[0], argv[1], NULL));
}
if (dump_opt['r']) {
if (argc != 3)
usage();
dump_opt['v'] = verbose;
error = dump_path(argv[0], argv[1], &object);
}
if (dump_opt['X'] || dump_opt['F'])
@ -8555,7 +8665,9 @@ main(int argc, char **argv)
argv++;
argc--;
if (!dump_opt['R']) {
if (dump_opt['r']) {
error = zdb_copy_object(os, object, argv[1]);
} else if (!dump_opt['R']) {
flagbits['d'] = ZOR_FLAG_DIRECTORY;
flagbits['f'] = ZOR_FLAG_PLAIN_FILE;
flagbits['m'] = ZOR_FLAG_SPACE_MAP;

View File

@ -47,3 +47,5 @@ zed_LDADD += -lrt $(LIBUDEV_LIBS) $(LIBUUID_LIBS)
zed_LDFLAGS = -pthread
EXTRA_DIST = agents/README.md
include $(top_srcdir)/config/CppCheck.am

View File

@ -13,6 +13,7 @@
/*
* Copyright (c) 2016, Intel Corporation.
* Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>
* Copyright (c) 2021 Hewlett Packard Enterprise Development LP
*/
#include <libnvpair.h>
@ -211,12 +212,18 @@ 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.
*/
(void) nvlist_lookup_string(nvl, DEV_IDENTIFIER,
&search.gs_devid);
(void) zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search);
pool_guid = search.gs_pool_guid;
vdev_guid = search.gs_vdev_guid;
devtype = search.gs_vdev_type;
if (pool_guid == 0 || vdev_guid == 0) {
if ((nvlist_lookup_string(nvl, DEV_IDENTIFIER,
&search.gs_devid) == 0) &&
(zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search)
== 1)) {
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

View File

@ -334,7 +334,7 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
*/
if (strcmp(class, "resource.fs.zfs.removed") == 0 ||
(strcmp(class, "resource.fs.zfs.statechange") == 0 &&
state == VDEV_STATE_REMOVED)) {
(state == VDEV_STATE_REMOVED || state == VDEV_STATE_FAULTED))) {
char *devtype;
char *devname;

0
sys/contrib/openzfs/cmd/zed/zed.d/zed-functions.sh Executable file → Normal file
View File

View File

@ -21,3 +21,5 @@ zfs_LDADD += $(LTLIBINTL)
if BUILD_FREEBSD
zfs_LDADD += -lgeom -ljail
endif
include $(top_srcdir)/config/CppCheck.am

View File

@ -7,3 +7,5 @@ zfs_ids_to_path_SOURCES = \
zfs_ids_to_path_LDADD = \
$(abs_top_builddir)/lib/libzfs/libzfs.la
include $(top_srcdir)/config/CppCheck.am

View File

@ -1,5 +1,7 @@
include $(top_srcdir)/config/Rules.am
bin_PROGRAMS = zgenhostid
sbin_PROGRAMS = zgenhostid
zgenhostid_SOURCES = zgenhostid.c
include $(top_srcdir)/config/CppCheck.am

View File

@ -12,3 +12,5 @@ zhack_LDADD = \
$(abs_top_builddir)/lib/libzpool/libzpool.la \
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
include $(top_srcdir)/config/CppCheck.am

View File

@ -11,3 +11,5 @@ zinject_LDADD = \
$(abs_top_builddir)/lib/libzfs/libzfs.la \
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
include $(top_srcdir)/config/CppCheck.am

View File

@ -34,6 +34,8 @@ zpool_LDADD += -lgeom
endif
zpool_LDADD += -lm $(LIBBLKID_LIBS) $(LIBUUID_LIBS)
include $(top_srcdir)/config/CppCheck.am
zpoolconfdir = $(sysconfdir)/zfs/zpool.d
zpoolexecdir = $(zfsexecdir)/zpool.d

View File

@ -1653,7 +1653,8 @@ zpool_do_create(int argc, char **argv)
if (strcmp(propval, ZFS_FEATURE_DISABLED) == 0)
(void) nvlist_remove_all(props,
propname);
} else if (enable_all_pool_feat) {
} else if (enable_all_pool_feat &&
feat->fi_zfs_mod_supported) {
ret = add_prop_list(propname,
ZFS_FEATURE_ENABLED, &props, B_TRUE);
if (ret != 0)
@ -2009,7 +2010,7 @@ zpool_print_cmd(vdev_cmd_data_list_t *vcdl, const char *pool, char *path)
* Mark empty values with dashes to make output
* awk-able.
*/
if (is_blank_str(val))
if (val == NULL || is_blank_str(val))
val = "-";
printf("%*s", vcdl->uniq_cols_width[j], val);
@ -9063,7 +9064,7 @@ print_history_records(nvlist_t *nvhis, hist_cbdata_t *cb)
&records, &numrecords) == 0);
for (i = 0; i < numrecords; i++) {
nvlist_t *rec = records[i];
char tbuf[30] = "";
char tbuf[64] = "";
if (nvlist_exists(rec, ZPOOL_HIST_TIME)) {
time_t tsec;
@ -9075,6 +9076,14 @@ print_history_records(nvlist_t *nvhis, hist_cbdata_t *cb)
(void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
}
if (nvlist_exists(rec, ZPOOL_HIST_ELAPSED_NS)) {
uint64_t elapsed_ns = fnvlist_lookup_int64(records[i],
ZPOOL_HIST_ELAPSED_NS);
(void) snprintf(tbuf + strlen(tbuf),
sizeof (tbuf) - strlen(tbuf),
" (%lldms)", (long long)elapsed_ns / 1000 / 1000);
}
if (nvlist_exists(rec, ZPOOL_HIST_CMD)) {
(void) printf("%s %s", tbuf,
fnvlist_lookup_string(rec, ZPOOL_HIST_CMD));

View File

@ -9,3 +9,5 @@ zpool_influxdb_LDADD = \
$(top_builddir)/lib/libspl/libspl.la \
$(top_builddir)/lib/libnvpair/libnvpair.la \
$(top_builddir)/lib/libzfs/libzfs.la
include $(top_srcdir)/config/CppCheck.am

View File

@ -13,3 +13,5 @@ zstream_LDADD = \
$(abs_top_builddir)/lib/libzfs/libzfs.la \
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
include $(top_srcdir)/config/CppCheck.am

View File

@ -21,3 +21,5 @@ ztest_LDADD = \
ztest_LDADD += -lm
ztest_LDFLAGS = -pthread
include $(top_srcdir)/config/CppCheck.am

File diff suppressed because it is too large Load Diff

View File

@ -8,3 +8,5 @@ udev_PROGRAMS = zvol_id
zvol_id_SOURCES = \
zvol_id_main.c
include $(top_srcdir)/config/CppCheck.am

View File

@ -0,0 +1,11 @@
#
# Default rules for running cppcheck against the the user space components.
#
PHONY += cppcheck
CPPCHECKFLAGS = --std=c99 --quiet --max-configs=1 --error-exitcode=2
CPPCHECKFLAGS += --inline-suppr -U_KERNEL
cppcheck:
$(CPPCHECK) -j$(CPU_COUNT) $(CPPCHECKFLAGS) $(DEFAULT_INCLUDES) $(SOURCES)

View File

@ -3,6 +3,7 @@
# should include these rules and override or extend them as needed.
#
PHONY =
DEFAULT_INCLUDES = \
-include $(top_builddir)/zfs_config.h \
-I$(top_builddir)/include \

View File

@ -0,0 +1,6 @@
dnl #
dnl # Check if cppcheck is available.
dnl #
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CPPCHECK], [
AC_CHECK_PROG([CPPCHECK], [cppcheck], [cppcheck])
])

View File

@ -0,0 +1,101 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_count_cpus.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_COUNT_CPUS([ACTION-IF-DETECTED],[ACTION-IF-NOT-DETECTED])
#
# DESCRIPTION
#
# Attempt to count the number of logical processor cores (including
# virtual and HT cores) currently available to use on the machine and
# place detected value in CPU_COUNT variable.
#
# On successful detection, ACTION-IF-DETECTED is executed if present. If
# the detection fails, then ACTION-IF-NOT-DETECTED is triggered. The
# default ACTION-IF-NOT-DETECTED is to set CPU_COUNT to 1.
#
# LICENSE
#
# Copyright (c) 2014,2016 Karlson2k (Evgeny Grin) <k2k@narod.ru>
# Copyright (c) 2012 Brian Aker <brian@tangent.org>
# Copyright (c) 2008 Michael Paul Bailey <jinxidoru@byu.net>
# Copyright (c) 2008 Christophe Tournayre <turn3r@users.sourceforge.net>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 22
AC_DEFUN([AX_COUNT_CPUS],[dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([AC_PROG_EGREP])dnl
AC_MSG_CHECKING([the number of available CPUs])
CPU_COUNT="0"
# Try generic methods
# 'getconf' is POSIX utility, but '_NPROCESSORS_ONLN' and
# 'NPROCESSORS_ONLN' are platform-specific
command -v getconf >/dev/null 2>&1 && \
CPU_COUNT=`getconf _NPROCESSORS_ONLN 2>/dev/null || getconf NPROCESSORS_ONLN 2>/dev/null` || CPU_COUNT="0"
AS_IF([[test "$CPU_COUNT" -gt "0" 2>/dev/null || ! command -v nproc >/dev/null 2>&1]],[[: # empty]],[dnl
# 'nproc' is part of GNU Coreutils and is widely available
CPU_COUNT=`OMP_NUM_THREADS='' nproc 2>/dev/null` || CPU_COUNT=`nproc 2>/dev/null` || CPU_COUNT="0"
])dnl
AS_IF([[test "$CPU_COUNT" -gt "0" 2>/dev/null]],[[: # empty]],[dnl
# Try platform-specific preferred methods
AS_CASE([[$host_os]],dnl
[[*linux*]],[[CPU_COUNT=`lscpu -p 2>/dev/null | $EGREP -e '^@<:@0-9@:>@+,' -c` || CPU_COUNT="0"]],dnl
[[*darwin*]],[[CPU_COUNT=`sysctl -n hw.logicalcpu 2>/dev/null` || CPU_COUNT="0"]],dnl
[[freebsd*]],[[command -v sysctl >/dev/null 2>&1 && CPU_COUNT=`sysctl -n kern.smp.cpus 2>/dev/null` || CPU_COUNT="0"]],dnl
[[netbsd*]], [[command -v sysctl >/dev/null 2>&1 && CPU_COUNT=`sysctl -n hw.ncpuonline 2>/dev/null` || CPU_COUNT="0"]],dnl
[[solaris*]],[[command -v psrinfo >/dev/null 2>&1 && CPU_COUNT=`psrinfo 2>/dev/null | $EGREP -e '^@<:@0-9@:>@.*on-line' -c 2>/dev/null` || CPU_COUNT="0"]],dnl
[[mingw*]],[[CPU_COUNT=`ls -qpU1 /proc/registry/HKEY_LOCAL_MACHINE/HARDWARE/DESCRIPTION/System/CentralProcessor/ 2>/dev/null | $EGREP -e '^@<:@0-9@:>@+/' -c` || CPU_COUNT="0"]],dnl
[[msys*]],[[CPU_COUNT=`ls -qpU1 /proc/registry/HKEY_LOCAL_MACHINE/HARDWARE/DESCRIPTION/System/CentralProcessor/ 2>/dev/null | $EGREP -e '^@<:@0-9@:>@+/' -c` || CPU_COUNT="0"]],dnl
[[cygwin*]],[[CPU_COUNT=`ls -qpU1 /proc/registry/HKEY_LOCAL_MACHINE/HARDWARE/DESCRIPTION/System/CentralProcessor/ 2>/dev/null | $EGREP -e '^@<:@0-9@:>@+/' -c` || CPU_COUNT="0"]]dnl
)dnl
])dnl
AS_IF([[test "$CPU_COUNT" -gt "0" 2>/dev/null || ! command -v sysctl >/dev/null 2>&1]],[[: # empty]],[dnl
# Try less preferred generic method
# 'hw.ncpu' exist on many platforms, but not on GNU/Linux
CPU_COUNT=`sysctl -n hw.ncpu 2>/dev/null` || CPU_COUNT="0"
])dnl
AS_IF([[test "$CPU_COUNT" -gt "0" 2>/dev/null]],[[: # empty]],[dnl
# Try platform-specific fallback methods
# They can be less accurate and slower then preferred methods
AS_CASE([[$host_os]],dnl
[[*linux*]],[[CPU_COUNT=`$EGREP -e '^processor' -c /proc/cpuinfo 2>/dev/null` || CPU_COUNT="0"]],dnl
[[*darwin*]],[[CPU_COUNT=`system_profiler SPHardwareDataType 2>/dev/null | $EGREP -i -e 'number of cores:'|cut -d : -f 2 -s|tr -d ' '` || CPU_COUNT="0"]],dnl
[[freebsd*]],[[CPU_COUNT=`dmesg 2>/dev/null| $EGREP -e '^cpu@<:@0-9@:>@+: '|sort -u|$EGREP -e '^' -c` || CPU_COUNT="0"]],dnl
[[netbsd*]], [[CPU_COUNT=`command -v cpuctl >/dev/null 2>&1 && cpuctl list 2>/dev/null| $EGREP -e '^@<:@0-9@:>@+ .* online ' -c` || \
CPU_COUNT=`dmesg 2>/dev/null| $EGREP -e '^cpu@<:@0-9@:>@+ at'|sort -u|$EGREP -e '^' -c` || CPU_COUNT="0"]],dnl
[[solaris*]],[[command -v kstat >/dev/null 2>&1 && CPU_COUNT=`kstat -m cpu_info -s state -p 2>/dev/null | $EGREP -c -e 'on-line'` || \
CPU_COUNT=`kstat -m cpu_info 2>/dev/null | $EGREP -c -e 'module: cpu_info'` || CPU_COUNT="0"]],dnl
[[mingw*]],[AS_IF([[CPU_COUNT=`reg query 'HKLM\\Hardware\\Description\\System\\CentralProcessor' 2>/dev/null | $EGREP -e '\\\\@<:@0-9@:>@+$' -c`]],dnl
[[: # empty]],[[test "$NUMBER_OF_PROCESSORS" -gt "0" 2>/dev/null && CPU_COUNT="$NUMBER_OF_PROCESSORS"]])],dnl
[[msys*]],[[test "$NUMBER_OF_PROCESSORS" -gt "0" 2>/dev/null && CPU_COUNT="$NUMBER_OF_PROCESSORS"]],dnl
[[cygwin*]],[[test "$NUMBER_OF_PROCESSORS" -gt "0" 2>/dev/null && CPU_COUNT="$NUMBER_OF_PROCESSORS"]]dnl
)dnl
])dnl
AS_IF([[test "x$CPU_COUNT" != "x0" && test "$CPU_COUNT" -gt 0 2>/dev/null]],[dnl
AC_MSG_RESULT([[$CPU_COUNT]])
m4_ifvaln([$1],[$1],)dnl
],[dnl
m4_ifval([$2],[dnl
AS_UNSET([[CPU_COUNT]])
AC_MSG_RESULT([[unable to detect]])
$2
], [dnl
CPU_COUNT="1"
AC_MSG_RESULT([[unable to detect (assuming 1)]])
])dnl
])dnl
])dnl

View File

@ -10,31 +10,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_IOV_ITER], [
ITER_IOVEC | ITER_KVEC | ITER_BVEC | ITER_PIPE;
])
ZFS_LINUX_TEST_SRC([iov_iter_init], [
#include <linux/fs.h>
#include <linux/uio.h>
],[
struct iov_iter iter = { 0 };
struct iovec iov;
unsigned long nr_segs = 1;
size_t count = 1024;
iov_iter_init(&iter, WRITE, &iov, nr_segs, count);
])
ZFS_LINUX_TEST_SRC([iov_iter_init_legacy], [
#include <linux/fs.h>
#include <linux/uio.h>
],[
struct iov_iter iter = { 0 };
struct iovec iov;
unsigned long nr_segs = 1;
size_t count = 1024;
size_t written = 0;
iov_iter_init(&iter, &iov, nr_segs, count, written);
])
ZFS_LINUX_TEST_SRC([iov_iter_advance], [
#include <linux/fs.h>
#include <linux/uio.h>
@ -114,25 +89,6 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_IOV_ITER], [
enable_vfs_iov_iter="no"
])
dnl #
dnl # 'iov_iter_init' available in Linux 3.16 and newer.
dnl # 'iov_iter_init_legacy' available in Linux 3.15 and older.
dnl #
AC_MSG_CHECKING([whether iov_iter_init() is available])
ZFS_LINUX_TEST_RESULT([iov_iter_init], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_IOV_ITER_INIT, 1,
[iov_iter_init() is available])
],[
ZFS_LINUX_TEST_RESULT([iov_iter_init_legacy], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_IOV_ITER_INIT_LEGACY, 1,
[iov_iter_init() is available])
],[
ZFS_LINUX_TEST_ERROR([iov_iter_init()])
])
])
AC_MSG_CHECKING([whether iov_iter_advance() is available])
ZFS_LINUX_TEST_RESULT([iov_iter_advance], [
AC_MSG_RESULT(yes)

View File

@ -153,6 +153,9 @@ AC_DEFUN([ZFS_AC_DEBUG_KMEM_TRACKING], [
])
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
AX_COUNT_CPUS([])
AC_SUBST(CPU_COUNT)
ZFS_AC_CONFIG_ALWAYS_CC_NO_UNUSED_BUT_SET_VARIABLE
ZFS_AC_CONFIG_ALWAYS_CC_NO_BOOL_COMPARE
ZFS_AC_CONFIG_ALWAYS_CC_FRAME_LARGER_THAN
@ -167,6 +170,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
ZFS_AC_CONFIG_ALWAYS_PYTHON
ZFS_AC_CONFIG_ALWAYS_PYZFS
ZFS_AC_CONFIG_ALWAYS_SED
ZFS_AC_CONFIG_ALWAYS_CPPCHECK
])
AC_DEFUN([ZFS_AC_CONFIG], [
@ -191,12 +195,10 @@ AC_DEFUN([ZFS_AC_CONFIG], [
ZFS_AC_CONFIG_ALWAYS
AM_COND_IF([BUILD_LINUX], [
AC_ARG_VAR([TEST_JOBS],
[simultaneous jobs during configure (defaults to $(nproc))])
AC_ARG_VAR([TEST_JOBS], [simultaneous jobs during configure])
if test "x$ac_cv_env_TEST_JOBS_set" != "xset"; then
TEST_JOBS=$(nproc)
TEST_JOBS=$CPU_COUNT
fi
AC_SUBST(TEST_JOBS)
])

View File

@ -5,7 +5,7 @@ check() {
[ "${1}" = "-d" ] && return 0
# Verify the zfs tool chain
for tool in "@bindir@/zgenhostid" "@sbindir@/zpool" "@sbindir@/zfs" "@mounthelperdir@/mount.zfs" ; do
for tool in "@sbindir@/zgenhostid" "@sbindir@/zpool" "@sbindir@/zfs" "@mounthelperdir@/mount.zfs" ; do
test -x "$tool" || return 1
done
# Verify grep exists
@ -38,7 +38,7 @@ install() {
inst_rules @udevruledir@/60-zvol.rules
dracut_install hostid
dracut_install grep
dracut_install @bindir@/zgenhostid
dracut_install @sbindir@/zgenhostid
dracut_install @sbindir@/zfs
dracut_install @sbindir@/zpool
# Workaround for https://github.com/openzfs/zfs/issues/4749 by

View File

@ -8,7 +8,7 @@ Before=zfs-import.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c "/bin/systemctl set-environment BOOTFS=$(@sbindir@/zpool list -H -o bootfs | grep -m1 -v '^-$')"
ExecStart=/bin/sh -c "systemctl set-environment BOOTFS=$(@sbindir@/zpool list -H -o bootfs | grep -m1 -v '^-$')"
[Install]
WantedBy=zfs-import.target

View File

@ -59,4 +59,12 @@ echo "zfs-generator: writing extension for sysroot.mount to $GENERATOR_DIR"/sysr
[ -d "$GENERATOR_DIR"/initrd-root-fs.target.requires ] || mkdir -p "$GENERATOR_DIR"/initrd-root-fs.target.requires
ln -s ../sysroot.mount "$GENERATOR_DIR"/initrd-root-fs.target.requires/sysroot.mount
[ -d "$GENERATOR_DIR"/dracut-pre-mount.service.d ] || mkdir "$GENERATOR_DIR"/dracut-pre-mount.service.d
{
echo "[Unit]"
echo "After=zfs-import.target"
} > "$GENERATOR_DIR"/dracut-pre-mount.service.d/zfs-enhancement.conf
echo "zfs-generator: finished" >> /dev/kmsg

View File

@ -1,7 +1,7 @@
#!/bin/sh
# only run this on systemd systems, we handle the decrypt in mount-zfs.sh in the mount hook otherwise
[ -e /bin/systemctl ] || return 0
[ -e /bin/systemctl ] || [ -e /usr/bin/systemctl ] || return 0
# This script only gets executed on systemd systems, see mount-zfs.sh for non-systemd systems

View File

@ -154,8 +154,8 @@ def os_open(name, mode):
@contextlib.contextmanager
def dev_null():
with os_open('/dev/null', os.O_WRONLY) as fd:
yield fd
with tempfile.TemporaryFile(suffix='.zstream') as fd:
yield fd.fileno()
@contextlib.contextmanager

View File

@ -1,8 +0,0 @@
preprocessorErrorDirective:./module/zfs/vdev_raidz_math_avx512f.c:243
preprocessorErrorDirective:./module/zfs/vdev_raidz_math_sse2.c:266
uninitvar:module/os/freebsd/zfs/vdev_geom.c
uninitvar:module/os/freebsd/zfs/zfs_vfsops.c
uninitvar:module/os/freebsd/spl/spl_zone.c
uninitvar:lib/libzutil/os/freebsd/zutil_import_os.c
*:module/zstd/lib/zstd.c
*:module/zstd/lib/zstd.h

View File

@ -8,7 +8,7 @@ After=cryptsetup.target
After=multipathd.target
After=systemd-remount-fs.service
Before=zfs-import.target
ConditionPathExists=@sysconfdir@/zfs/zpool.cache
ConditionFileNotEmpty=@sysconfdir@/zfs/zpool.cache
ConditionPathIsDirectory=/sys/module/zfs
[Service]

View File

@ -7,7 +7,7 @@ After=systemd-udev-settle.service
After=cryptsetup.target
After=multipathd.target
Before=zfs-import.target
ConditionPathExists=!@sysconfdir@/zfs/zpool.cache
ConditionFileNotEmpty=!@sysconfdir@/zfs/zpool.cache
ConditionPathIsDirectory=/sys/module/zfs
[Service]

View File

@ -15,6 +15,7 @@ KERNEL_H = \
disp.h \
dkio.h \
extdirent.h \
fcntl.h \
file.h \
freebsd_rwlock.h \
inttypes.h \

View File

@ -166,9 +166,6 @@ extern "C" {
#define ECHRNG ENXIO
#define ETIME ETIMEDOUT
#define O_LARGEFILE 0
#define O_RSYNC 0
#ifndef LOCORE
#ifndef HAVE_RPC_TYPES
typedef int bool_t;

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2021 iXsystems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _SPL_SYS_FCNTL_H_
#define _SPL_SYS_FCNTL_H_
#include_next <sys/fcntl.h>
#define O_LARGEFILE 0
#define O_RSYNC 0
#ifndef O_DSYNC
#define O_DSYNC 0
#endif
#endif /* _SPL_SYS_FCNTL_H_ */

View File

@ -35,55 +35,72 @@
#include <sys/_uio.h>
#include <sys/debug.h>
#define uio_loffset uio_offset
typedef struct uio uio_t;
typedef struct iovec iovec_t;
typedef enum uio_seg uio_seg_t;
typedef enum uio_seg zfs_uio_seg_t;
typedef enum uio_rw zfs_uio_rw_t;
typedef struct zfs_uio {
struct uio *uio;
} zfs_uio_t;
#define GET_UIO_STRUCT(u) (u)->uio
#define zfs_uio_segflg(u) GET_UIO_STRUCT(u)->uio_segflg
#define zfs_uio_offset(u) GET_UIO_STRUCT(u)->uio_offset
#define zfs_uio_resid(u) GET_UIO_STRUCT(u)->uio_resid
#define zfs_uio_iovcnt(u) GET_UIO_STRUCT(u)->uio_iovcnt
#define zfs_uio_iovlen(u, idx) GET_UIO_STRUCT(u)->uio_iov[(idx)].iov_len
#define zfs_uio_iovbase(u, idx) GET_UIO_STRUCT(u)->uio_iov[(idx)].iov_base
#define zfs_uio_td(u) GET_UIO_STRUCT(u)->uio_td
#define zfs_uio_rw(u) GET_UIO_STRUCT(u)->uio_rw
#define zfs_uio_fault_disable(u, set)
#define zfs_uio_prefaultpages(size, u) (0)
static __inline void
zfs_uio_init(zfs_uio_t *uio, struct uio *uio_s)
{
GET_UIO_STRUCT(uio) = uio_s;
}
static __inline void
zfs_uio_setoffset(zfs_uio_t *uio, offset_t off)
{
zfs_uio_offset(uio) = off;
}
static __inline int
zfs_uiomove(void *cp, size_t n, enum uio_rw dir, uio_t *uio)
zfs_uiomove(void *cp, size_t n, zfs_uio_rw_t dir, zfs_uio_t *uio)
{
ASSERT(uio->uio_rw == dir);
return (uiomove(cp, (int)n, uio));
ASSERT(zfs_uio_rw(uio) == dir);
return (uiomove(cp, (int)n, GET_UIO_STRUCT(uio)));
}
#define uiomove(cp, n, dir, uio) zfs_uiomove((cp), (n), (dir), (uio))
int uiocopy(void *p, size_t n, enum uio_rw rw, struct uio *uio, size_t *cbytes);
void uioskip(uio_t *uiop, size_t n);
#define uio_segflg(uio) (uio)->uio_segflg
#define uio_offset(uio) (uio)->uio_loffset
#define uio_resid(uio) (uio)->uio_resid
#define uio_iovcnt(uio) (uio)->uio_iovcnt
#define uio_iovlen(uio, idx) (uio)->uio_iov[(idx)].iov_len
#define uio_iovbase(uio, idx) (uio)->uio_iov[(idx)].iov_base
#define uio_fault_disable(uio, set)
#define uio_prefaultpages(size, uio) (0)
int zfs_uiocopy(void *p, size_t n, zfs_uio_rw_t rw, zfs_uio_t *uio,
size_t *cbytes);
void zfs_uioskip(zfs_uio_t *uiop, size_t n);
int zfs_uio_fault_move(void *p, size_t n, zfs_uio_rw_t dir, zfs_uio_t *uio);
static inline void
uio_iov_at_index(uio_t *uio, uint_t idx, void **base, uint64_t *len)
zfs_uio_iov_at_index(zfs_uio_t *uio, uint_t idx, void **base, uint64_t *len)
{
*base = uio_iovbase(uio, idx);
*len = uio_iovlen(uio, idx);
*base = zfs_uio_iovbase(uio, idx);
*len = zfs_uio_iovlen(uio, idx);
}
static inline void
uio_advance(uio_t *uio, size_t size)
zfs_uio_advance(zfs_uio_t *uio, size_t size)
{
uio->uio_resid -= size;
uio->uio_loffset += size;
zfs_uio_resid(uio) -= size;
zfs_uio_offset(uio) += size;
}
static inline offset_t
uio_index_at_offset(uio_t *uio, offset_t off, uint_t *vec_idx)
zfs_uio_index_at_offset(zfs_uio_t *uio, offset_t off, uint_t *vec_idx)
{
*vec_idx = 0;
while (*vec_idx < uio_iovcnt(uio) && off >= uio_iovlen(uio, *vec_idx)) {
off -= uio_iovlen(uio, *vec_idx);
while (*vec_idx < zfs_uio_iovcnt(uio) &&
off >= zfs_uio_iovlen(uio, *vec_idx)) {
off -= zfs_uio_iovlen(uio, *vec_idx);
(*vec_idx)++;
}

View File

@ -92,7 +92,7 @@ int freebsd_crypt_newsession(freebsd_crypt_session_t *sessp,
void freebsd_crypt_freesession(freebsd_crypt_session_t *sessp);
int freebsd_crypt_uio(boolean_t, freebsd_crypt_session_t *,
struct zio_crypt_info *, uio_t *, crypto_key_t *, uint8_t *,
struct zio_crypt_info *, zfs_uio_t *, crypto_key_t *, uint8_t *,
size_t, size_t);
#endif /* _ZFS_FREEBSD_CRYPTO_H */

View File

@ -40,6 +40,7 @@
#include <sys/zil.h>
#include <sys/zfs_project.h>
#include <vm/vm_object.h>
#include <sys/uio.h>
#ifdef __cplusplus
extern "C" {
@ -118,7 +119,8 @@ extern minor_t zfsdev_minor_alloc(void);
#define Z_ISDIR(type) ((type) == VDIR)
#define zn_has_cached_data(zp) vn_has_cached_data(ZTOV(zp))
#define zn_rlimit_fsize(zp, uio, td) vn_rlimit_fsize(ZTOV(zp), (uio), (td))
#define zn_rlimit_fsize(zp, uio) \
vn_rlimit_fsize(ZTOV(zp), GET_UIO_STRUCT(uio), zfs_uio_td(uio))
/* Called on entry to each ZFS vnode and vfs operation */
#define ZFS_ENTER(zfsvfs) \
@ -179,7 +181,6 @@ extern int zfsfstype;
extern int zfs_znode_parent_and_name(struct znode *zp, struct znode **dzpp,
char *buf);
extern void zfs_inode_update(struct znode *);
#ifdef __cplusplus
}
#endif

View File

@ -36,21 +36,21 @@
typedef struct iovec iovec_t;
typedef enum uio_rw {
typedef enum zfs_uio_rw {
UIO_READ = 0,
UIO_WRITE = 1,
} uio_rw_t;
} zfs_uio_rw_t;
typedef enum uio_seg {
typedef enum zfs_uio_seg {
UIO_USERSPACE = 0,
UIO_SYSSPACE = 1,
UIO_BVEC = 2,
#if defined(HAVE_VFS_IOV_ITER)
UIO_ITER = 3,
#endif
} uio_seg_t;
} zfs_uio_seg_t;
typedef struct uio {
typedef struct zfs_uio {
union {
const struct iovec *uio_iov;
const struct bio_vec *uio_bvec;
@ -60,42 +60,51 @@ typedef struct uio {
};
int uio_iovcnt;
offset_t uio_loffset;
uio_seg_t uio_segflg;
zfs_uio_seg_t uio_segflg;
boolean_t uio_fault_disable;
uint16_t uio_fmode;
uint16_t uio_extflg;
ssize_t uio_resid;
size_t uio_skip;
} uio_t;
} zfs_uio_t;
#define uio_segflg(uio) (uio)->uio_segflg
#define uio_offset(uio) (uio)->uio_loffset
#define uio_resid(uio) (uio)->uio_resid
#define uio_iovcnt(uio) (uio)->uio_iovcnt
#define uio_iovlen(uio, idx) (uio)->uio_iov[(idx)].iov_len
#define uio_iovbase(uio, idx) (uio)->uio_iov[(idx)].iov_base
#define uio_fault_disable(uio, set) (uio)->uio_fault_disable = set
#define zfs_uio_segflg(u) (u)->uio_segflg
#define zfs_uio_offset(u) (u)->uio_loffset
#define zfs_uio_resid(u) (u)->uio_resid
#define zfs_uio_iovcnt(u) (u)->uio_iovcnt
#define zfs_uio_iovlen(u, idx) (u)->uio_iov[(idx)].iov_len
#define zfs_uio_iovbase(u, idx) (u)->uio_iov[(idx)].iov_base
#define zfs_uio_fault_disable(u, set) (u)->uio_fault_disable = set
#define zfs_uio_rlimit_fsize(z, u) (0)
#define zfs_uio_fault_move(p, n, rw, u) zfs_uiomove((p), (n), (rw), (u))
static inline void
uio_iov_at_index(uio_t *uio, uint_t idx, void **base, uint64_t *len)
zfs_uio_setoffset(zfs_uio_t *uio, offset_t off)
{
*base = uio_iovbase(uio, idx);
*len = uio_iovlen(uio, idx);
uio->uio_loffset = off;
}
static inline void
uio_advance(uio_t *uio, size_t size)
zfs_uio_iov_at_index(zfs_uio_t *uio, uint_t idx, void **base, uint64_t *len)
{
*base = zfs_uio_iovbase(uio, idx);
*len = zfs_uio_iovlen(uio, idx);
}
static inline void
zfs_uio_advance(zfs_uio_t *uio, size_t size)
{
uio->uio_resid -= size;
uio->uio_loffset += size;
}
static inline offset_t
uio_index_at_offset(uio_t *uio, offset_t off, uint_t *vec_idx)
zfs_uio_index_at_offset(zfs_uio_t *uio, offset_t off, uint_t *vec_idx)
{
*vec_idx = 0;
while (*vec_idx < uio_iovcnt(uio) && off >= uio_iovlen(uio, *vec_idx)) {
off -= uio_iovlen(uio, *vec_idx);
while (*vec_idx < zfs_uio_iovcnt(uio) &&
off >= zfs_uio_iovlen(uio, *vec_idx)) {
off -= zfs_uio_iovlen(uio, *vec_idx);
(*vec_idx)++;
}
@ -103,21 +112,9 @@ uio_index_at_offset(uio_t *uio, offset_t off, uint_t *vec_idx)
}
static inline void
iov_iter_init_compat(struct iov_iter *iter, unsigned int dir,
const struct iovec *iov, unsigned long nr_segs, size_t count)
{
#if defined(HAVE_IOV_ITER_INIT)
iov_iter_init(iter, dir, iov, nr_segs, count);
#elif defined(HAVE_IOV_ITER_INIT_LEGACY)
iov_iter_init(iter, iov, nr_segs, count, 0);
#else
#error "Unsupported kernel"
#endif
}
static inline void
uio_iovec_init(uio_t *uio, const struct iovec *iov, unsigned long nr_segs,
offset_t offset, uio_seg_t seg, ssize_t resid, size_t skip)
zfs_uio_iovec_init(zfs_uio_t *uio, const struct iovec *iov,
unsigned long nr_segs, offset_t offset, zfs_uio_seg_t seg, ssize_t resid,
size_t skip)
{
ASSERT(seg == UIO_USERSPACE || seg == UIO_SYSSPACE);
@ -133,7 +130,7 @@ uio_iovec_init(uio_t *uio, const struct iovec *iov, unsigned long nr_segs,
}
static inline void
uio_bvec_init(uio_t *uio, struct bio *bio)
zfs_uio_bvec_init(zfs_uio_t *uio, struct bio *bio)
{
uio->uio_bvec = &bio->bi_io_vec[BIO_BI_IDX(bio)];
uio->uio_iovcnt = bio->bi_vcnt - BIO_BI_IDX(bio);
@ -148,7 +145,7 @@ uio_bvec_init(uio_t *uio, struct bio *bio)
#if defined(HAVE_VFS_IOV_ITER)
static inline void
uio_iov_iter_init(uio_t *uio, struct iov_iter *iter, offset_t offset,
zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset,
ssize_t resid, size_t skip)
{
uio->uio_iter = iter;

View File

@ -60,7 +60,7 @@ extern int zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp,
char *tnm, cred_t *cr, int flags);
extern int zfs_symlink(znode_t *dzp, char *name, vattr_t *vap,
char *link, znode_t **zpp, cred_t *cr, int flags);
extern int zfs_readlink(struct inode *ip, uio_t *uio, cred_t *cr);
extern int zfs_readlink(struct inode *ip, zfs_uio_t *uio, cred_t *cr);
extern int zfs_link(znode_t *tdzp, znode_t *szp,
char *name, cred_t *cr, int flags);
extern void zfs_inactive(struct inode *ip);

View File

@ -70,8 +70,8 @@ extern "C" {
#define Z_ISDEV(type) (S_ISCHR(type) || S_ISBLK(type) || S_ISFIFO(type))
#define Z_ISDIR(type) S_ISDIR(type)
#define zn_has_cached_data(zp) ((zp)->z_is_mapped)
#define zn_rlimit_fsize(zp, uio, td) (0)
#define zn_has_cached_data(zp) ((zp)->z_is_mapped)
#define zn_rlimit_fsize(zp, uio) (0)
#define zhold(zp) igrab(ZTOI((zp)))
#define zrele(zp) iput(ZTOI((zp)))
@ -158,7 +158,6 @@ 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_destroy(struct inode *);
extern void zfs_inode_update(struct znode *);
extern void zfs_mark_inode_dirty(struct inode *);
extern boolean_t zfs_relatime_need_update(const struct inode *);

View File

@ -35,8 +35,48 @@
extern "C" {
#endif
struct abd; /* forward declaration */
typedef struct abd abd_t;
typedef enum abd_flags {
ABD_FLAG_LINEAR = 1 << 0, /* is buffer linear (or scattered)? */
ABD_FLAG_OWNER = 1 << 1, /* does it own its data buffers? */
ABD_FLAG_META = 1 << 2, /* does this represent FS metadata? */
ABD_FLAG_MULTI_ZONE = 1 << 3, /* pages split over memory zones */
ABD_FLAG_MULTI_CHUNK = 1 << 4, /* pages split over multiple chunks */
ABD_FLAG_LINEAR_PAGE = 1 << 5, /* linear but allocd from page */
ABD_FLAG_GANG = 1 << 6, /* mult ABDs chained together */
ABD_FLAG_GANG_FREE = 1 << 7, /* gang ABD is responsible for mem */
ABD_FLAG_ZEROS = 1 << 8, /* ABD for zero-filled buffer */
ABD_FLAG_ALLOCD = 1 << 9, /* we allocated the abd_t */
} abd_flags_t;
typedef struct abd {
abd_flags_t abd_flags;
uint_t abd_size; /* excludes scattered abd_offset */
list_node_t abd_gang_link;
#ifdef ZFS_DEBUG
struct abd *abd_parent;
zfs_refcount_t abd_children;
#endif
kmutex_t abd_mtx;
union {
struct abd_scatter {
uint_t abd_offset;
#if defined(__FreeBSD__) && defined(_KERNEL)
uint_t abd_chunk_size;
void *abd_chunks[1]; /* actually variable-length */
#else
uint_t abd_nents;
struct scatterlist *abd_sgl;
#endif
} abd_scatter;
struct abd_linear {
void *abd_buf;
struct scatterlist *abd_sgl; /* for LINEAR_PAGE */
} abd_linear;
struct abd_gang {
list_t abd_gang_chain;
} abd_gang;
} abd_u;
} abd_t;
typedef int abd_iter_func_t(void *buf, size_t len, void *priv);
typedef int abd_iter_func2_t(void *bufa, void *bufb, size_t len, void *priv);
@ -49,14 +89,14 @@ extern int zfs_abd_scatter_enabled;
abd_t *abd_alloc(size_t, boolean_t);
abd_t *abd_alloc_linear(size_t, boolean_t);
abd_t *abd_alloc_gang_abd(void);
abd_t *abd_alloc_gang(void);
abd_t *abd_alloc_for_io(size_t, boolean_t);
abd_t *abd_alloc_sametype(abd_t *, size_t);
void abd_gang_add(abd_t *, abd_t *, boolean_t);
void abd_free(abd_t *);
void abd_put(abd_t *);
abd_t *abd_get_offset(abd_t *, size_t);
abd_t *abd_get_offset_size(abd_t *, size_t, size_t);
abd_t *abd_get_offset_struct(abd_t *, abd_t *, size_t, size_t);
abd_t *abd_get_zeros(size_t);
abd_t *abd_get_from_buf(void *, size_t);
void abd_cache_reap_now(void);
@ -87,7 +127,6 @@ int abd_cmp(abd_t *, abd_t *);
int abd_cmp_buf_off(abd_t *, const void *, size_t, size_t);
void abd_zero_off(abd_t *, size_t, size_t);
void abd_verify(abd_t *);
uint_t abd_get_size(abd_t *);
void abd_raidz_gen_iterate(abd_t **cabds, abd_t *dabd,
ssize_t csize, ssize_t dsize, const unsigned parity,
@ -135,9 +174,29 @@ abd_zero(abd_t *abd, size_t size)
/*
* ABD type check functions
*/
boolean_t abd_is_linear(abd_t *);
boolean_t abd_is_gang(abd_t *);
boolean_t abd_is_linear_page(abd_t *);
static inline boolean_t
abd_is_linear(abd_t *abd)
{
return ((abd->abd_flags & ABD_FLAG_LINEAR) ? B_TRUE : B_FALSE);
}
static inline boolean_t
abd_is_linear_page(abd_t *abd)
{
return ((abd->abd_flags & ABD_FLAG_LINEAR_PAGE) ? B_TRUE : B_FALSE);
}
static inline boolean_t
abd_is_gang(abd_t *abd)
{
return ((abd->abd_flags & ABD_FLAG_GANG) ? B_TRUE : B_FALSE);
}
static inline uint_t
abd_get_size(abd_t *abd)
{
return (abd->abd_size);
}
/*
* Module lifecycle

View File

@ -32,51 +32,11 @@
extern "C" {
#endif
typedef enum abd_flags {
ABD_FLAG_LINEAR = 1 << 0, /* is buffer linear (or scattered)? */
ABD_FLAG_OWNER = 1 << 1, /* does it own its data buffers? */
ABD_FLAG_META = 1 << 2, /* does this represent FS metadata? */
ABD_FLAG_MULTI_ZONE = 1 << 3, /* pages split over memory zones */
ABD_FLAG_MULTI_CHUNK = 1 << 4, /* pages split over multiple chunks */
ABD_FLAG_LINEAR_PAGE = 1 << 5, /* linear but allocd from page */
ABD_FLAG_GANG = 1 << 6, /* mult ABDs chained together */
ABD_FLAG_GANG_FREE = 1 << 7, /* gang ABD is responsible for mem */
ABD_FLAG_ZEROS = 1 << 8, /* ABD for zero-filled buffer */
} abd_flags_t;
typedef enum abd_stats_op {
ABDSTAT_INCR, /* Increase abdstat values */
ABDSTAT_DECR /* Decrease abdstat values */
} abd_stats_op_t;
struct abd {
abd_flags_t abd_flags;
uint_t abd_size; /* excludes scattered abd_offset */
list_node_t abd_gang_link;
struct abd *abd_parent;
zfs_refcount_t abd_children;
kmutex_t abd_mtx;
union {
struct abd_scatter {
uint_t abd_offset;
#if defined(__FreeBSD__) && defined(_KERNEL)
uint_t abd_chunk_size;
void *abd_chunks[];
#else
uint_t abd_nents;
struct scatterlist *abd_sgl;
#endif
} abd_scatter;
struct abd_linear {
void *abd_buf;
struct scatterlist *abd_sgl; /* for LINEAR_PAGE */
} abd_linear;
struct abd_gang {
list_t abd_gang_chain;
} abd_gang;
} abd_u;
};
struct scatterlist; /* forward declaration */
struct abd_iter {
@ -95,14 +55,16 @@ struct abd_iter {
extern abd_t *abd_zero_scatter;
abd_t *abd_gang_get_offset(abd_t *, size_t *);
abd_t *abd_alloc_struct(size_t);
void abd_free_struct(abd_t *);
/*
* OS specific functions
*/
abd_t *abd_alloc_struct(size_t);
abd_t *abd_get_offset_scatter(abd_t *, size_t);
void abd_free_struct(abd_t *);
abd_t *abd_alloc_struct_impl(size_t);
abd_t *abd_get_offset_scatter(abd_t *, abd_t *, size_t);
void abd_free_struct_impl(abd_t *);
void abd_alloc_chunks(abd_t *, size_t);
void abd_free_chunks(abd_t *);
boolean_t abd_size_alloc_linear(size_t);

View File

@ -244,7 +244,7 @@ typedef struct crypto_data {
iovec_t cdu_raw; /* Pointer and length */
/* uio scatter-gather format */
uio_t *cdu_uio;
zfs_uio_t *cdu_uio;
} cdu; /* Crypto Data Union */
} crypto_data_t;

View File

@ -142,9 +142,6 @@ typedef enum dmu_object_byteswap {
#define DMU_OT_IS_DDT(ot) \
((ot) == DMU_OT_DDT_ZAP)
#define DMU_OT_IS_ZIL(ot) \
((ot) == DMU_OT_INTENT_LOG)
/* Note: ztest uses DMU_OT_UINT64_OTHER as a proxy for file blocks */
#define DMU_OT_IS_FILE(ot) \
((ot) == DMU_OT_PLAIN_FILE_CONTENTS || (ot) == DMU_OT_UINT64_OTHER)
@ -847,14 +844,14 @@ void dmu_write_by_dnode(dnode_t *dn, uint64_t offset, uint64_t size,
void dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
dmu_tx_t *tx);
#ifdef _KERNEL
int dmu_read_uio(objset_t *os, uint64_t object, struct uio *uio, uint64_t size);
int dmu_read_uio_dbuf(dmu_buf_t *zdb, struct uio *uio, uint64_t size);
int dmu_read_uio_dnode(dnode_t *dn, struct uio *uio, uint64_t size);
int dmu_write_uio(objset_t *os, uint64_t object, struct uio *uio, uint64_t size,
int dmu_read_uio(objset_t *os, uint64_t object, zfs_uio_t *uio, uint64_t size);
int dmu_read_uio_dbuf(dmu_buf_t *zdb, zfs_uio_t *uio, uint64_t size);
int dmu_read_uio_dnode(dnode_t *dn, zfs_uio_t *uio, uint64_t size);
int dmu_write_uio(objset_t *os, uint64_t object, zfs_uio_t *uio, uint64_t size,
dmu_tx_t *tx);
int dmu_write_uio_dbuf(dmu_buf_t *zdb, struct uio *uio, uint64_t size,
int dmu_write_uio_dbuf(dmu_buf_t *zdb, zfs_uio_t *uio, uint64_t size,
dmu_tx_t *tx);
int dmu_write_uio_dnode(dnode_t *dn, struct uio *uio, uint64_t size,
int dmu_write_uio_dnode(dnode_t *dn, zfs_uio_t *uio, uint64_t size,
dmu_tx_t *tx);
#endif
struct arc_buf *dmu_request_arcbuf(dmu_buf_t *handle, int size);

View File

@ -1456,6 +1456,7 @@ typedef enum {
#define ZPOOL_HIST_DSNAME "dsname"
#define ZPOOL_HIST_DSID "dsid"
#define ZPOOL_HIST_ERRNO "errno"
#define ZPOOL_HIST_ELAPSED_NS "elapsed_ns"
/*
* Special nvlist name that will not have its args recorded in the pool's

View File

@ -158,7 +158,7 @@ void sa_handle_lock(sa_handle_t *);
void sa_handle_unlock(sa_handle_t *);
#ifdef _KERNEL
int sa_lookup_uio(sa_handle_t *, sa_attr_type_t, uio_t *);
int sa_lookup_uio(sa_handle_t *, sa_attr_type_t, zfs_uio_t *);
int sa_add_projid(sa_handle_t *, dmu_tx_t *, uint64_t);
#endif

View File

@ -1047,6 +1047,7 @@ extern uint64_t spa_version(spa_t *spa);
extern boolean_t spa_deflate(spa_t *spa);
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_dedup_class(spa_t *spa);
extern metaslab_class_t *spa_preferred_class(spa_t *spa, uint64_t size,

View File

@ -226,6 +226,7 @@ struct spa {
boolean_t spa_is_exporting; /* true while exporting pool */
metaslab_class_t *spa_normal_class; /* normal data class */
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_dedup_class; /* dedup allocation class */
uint64_t spa_first_txg; /* first txg after spa_open() */

View File

@ -41,9 +41,9 @@
#include <sys/uio.h>
extern int uiomove(void *, size_t, enum uio_rw, uio_t *);
extern int uio_prefaultpages(ssize_t, uio_t *);
extern int uiocopy(void *, size_t, enum uio_rw, uio_t *, size_t *);
extern void uioskip(uio_t *, size_t);
extern int zfs_uiomove(void *, size_t, zfs_uio_rw_t, zfs_uio_t *);
extern int zfs_uio_prefaultpages(ssize_t, zfs_uio_t *);
extern int zfs_uiocopy(void *, size_t, zfs_uio_rw_t, zfs_uio_t *, size_t *);
extern void zfs_uioskip(zfs_uio_t *, size_t);
#endif /* _SYS_UIO_IMPL_H */

View File

@ -33,6 +33,7 @@
#include <sys/zio.h>
#include <sys/dmu.h>
#include <sys/space_map.h>
#include <sys/metaslab.h>
#include <sys/fs/zfs.h>
#ifdef __cplusplus
@ -113,6 +114,9 @@ extern void vdev_xlate_walk(vdev_t *vd, const range_seg64_t *logical_rs,
vdev_xlate_func_t *func, void *arg);
extern void vdev_get_stats_ex(vdev_t *vd, vdev_stat_t *vs, vdev_stat_ex_t *vsx);
extern metaslab_group_t *vdev_get_mg(vdev_t *vd, metaslab_class_t *mc);
extern void vdev_get_stats(vdev_t *vd, vdev_stat_t *vs);
extern void vdev_clear_stats(vdev_t *vd);
extern void vdev_stat_update(zio_t *zio, uint64_t psize);

View File

@ -269,8 +269,11 @@ struct vdev {
boolean_t vdev_expanding; /* expand the vdev? */
boolean_t vdev_reopening; /* reopen in progress? */
boolean_t vdev_nonrot; /* true if solid state */
int vdev_load_error; /* error on last load */
int vdev_open_error; /* error on last open */
int vdev_validate_error; /* error on last validate */
kthread_t *vdev_open_thread; /* thread opening children */
kthread_t *vdev_validate_thread; /* thread validating children */
uint64_t vdev_crtxg; /* txg when top-level was added */
/*
@ -280,6 +283,7 @@ struct vdev {
uint64_t vdev_ms_shift; /* metaslab size shift */
uint64_t vdev_ms_count; /* number of metaslabs */
metaslab_group_t *vdev_mg; /* metaslab group */
metaslab_group_t *vdev_log_mg; /* embedded slog metaslab group */
metaslab_t **vdev_ms; /* metaslab array */
uint64_t vdev_pending_fastwrite; /* allocated fastwrites */
txg_list_t vdev_ms_list; /* per-txg dirty metaslab lists */
@ -636,6 +640,7 @@ extern int vdev_obsolete_counts_are_precise(vdev_t *vd, boolean_t *are_precise);
* Other miscellaneous functions
*/
int vdev_checkpoint_sm_object(vdev_t *vd, uint64_t *sm_obj);
void vdev_metaslab_group_create(vdev_t *vd);
/*
* Vdev ashift optimization tunables

View File

@ -106,6 +106,7 @@ typedef struct raidz_col {
uint64_t rc_devidx; /* child device index for I/O */
uint64_t rc_offset; /* device offset */
uint64_t rc_size; /* I/O size */
abd_t rc_abdstruct; /* rc_abd probably points here */
abd_t *rc_abd; /* I/O data */
void *rc_orig_data; /* pre-reconstruction */
abd_t *rc_gdata; /* used to store the "good" version */

View File

@ -56,6 +56,7 @@ extern int zfs_dbgmsg_enable;
#define ZFS_DEBUG_INDIRECT_REMAP (1 << 10)
#define ZFS_DEBUG_TRIM (1 << 11)
#define ZFS_DEBUG_LOG_SPACEMAP (1 << 12)
#define ZFS_DEBUG_METASLAB_ALLOC (1 << 13)
extern void __set_error(const char *file, const char *func, int line, int err);
extern void __zfs_dbgmsg(char *buf);

View File

@ -134,7 +134,7 @@ typedef struct znode_phys {
#define DXATTR_MAX_ENTRY_SIZE (32768)
#define DXATTR_MAX_SA_SIZE (SPA_OLD_MAXBLOCKSIZE >> 1)
int zfs_sa_readlink(struct znode *, uio_t *);
int zfs_sa_readlink(struct znode *, zfs_uio_t *);
void zfs_sa_symlink(struct znode *, char *link, int len, dmu_tx_t *);
void zfs_sa_get_scanstamp(struct znode *, xvattr_t *);
void zfs_sa_set_scanstamp(struct znode *, xvattr_t *, dmu_tx_t *);

View File

@ -27,16 +27,16 @@
#include <sys/zfs_vnops_os.h>
extern int zfs_fsync(znode_t *, int, cred_t *);
extern int zfs_read(znode_t *, uio_t *, int, cred_t *);
extern int zfs_write(znode_t *, uio_t *, int, cred_t *);
extern int zfs_read(znode_t *, zfs_uio_t *, int, cred_t *);
extern int zfs_write(znode_t *, zfs_uio_t *, int, cred_t *);
extern int zfs_holey(znode_t *, ulong_t, loff_t *);
extern int zfs_access(znode_t *, int, int, cred_t *);
extern int zfs_getsecattr(znode_t *, vsecattr_t *, int, cred_t *);
extern int zfs_setsecattr(znode_t *, vsecattr_t *, int, cred_t *);
extern int mappedread(znode_t *, int, uio_t *);
extern int mappedread_sf(znode_t *, int, uio_t *);
extern int mappedread(znode_t *, int, zfs_uio_t *);
extern int mappedread_sf(znode_t *, int, zfs_uio_t *);
extern void update_pages(znode_t *, int64_t, int, objset_t *);
/*

View File

@ -287,6 +287,8 @@ extern void zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp,
extern void zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx);
extern void zfs_upgrade(zfsvfs_t *zfsvfs, dmu_tx_t *tx);
extern void zfs_znode_update_vfs(struct znode *);
#endif
#ifdef __cplusplus
}

View File

@ -1,9 +1,12 @@
# NB: GNU Automake Manual, Chapter 8.3.5: Libtool Convenience Libraries
# These nine libraries are intermediary build components.
SUBDIRS = libavl libicp libshare libspl libtpool libzstd
CPPCHECKDIRS = libavl libicp libnvpair libshare libspl libtpool libunicode
CPPCHECKDIRS += libuutil libzfs libzfs_core libzfsbootenv libzpool libzutil
if BUILD_LINUX
SUBDIRS += libefi
CPPCHECKDIRS += libefi
endif
# libnvpair is installed as part of the final build product
@ -23,7 +26,7 @@ DISTLIBS += libnvpair
# is only linked against by ztest and zdb and no stable ABI is provided.
ABILIBS = libnvpair libuutil libzfs_core libzfs libzfsbootenv
PHONY = checkabi storeabi
PHONY = checkabi storeabi cppcheck
checkabi: $(ABILIBS)
set -e ; for dir in $(ABILIBS) ; do \
$(MAKE) -C $$dir checkabi ; \
@ -33,3 +36,8 @@ storeabi: $(ABILIBS)
set -e ; for dir in $(ABILIBS) ; do \
$(MAKE) -C $$dir storeabi ; \
done
cppcheck: $(CPPCHECKDIRS)
set -e ; for dir in $(CPPCHECKDIRS) ; do \
$(MAKE) -C $$dir cppcheck ; \
done

View File

@ -12,3 +12,5 @@ KERNEL_C = \
nodist_libavl_la_SOURCES = \
$(KERNEL_C)
include $(top_srcdir)/config/CppCheck.am

View File

@ -10,3 +10,5 @@ USER_C = \
libefi_la_SOURCES = $(USER_C)
libefi_la_LIBADD = $(LIBUUID_LIBS) $(ZLIB_LIBS)
include $(top_srcdir)/config/CppCheck.am

View File

@ -468,6 +468,7 @@ efi_alloc_and_read(int fd, struct dk_gpt **vtoc)
(int) sizeof (struct dk_part) * (vptr->efi_nparts - 1);
nparts = vptr->efi_nparts;
if ((tmp = realloc(vptr, length)) == NULL) {
/* cppcheck-suppress doubleFree */
free(vptr);
*vtoc = NULL;
return (VT_ERROR);

View File

@ -71,3 +71,5 @@ KERNEL_ASM = $(ASM_SOURCES_AS)
nodist_libicp_la_SOURCES = \
$(KERNEL_C) \
$(KERNEL_ASM)
include $(top_srcdir)/config/CppCheck.am

View File

@ -1,5 +1,4 @@
include $(top_srcdir)/config/Rules.am
PHONY =
VPATH = \
$(top_srcdir)/module/nvpair \
@ -42,5 +41,7 @@ endif
libnvpair_la_LDFLAGS += -version-info 3:0:0
include $(top_srcdir)/config/CppCheck.am
# Library ABI
EXTRA_DIST = libnvpair.abi libnvpair.suppr

View File

@ -23,3 +23,5 @@ USER_C += \
endif
libshare_la_SOURCES = $(USER_C)
include $(top_srcdir)/config/CppCheck.am

View File

@ -55,3 +55,12 @@ libspl_la_LIBADD = \
libspl_assert.la
libspl_la_LIBADD += $(LIBCLOCK_GETTIME)
include $(top_srcdir)/config/CppCheck.am
# Override the default SOURCES which includes TARGET_CPU_ATOMIC_SOURCE
# in order to always evaluate the generic asm-generic/atomic.c source.
CPPCHECKSRC = $(USER_C) asm-generic/atomic.c
cppcheck:
$(CPPCHECK) -j$(CPU_COUNT) $(CPPCHECKFLAGS) --force \
$(DEFAULT_INCLUDES) $(CPPCHECKSRC)

View File

@ -1 +1,5 @@
SUBDIRS = sys
libspldir = $(includedir)/libspl
libspl_HEADERS = \
fcntl.h

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2021 iXsystems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _LIBSPL_FCNTL_H_
#define _LIBSPL_FCNTL_H_
#include_next <fcntl.h>
#include <sys/fcntl.h>
#endif /* _LIBSPL_FCNTL_H_ */

View File

@ -1,6 +1,7 @@
libspldir = $(includedir)/libspl/sys
libspl_HEADERS = \
byteorder.h \
fcntl.h \
file.h \
mnttab.h \
mount.h \

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2021 iXsystems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _LIBSPL_SYS_FCNTL_H_
#define _LIBSPL_SYS_FCNTL_H_
#include_next <sys/fcntl.h>
#define O_LARGEFILE 0
#define O_RSYNC 0
#ifndef O_DSYNC
#define O_DSYNC 0
#endif
#endif /* _LIBSPL_SYS_FCNTL_H_ */

View File

@ -51,58 +51,58 @@
typedef struct iovec iovec_t;
#if defined(__linux__) || defined(__APPLE__)
typedef enum uio_rw {
typedef enum zfs_uio_rw {
UIO_READ = 0,
UIO_WRITE = 1,
} uio_rw_t;
} zfs_uio_rw_t;
typedef enum uio_seg {
typedef enum zfs_uio_seg {
UIO_USERSPACE = 0,
UIO_SYSSPACE = 1,
} uio_seg_t;
} zfs_uio_seg_t;
#elif defined(__FreeBSD__)
typedef enum uio_seg uio_seg_t;
typedef enum uio_seg zfs_uio_seg_t;
#endif
typedef struct uio {
typedef struct zfs_uio {
struct iovec *uio_iov; /* pointer to array of iovecs */
int uio_iovcnt; /* number of iovecs */
offset_t uio_loffset; /* file offset */
uio_seg_t uio_segflg; /* address space (kernel or user) */
zfs_uio_seg_t uio_segflg; /* address space (kernel or user) */
uint16_t uio_fmode; /* file mode flags */
uint16_t uio_extflg; /* extended flags */
ssize_t uio_resid; /* residual count */
} uio_t;
} zfs_uio_t;
#define uio_segflg(uio) (uio)->uio_segflg
#define uio_offset(uio) (uio)->uio_loffset
#define uio_resid(uio) (uio)->uio_resid
#define uio_iovcnt(uio) (uio)->uio_iovcnt
#define uio_iovlen(uio, idx) (uio)->uio_iov[(idx)].iov_len
#define uio_iovbase(uio, idx) (uio)->uio_iov[(idx)].iov_base
#define zfs_uio_segflg(uio) (uio)->uio_segflg
#define zfs_uio_offset(uio) (uio)->uio_loffset
#define zfs_uio_resid(uio) (uio)->uio_resid
#define zfs_uio_iovcnt(uio) (uio)->uio_iovcnt
#define zfs_uio_iovlen(uio, idx) (uio)->uio_iov[(idx)].iov_len
#define zfs_uio_iovbase(uio, idx) (uio)->uio_iov[(idx)].iov_base
static inline void
uio_iov_at_index(uio_t *uio, uint_t idx, void **base, uint64_t *len)
zfs_uio_iov_at_index(zfs_uio_t *uio, uint_t idx, void **base, uint64_t *len)
{
*base = uio_iovbase(uio, idx);
*len = uio_iovlen(uio, idx);
*base = zfs_uio_iovbase(uio, idx);
*len = zfs_uio_iovlen(uio, idx);
}
static inline void
uio_advance(uio_t *uio, size_t size)
zfs_uio_advance(zfs_uio_t *uio, size_t size)
{
uio->uio_resid -= size;
uio->uio_loffset += size;
}
static inline offset_t
uio_index_at_offset(uio_t *uio, offset_t off, uint_t *vec_idx)
zfs_uio_index_at_offset(zfs_uio_t *uio, offset_t off, uint_t *vec_idx)
{
*vec_idx = 0;
while (*vec_idx < (uint_t)uio_iovcnt(uio) &&
off >= (offset_t)uio_iovlen(uio, *vec_idx)) {
off -= uio_iovlen(uio, *vec_idx);
while (*vec_idx < (uint_t)zfs_uio_iovcnt(uio) &&
off >= (offset_t)zfs_uio_iovlen(uio, *vec_idx)) {
off -= zfs_uio_iovlen(uio, *vec_idx);
(*vec_idx)++;
}

View File

@ -7,3 +7,5 @@ USER_C = \
thread_pool_impl.h
libtpool_la_SOURCES = $(USER_C)
include $(top_srcdir)/config/CppCheck.am

View File

@ -13,3 +13,5 @@ KERNEL_C = \
nodist_libunicode_la_SOURCES = \
$(KERNEL_C)
include $(top_srcdir)/config/CppCheck.am

View File

@ -1,5 +1,4 @@
include $(top_srcdir)/config/Rules.am
PHONY =
lib_LTLIBRARIES = libuutil.la
@ -32,5 +31,7 @@ endif
libuutil_la_LDFLAGS += -version-info 3:0:0
include $(top_srcdir)/config/CppCheck.am
# Library ABI
EXTRA_DIST = libuutil.abi libuutil.suppr

View File

@ -128,6 +128,7 @@ uu_avl_pool_destroy(uu_avl_pool_t *pp)
pp->uap_next->uap_prev = pp->uap_prev;
pp->uap_prev->uap_next = pp->uap_next;
(void) pthread_mutex_unlock(&uu_apool_list_lock);
(void) pthread_mutex_destroy(&pp->uap_lock);
pp->uap_prev = NULL;
pp->uap_next = NULL;
uu_free(pp);

View File

@ -1,5 +1,4 @@
include $(top_srcdir)/config/Rules.am
PHONY =
VPATH = \
$(top_srcdir)/module/icp \
@ -90,6 +89,8 @@ endif
libzfs_la_LDFLAGS += -version-info 4:0:0
include $(top_srcdir)/config/CppCheck.am
# Library ABI
EXTRA_DIST = libzfs.abi libzfs.suppr

View File

@ -77,7 +77,7 @@ refresh_config(libzfs_handle_t *hdl, nvlist_t *config)
if (zcmd_write_conf_nvlist(hdl, &zc, config) != 0)
return (NULL);
dstbuf_size = MAX(CONFIG_BUF_MINSIZE, zc.zc_nvlist_conf_size * 4);
dstbuf_size = MAX(CONFIG_BUF_MINSIZE, zc.zc_nvlist_conf_size * 32);
if (zcmd_alloc_dst_nvlist(hdl, &zc, dstbuf_size) != 0) {
zcmd_free_nvlists(&zc);

View File

@ -1188,6 +1188,30 @@ zpool_has_special_vdev(nvlist_t *nvroot)
return (B_FALSE);
}
/*
* Check if vdev list contains a dRAID vdev
*/
static boolean_t
zpool_has_draid_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++) {
char *type;
if (nvlist_lookup_string(child[c],
ZPOOL_CONFIG_TYPE, &type) == 0 &&
strcmp(type, VDEV_TYPE_DRAID) == 0) {
return (B_TRUE);
}
}
}
return (B_FALSE);
}
/*
* Output a dRAID top-level vdev name in to the provided buffer.
*/
@ -1373,6 +1397,17 @@ zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
"one or more devices is out of space"));
return (zfs_error(hdl, EZFS_BADDEV, msg));
case EINVAL:
if (zpool_has_draid_vdev(nvroot) &&
zfeature_lookup_name("draid", NULL) != 0) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"dRAID vdevs are unsupported by the "
"kernel"));
return (zfs_error(hdl, EZFS_BADDEV, msg));
} else {
return (zpool_standard_error(hdl, errno, msg));
}
default:
return (zpool_standard_error(hdl, errno, msg));
}
@ -1528,9 +1563,19 @@ zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
break;
case EINVAL:
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"invalid config; a pool with removing/removed "
"vdevs does not support adding raidz vdevs"));
if (zpool_has_draid_vdev(nvroot) &&
zfeature_lookup_name("draid", NULL) != 0) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"dRAID vdevs are unsupported by the "
"kernel"));
} else {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"invalid config; a pool with removing/"
"removed vdevs does not support adding "
"raidz or dRAID vdevs"));
}
(void) zfs_error(hdl, EZFS_BADDEV, msg);
break;

View File

@ -186,15 +186,15 @@ fsavl_create(nvlist_t *fss)
nvlist_t *nvfs, *snaps;
nvpair_t *snapelem = NULL;
VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs));
VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps));
nvfs = fnvpair_value_nvlist(fselem);
snaps = fnvlist_lookup_nvlist(nvfs, "snaps");
while ((snapelem =
nvlist_next_nvpair(snaps, snapelem)) != NULL) {
fsavl_node_t *fn;
uint64_t guid;
VERIFY(0 == nvpair_value_uint64(snapelem, &guid));
guid = fnvpair_value_uint64(snapelem);
if ((fn = malloc(sizeof (fsavl_node_t))) == NULL) {
fsavl_destroy(fsavl);
return (NULL);
@ -311,7 +311,7 @@ send_iterate_snap(zfs_handle_t *zhp, void *arg)
return (0);
}
VERIFY(0 == nvlist_add_uint64(sd->parent_snaps, snapname, guid));
fnvlist_add_uint64(sd->parent_snaps, snapname, guid);
/*
* NB: if there is no fromsnap here (it's a newly created fs in
* an incremental replication), we will substitute the tosnap.
@ -336,16 +336,15 @@ send_iterate_snap(zfs_handle_t *zhp, void *arg)
sd->seento = B_TRUE;
}
VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0));
nv = fnvlist_alloc();
send_iterate_prop(zhp, sd->backup, nv);
VERIFY(0 == nvlist_add_nvlist(sd->snapprops, snapname, nv));
nvlist_free(nv);
fnvlist_add_nvlist(sd->snapprops, snapname, nv);
fnvlist_free(nv);
if (sd->holds) {
nvlist_t *holds = fnvlist_alloc();
int err = lzc_get_holds(zhp->zfs_name, &holds);
if (err == 0) {
VERIFY(0 == nvlist_add_nvlist(sd->snapholds,
snapname, holds));
fnvlist_add_nvlist(sd->snapholds, snapname, holds);
}
fnvlist_free(holds);
}
@ -420,14 +419,12 @@ send_iterate_prop(zfs_handle_t *zhp, boolean_t received_only, nvlist_t *nv)
if (zfs_prop_user(propname) ||
zfs_prop_get_type(prop) == PROP_TYPE_STRING) {
char *value;
verify(nvlist_lookup_string(propnv,
ZPROP_VALUE, &value) == 0);
VERIFY(0 == nvlist_add_string(nv, propname, value));
value = fnvlist_lookup_string(propnv, ZPROP_VALUE);
fnvlist_add_string(nv, propname, value);
} else {
uint64_t value;
verify(nvlist_lookup_uint64(propnv,
ZPROP_VALUE, &value) == 0);
VERIFY(0 == nvlist_add_uint64(nv, propname, value));
value = fnvlist_lookup_uint64(propnv, ZPROP_VALUE);
fnvlist_add_uint64(nv, propname, value);
}
}
}
@ -572,8 +569,7 @@ send_iterate_fs(zfs_handle_t *zhp, void *arg)
sd->parent_snaps = fnvlist_alloc();
sd->snapprops = fnvlist_alloc();
if (sd->holds)
VERIFY(0 == nvlist_alloc(&sd->snapholds, NV_UNIQUE_NAME, 0));
sd->snapholds = fnvlist_alloc();
/*
* If this is a "doall" send, a replicate send or we're just trying
@ -656,7 +652,7 @@ gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
if (zhp == NULL)
return (EZFS_BADTYPE);
VERIFY(0 == nvlist_alloc(&sd.fss, NV_UNIQUE_NAME, 0));
sd.fss = fnvlist_alloc();
sd.fsname = fsname;
sd.fromsnap = fromsnap;
sd.tosnap = tosnap;
@ -670,7 +666,7 @@ gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
sd.props = props;
if ((error = send_iterate_fs(zhp, &sd)) != 0) {
nvlist_free(sd.fss);
fnvlist_free(sd.fss);
if (avlp != NULL)
*avlp = NULL;
*nvlp = NULL;
@ -678,7 +674,7 @@ gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
}
if (avlp != NULL && (*avlp = fsavl_create(sd.fss)) == NULL) {
nvlist_free(sd.fss);
fnvlist_free(sd.fss);
*nvlp = NULL;
return (EZFS_NOMEM);
}
@ -789,10 +785,9 @@ dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
zc.zc_fromobj = fromsnap_obj;
zc.zc_flags = flags;
VERIFY(0 == nvlist_alloc(&thisdbg, NV_UNIQUE_NAME, 0));
thisdbg = fnvlist_alloc();
if (fromsnap && fromsnap[0] != '\0') {
VERIFY(0 == nvlist_add_string(thisdbg,
"fromsnap", fromsnap));
fnvlist_add_string(thisdbg, "fromsnap", fromsnap);
}
if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND, &zc) != 0) {
@ -800,12 +795,11 @@ dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
"warning: cannot send '%s'"), zhp->zfs_name);
VERIFY(0 == nvlist_add_uint64(thisdbg, "error", errno));
fnvlist_add_uint64(thisdbg, "error", errno);
if (debugnv) {
VERIFY(0 == nvlist_add_nvlist(debugnv,
zhp->zfs_name, thisdbg));
fnvlist_add_nvlist(debugnv, zhp->zfs_name, thisdbg);
}
nvlist_free(thisdbg);
fnvlist_free(thisdbg);
switch (errno) {
case EXDEV:
@ -847,8 +841,8 @@ dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
}
if (debugnv)
VERIFY(0 == nvlist_add_nvlist(debugnv, zhp->zfs_name, thisdbg));
nvlist_free(thisdbg);
fnvlist_add_nvlist(debugnv, zhp->zfs_name, thisdbg);
fnvlist_free(thisdbg);
return (0);
}
@ -1047,10 +1041,8 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
nvlist_t *nvfs = fsavl_find(sdd->fsavl,
zhp->zfs_dmustats.dds_guid, &snapname);
VERIFY(0 == nvlist_lookup_nvlist(nvfs,
"snapprops", &snapprops));
VERIFY(0 == nvlist_lookup_nvlist(snapprops,
thissnap, &snapprops));
snapprops = fnvlist_lookup_nvlist(nvfs, "snapprops");
snapprops = fnvlist_lookup_nvlist(snapprops, thissnap);
exclude = !nvlist_exists(snapprops, "is_clone_origin");
} else {
exclude = B_TRUE;
@ -1269,7 +1261,7 @@ dump_filesystems(zfs_handle_t *rzhp, void *arg)
nvlist_t *nvfs;
uint64_t origin_guid = 0;
VERIFY(0 == nvpair_value_nvlist(fspair, &nvfs));
nvfs = fnvpair_value_nvlist(fspair);
(void) nvlist_lookup_uint64(nvfs, "origin", &origin_guid);
if (origin_guid != 0) {
char *snapname;
@ -1277,12 +1269,12 @@ dump_filesystems(zfs_handle_t *rzhp, void *arg)
origin_guid, &snapname);
if (origin_nv != NULL) {
nvlist_t *snapprops;
VERIFY(0 == nvlist_lookup_nvlist(origin_nv,
"snapprops", &snapprops));
VERIFY(0 == nvlist_lookup_nvlist(snapprops,
snapname, &snapprops));
VERIFY(0 == nvlist_add_boolean(
snapprops, "is_clone_origin"));
snapprops = fnvlist_lookup_nvlist(origin_nv,
"snapprops");
snapprops = fnvlist_lookup_nvlist(snapprops,
snapname);
fnvlist_add_boolean(snapprops,
"is_clone_origin");
}
}
}
@ -1297,11 +1289,11 @@ dump_filesystems(zfs_handle_t *rzhp, void *arg)
uint64_t origin_guid = 0;
uint64_t parent_guid = 0;
VERIFY(nvpair_value_nvlist(fspair, &fslist) == 0);
fslist = fnvpair_value_nvlist(fspair);
if (nvlist_lookup_boolean(fslist, "sent") == 0)
continue;
VERIFY(nvlist_lookup_string(fslist, "name", &fsname) == 0);
fsname = fnvlist_lookup_string(fslist, "name");
(void) nvlist_lookup_uint64(fslist, "origin", &origin_guid);
(void) nvlist_lookup_uint64(fslist, "parentfromsnap",
&parent_guid);
@ -1333,7 +1325,7 @@ dump_filesystems(zfs_handle_t *rzhp, void *arg)
if (zhp == NULL)
return (-1);
err = dump_filesystem(zhp, sdd);
VERIFY(nvlist_add_boolean(fslist, "sent") == 0);
fnvlist_add_boolean(fslist, "sent");
progress = B_TRUE;
zfs_close(zhp);
if (err)
@ -1349,7 +1341,7 @@ dump_filesystems(zfs_handle_t *rzhp, void *arg)
fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
nvlist_t *fslist;
VERIFY(nvpair_value_nvlist(fspair, &fslist) == 0);
fslist = fnvpair_value_nvlist(fspair);
(void) nvlist_remove_all(fslist, "sent");
}
@ -1560,7 +1552,7 @@ find_redact_book(libzfs_handle_t *hdl, const char *path,
fnvlist_add_boolean(props, "redact_complete");
fnvlist_add_boolean(props, zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS));
error = lzc_get_bookmarks(path, props, &bmarks);
nvlist_free(props);
fnvlist_free(props);
if (error != 0) {
if (error == ESRCH) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
@ -1850,7 +1842,7 @@ zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
}
ret = zfs_send_resume_impl(hdl, flags, outfd, resume_nvl);
nvlist_free(resume_nvl);
fnvlist_free(resume_nvl);
return (ret);
}
@ -1940,8 +1932,8 @@ zfs_send_saved(zfs_handle_t *zhp, sendflags_t *flags, int outfd,
ret = zfs_send_resume_impl(hdl, flags, outfd, saved_nvl);
out:
nvlist_free(saved_nvl);
nvlist_free(resume_nvl);
fnvlist_free(saved_nvl);
fnvlist_free(resume_nvl);
return (ret);
}
@ -2018,7 +2010,7 @@ send_prelim_records(zfs_handle_t *zhp, const char *from, int fd,
fnvlist_add_boolean(hdrnv, "not_recursive");
if (raw) {
VERIFY0(nvlist_add_boolean(hdrnv, "raw"));
fnvlist_add_boolean(hdrnv, "raw");
}
if ((err = gather_nvlist(zhp->zfs_hdl, tofs,
@ -2048,9 +2040,9 @@ send_prelim_records(zfs_handle_t *zhp, const char *from, int fd,
if (fssp != NULL) {
*fssp = fss;
} else {
nvlist_free(fss);
fnvlist_free(fss);
}
nvlist_free(hdrnv);
fnvlist_free(hdrnv);
}
if (!dryrun) {
@ -2267,7 +2259,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
err = dump_filesystems(zhp, &sdd);
fsavl_destroy(fsavl);
nvlist_free(fss);
fnvlist_free(fss);
/* Ensure no snaps found is treated as an error. */
if (err == 0 && !sdd.seento)
@ -2296,7 +2288,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
err = zfs_standard_error(zhp->zfs_hdl, err, errbuf);
err_out:
fsavl_destroy(fsavl);
nvlist_free(fss);
fnvlist_free(fss);
fnvlist_free(sdd.snapholds);
if (sdd.cleanup_fd != -1)
@ -3041,14 +3033,14 @@ created_before(libzfs_handle_t *hdl, avl_tree_t *avl,
return (1);
nvfs = fsavl_find(avl, guid1, &snapname);
VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
fsname = fnvlist_lookup_string(nvfs, "name");
(void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
guid1hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
if (guid1hdl == NULL)
return (-1);
nvfs = fsavl_find(avl, guid2, &snapname);
VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
fsname = fnvlist_lookup_string(nvfs, "name");
(void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
guid2hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
if (guid2hdl == NULL) {
@ -3086,7 +3078,7 @@ recv_fix_encryption_hierarchy(libzfs_handle_t *hdl, const char *top_zfs,
nvpair_t *fselem = NULL;
nvlist_t *stream_fss;
VERIFY(0 == nvlist_lookup_nvlist(stream_nv, "fss", &stream_fss));
stream_fss = fnvlist_lookup_nvlist(stream_nv, "fss");
while ((fselem = nvlist_next_nvpair(stream_fss, fselem)) != NULL) {
zfs_handle_t *zhp = NULL;
@ -3100,9 +3092,9 @@ recv_fix_encryption_hierarchy(libzfs_handle_t *hdl, const char *top_zfs,
char fsname[ZFS_MAX_DATASET_NAME_LEN];
keylocation[0] = '\0';
VERIFY(0 == nvpair_value_nvlist(fselem, &stream_nvfs));
VERIFY(0 == nvlist_lookup_nvlist(stream_nvfs, "snaps", &snaps));
VERIFY(0 == nvlist_lookup_nvlist(stream_nvfs, "props", &props));
stream_nvfs = fnvpair_value_nvlist(fselem);
snaps = fnvlist_lookup_nvlist(stream_nvfs, "snaps");
props = fnvlist_lookup_nvlist(stream_nvfs, "props");
stream_encroot = nvlist_exists(stream_nvfs, "is_encroot");
/* find a snapshot from the stream that exists locally */
@ -3110,7 +3102,7 @@ recv_fix_encryption_hierarchy(libzfs_handle_t *hdl, const char *top_zfs,
while ((snapel = nvlist_next_nvpair(snaps, snapel)) != NULL) {
uint64_t guid;
VERIFY(0 == nvpair_value_uint64(snapel, &guid));
guid = fnvpair_value_uint64(snapel);
err = guid_to_name(hdl, top_zfs, guid, B_FALSE,
fsname);
if (err == 0)
@ -3155,9 +3147,8 @@ recv_fix_encryption_hierarchy(libzfs_handle_t *hdl, const char *top_zfs,
}
}
VERIFY(0 == nvlist_lookup_string(props,
zfs_prop_to_name(ZFS_PROP_KEYLOCATION),
&stream_keylocation));
stream_keylocation = fnvlist_lookup_string(props,
zfs_prop_to_name(ZFS_PROP_KEYLOCATION));
/*
* Refresh the properties in case the call to
@ -3223,7 +3214,7 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
boolean_t needagain, progress, recursive;
char *s1, *s2;
VERIFY(0 == nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap));
fromsnap = fnvlist_lookup_string(stream_nv, "fromsnap");
recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
ENOENT);
@ -3234,7 +3225,7 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
again:
needagain = progress = B_FALSE;
VERIFY(0 == nvlist_alloc(&deleted, NV_UNIQUE_NAME, 0));
deleted = fnvlist_alloc();
if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL,
recursive, B_TRUE, B_FALSE, recursive, B_FALSE, B_FALSE,
@ -3257,11 +3248,11 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
nextfselem = nvlist_next_nvpair(local_nv, fselem);
VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs));
VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps));
VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
VERIFY(0 == nvlist_lookup_uint64(nvfs, "parentfromsnap",
&parent_fromsnap_guid));
nvfs = fnvpair_value_nvlist(fselem);
snaps = fnvlist_lookup_nvlist(nvfs, "snaps");
fsname = fnvlist_lookup_string(nvfs, "name");
parent_fromsnap_guid = fnvlist_lookup_uint64(nvfs,
"parentfromsnap");
(void) nvlist_lookup_uint64(nvfs, "origin", &originguid);
/*
@ -3272,7 +3263,7 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
snapelem; snapelem = nvlist_next_nvpair(snaps, snapelem)) {
uint64_t thisguid;
VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid));
thisguid = fnvpair_value_uint64(snapelem);
stream_nvfs = fsavl_find(stream_avl, thisguid, NULL);
if (stream_nvfs != NULL)
@ -3292,8 +3283,8 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
origin_nvfs = fsavl_find(local_avl, originguid,
NULL);
VERIFY(0 == nvlist_lookup_string(origin_nvfs,
"name", &origin_fsname));
origin_fsname = fnvlist_lookup_string(
origin_nvfs, "name");
error = recv_promote(hdl, fsname, origin_fsname,
flags);
if (error == 0)
@ -3304,7 +3295,7 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
break;
case -1:
fsavl_destroy(local_avl);
nvlist_free(local_nv);
fnvlist_free(local_nv);
return (-1);
}
/*
@ -3324,7 +3315,7 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
nextsnapelem = nvlist_next_nvpair(snaps, snapelem);
VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid));
thisguid = fnvpair_value_uint64(snapelem);
found = fsavl_find(stream_avl, thisguid,
&stream_snapname);
@ -3418,10 +3409,9 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
continue;
}
VERIFY(0 == nvlist_lookup_string(stream_nvfs,
"name", &stream_fsname));
VERIFY(0 == nvlist_lookup_uint64(stream_nvfs,
"parentfromsnap", &stream_parent_fromsnap_guid));
stream_fsname = fnvlist_lookup_string(stream_nvfs, "name");
stream_parent_fromsnap_guid = fnvlist_lookup_uint64(
stream_nvfs, "parentfromsnap");
s1 = strrchr(fsname, '/');
s2 = strrchr(stream_fsname, '/');
@ -3470,8 +3460,7 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
if (parent != NULL) {
char *pname;
VERIFY(0 == nvlist_lookup_string(parent, "name",
&pname));
pname = fnvlist_lookup_string(parent, "name");
(void) snprintf(tryname, sizeof (tryname),
"%s%s", pname, strrchr(stream_fsname, '/'));
} else {
@ -3488,8 +3477,7 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
strlen(tofs)+1, newname, flags);
if (renamed != NULL && newname[0] != '\0') {
VERIFY(0 == nvlist_add_boolean(renamed,
newname));
fnvlist_add_boolean(renamed, newname);
}
if (error)
@ -3501,8 +3489,8 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
doagain:
fsavl_destroy(local_avl);
nvlist_free(local_nv);
nvlist_free(deleted);
fnvlist_free(local_nv);
fnvlist_free(deleted);
if (needagain && progress) {
/* do another pass to fix up temporary names */
@ -3597,8 +3585,7 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
if (drr->drr_payloadlen != 0) {
nvlist_t *stream_fss;
VERIFY(0 == nvlist_lookup_nvlist(stream_nv, "fss",
&stream_fss));
stream_fss = fnvlist_lookup_nvlist(stream_nv, "fss");
if ((stream_avl = fsavl_create(stream_fss)) == NULL) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"couldn't allocate avl tree"));
@ -3634,8 +3621,7 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
}
if (!flags->dryrun && !flags->nomount) {
VERIFY(0 == nvlist_alloc(&renamed,
NV_UNIQUE_NAME, 0));
renamed = fnvlist_alloc();
}
softerr = recv_incremental_replication(hdl, tofs, flags,
@ -3662,7 +3648,7 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
}
}
nvlist_free(renamed);
fnvlist_free(renamed);
}
}
@ -3718,7 +3704,7 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
out:
fsavl_destroy(stream_avl);
nvlist_free(stream_nv);
fnvlist_free(stream_nv);
if (softerr)
error = -2;
if (anyerr)
@ -4141,7 +4127,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
&parent_snapguid);
err = nvlist_lookup_nvlist(fs, "props", &rcvprops);
if (err) {
VERIFY(0 == nvlist_alloc(&rcvprops, NV_UNIQUE_NAME, 0));
rcvprops = fnvlist_alloc();
newprops = B_TRUE;
}
@ -4162,22 +4148,22 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
}
if (flags->canmountoff) {
VERIFY(0 == nvlist_add_uint64(rcvprops,
zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0));
fnvlist_add_uint64(rcvprops,
zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0);
} else if (newprops) { /* nothing in rcvprops, eliminate it */
nvlist_free(rcvprops);
fnvlist_free(rcvprops);
rcvprops = NULL;
newprops = B_FALSE;
}
if (0 == nvlist_lookup_nvlist(fs, "snapprops", &lookup)) {
VERIFY(0 == nvlist_lookup_nvlist(lookup,
snapname, &snapprops_nvlist));
snapprops_nvlist = fnvlist_lookup_nvlist(lookup,
snapname);
}
if (holds) {
if (0 == nvlist_lookup_nvlist(fs, "snapholds",
&lookup)) {
VERIFY(0 == nvlist_lookup_nvlist(lookup,
snapname, &snapholds_nvlist));
snapholds_nvlist = fnvlist_lookup_nvlist(
lookup, snapname);
}
}
}
@ -4711,12 +4697,11 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
for (pair = nvlist_next_nvpair(snapholds_nvlist, NULL);
pair != NULL;
pair = nvlist_next_nvpair(snapholds_nvlist, pair)) {
VERIFY(0 == nvlist_add_string(holds, destsnap,
nvpair_name(pair)));
fnvlist_add_string(holds, destsnap, nvpair_name(pair));
}
(void) lzc_hold(holds, cleanup_fd, &errors);
nvlist_free(snapholds_nvlist);
nvlist_free(holds);
fnvlist_free(snapholds_nvlist);
fnvlist_free(holds);
}
if (err && (ioctl_errno == ENOENT || ioctl_errno == EEXIST)) {
@ -4741,7 +4726,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
*cp = '@';
fs = fsavl_find(local_avl, drrb->drr_toguid, NULL);
fsavl_destroy(local_avl);
nvlist_free(local_nv);
fnvlist_free(local_nv);
if (fs != NULL) {
if (flags->verbose) {
@ -4917,18 +4902,18 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
err = 0;
out:
if (prop_errors != NULL)
nvlist_free(prop_errors);
fnvlist_free(prop_errors);
if (tmp_keylocation[0] != '\0') {
VERIFY(0 == nvlist_add_string(rcvprops,
zfs_prop_to_name(ZFS_PROP_KEYLOCATION), tmp_keylocation));
fnvlist_add_string(rcvprops,
zfs_prop_to_name(ZFS_PROP_KEYLOCATION), tmp_keylocation);
}
if (newprops)
nvlist_free(rcvprops);
fnvlist_free(rcvprops);
nvlist_free(oxprops);
nvlist_free(origprops);
fnvlist_free(oxprops);
fnvlist_free(origprops);
return (err);
}

View File

@ -1,5 +1,4 @@
include $(top_srcdir)/config/Rules.am
PHONY =
pkgconfig_DATA = libzfs_core.pc
@ -30,5 +29,7 @@ endif
libzfs_core_la_LDFLAGS += -version-info 3:0:0
include $(top_srcdir)/config/CppCheck.am
# Library ABI
EXTRA_DIST = libzfs_core.abi libzfs_core.suppr

View File

@ -1,5 +1,4 @@
include $(top_srcdir)/config/Rules.am
PHONY =
pkgconfig_DATA = libzfsbootenv.pc
@ -34,5 +33,7 @@ endif
libzfsbootenv_la_LDFLAGS += -version-info 1:0:0
include $(top_srcdir)/config/CppCheck.am
# Library ABI
EXTRA_DIST = libzfsbootenv.abi libzfsbootenv.suppr

View File

@ -235,3 +235,5 @@ if TARGET_CPU_POWERPC
vdev_raidz_math_powerpc_altivec.$(OBJEXT): CFLAGS += -maltivec
vdev_raidz_math_powerpc_altivec.l$(OBJEXT): CFLAGS += -maltivec
endif
include $(top_srcdir)/config/CppCheck.am

View File

@ -19,3 +19,5 @@ lib/zstd.l$(OBJEXT): CFLAGS += -fno-tree-vectorize -include $(top_srcdir)/module
zfs_zstd.$(OBJEXT): CFLAGS += -include $(top_srcdir)/module/zstd/include/zstd_compat_wrapper.h
zfs_zstd.l$(OBJEXT): CFLAGS += -include $(top_srcdir)/module/zstd/include/zstd_compat_wrapper.h
include $(top_srcdir)/config/CppCheck.am

View File

@ -45,7 +45,10 @@ libzutil_la_LIBADD = \
if BUILD_LINUX
libzutil_la_LIBADD += \
$(abs_top_builddir)/lib/libefi/libefi.la
$(abs_top_builddir)/lib/libefi/libefi.la \
-lrt
endif
libzutil_la_LIBADD += -lm $(LIBBLKID_LIBS) $(LIBUDEV_LIBS)
include $(top_srcdir)/config/CppCheck.am

View File

@ -42,6 +42,12 @@
* using our derived config, and record the results.
*/
#include <sys/types.h>
#include <sys/disk.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <aio.h>
#include <ctype.h>
#include <dirent.h>
@ -51,9 +57,6 @@
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/disk.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
@ -181,6 +184,7 @@ int
zpool_find_import_blkid(libpc_handle_t *hdl, pthread_mutex_t *lock,
avl_tree_t **slice_cache)
{
const char *oid = "vfs.zfs.vol.recursive";
char *end, path[MAXPATHLEN];
rdsk_node_t *slice;
struct gmesh mesh;
@ -188,8 +192,9 @@ zpool_find_import_blkid(libpc_handle_t *hdl, pthread_mutex_t *lock,
struct ggeom *gp;
struct gprovider *pp;
avl_index_t where;
size_t pathleft;
int error;
int error, value;
size_t pathleft, size = sizeof (value);
boolean_t skip_zvols = B_FALSE;
end = stpcpy(path, "/dev/");
pathleft = &path[sizeof (path)] - end;
@ -198,11 +203,16 @@ zpool_find_import_blkid(libpc_handle_t *hdl, pthread_mutex_t *lock,
if (error != 0)
return (error);
if (sysctlbyname(oid, &value, &size, NULL, 0) == 0 && value == 0)
skip_zvols = B_TRUE;
*slice_cache = zutil_alloc(hdl, sizeof (avl_tree_t));
avl_create(*slice_cache, slice_cache_compare, sizeof (rdsk_node_t),
offsetof(rdsk_node_t, rn_node));
LIST_FOREACH(mp, &mesh.lg_class, lg_class) {
if (skip_zvols && strcmp(mp->lg_name, "ZFS::ZVOL") == 0)
continue;
LIST_FOREACH(gp, &mp->lg_geom, lg_geom) {
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
strlcpy(end, pp->lg_name, pathleft);

View File

@ -46,6 +46,7 @@
* using our derived config, and record the results.
*/
#include <aio.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
@ -887,11 +888,12 @@ int
zpool_read_label(int fd, nvlist_t **config, int *num_labels)
{
struct stat64 statbuf;
int l, count = 0;
vdev_label_t *label;
struct aiocb aiocbs[VDEV_LABELS];
struct aiocb *aiocbps[VDEV_LABELS];
vdev_phys_t *labels;
nvlist_t *expected_config = NULL;
uint64_t expected_guid = 0, size;
int error;
int error, l, count = 0;
*config = NULL;
@ -899,19 +901,51 @@ zpool_read_label(int fd, nvlist_t **config, int *num_labels)
return (0);
size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
error = posix_memalign((void **)&label, PAGESIZE, sizeof (*label));
error = posix_memalign((void **)&labels, PAGESIZE,
VDEV_LABELS * sizeof (*labels));
if (error)
return (-1);
memset(aiocbs, 0, sizeof (aiocbs));
for (l = 0; l < VDEV_LABELS; l++) {
off_t offset = label_offset(size, l) + VDEV_SKIP_SIZE;
aiocbs[l].aio_fildes = fd;
aiocbs[l].aio_offset = offset;
aiocbs[l].aio_buf = &labels[l];
aiocbs[l].aio_nbytes = sizeof (vdev_phys_t);
aiocbs[l].aio_lio_opcode = LIO_READ;
aiocbps[l] = &aiocbs[l];
}
if (lio_listio(LIO_WAIT, aiocbps, VDEV_LABELS, NULL) != 0) {
int saved_errno = errno;
if (errno == EAGAIN || errno == EINTR || errno == EIO) {
/*
* A portion of the requests may have been submitted.
* Clean them up.
*/
for (l = 0; l < VDEV_LABELS; l++) {
errno = 0;
int r = aio_error(&aiocbs[l]);
if (r != EINVAL)
(void) aio_return(&aiocbs[l]);
}
}
free(labels);
errno = saved_errno;
return (-1);
}
for (l = 0; l < VDEV_LABELS; l++) {
uint64_t state, guid, txg;
if (pread64(fd, label, sizeof (vdev_label_t),
label_offset(size, l)) != sizeof (vdev_label_t))
if (aio_return(&aiocbs[l]) != sizeof (vdev_phys_t))
continue;
if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
sizeof (label->vl_vdev_phys.vp_nvlist), config, 0) != 0)
if (nvlist_unpack(labels[l].vp_nvlist,
sizeof (labels[l].vp_nvlist), config, 0) != 0)
continue;
if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_GUID,
@ -948,7 +982,7 @@ zpool_read_label(int fd, nvlist_t **config, int *num_labels)
if (num_labels != NULL)
*num_labels = count;
free(label);
free(labels);
*config = expected_config;
return (0);

View File

@ -3936,6 +3936,22 @@ to limit potential SLOG device abuse by single active ZIL writer.
Default value: \fB786,432\fR.
.RE
.sp
.ne 2
.na
\fBzfs_embedded_slog_min_ms\fR (int)
.ad
.RS 12n
Usually, one metaslab from each (normal-class) vdev is dedicated for use by
the ZIL (to log synchronous writes).
However, if there are fewer than zfs_embedded_slog_min_ms metaslabs in the
vdev, this functionality is disabled.
This ensures that we don't set aside an unreasonable amount of space for the
ZIL.
.sp
Default value: \fB64\fR.
.RE
.sp
.ne 2
.na

Some files were not shown because too many files have changed in this diff Show More