Compare commits
219 Commits
zfs-2.0.2
...
zfs-2.0-re
Author | SHA1 | Date |
---|---|---|
Tony Hutter | ad81baab77 | |
Brian Behlendorf | a4831fa023 | |
Ryan Moeller | b327131a1f | |
Ryan Moeller | 2ed7c54654 | |
Pawel Jakub Dawidek | 70fdb198ad | |
Ryan Moeller | 7100db9793 | |
Mark Johnston | 57f43735ca | |
Mark Johnston | 47f098d2db | |
Mark Johnston | d94d1a589c | |
Brian Behlendorf | 4bbffa2489 | |
Brian Behlendorf | d1bf6c7251 | |
Paul Dagnelie | 1fbfc022c9 | |
Coleman Kane | 2a21853b75 | |
Coleman Kane | 6a3ba7538a | |
Coleman Kane | 94e49866e9 | |
Coleman Kane | eb9d35e641 | |
Coleman Kane | 649b3ce987 | |
Coleman Kane | 541fe3d598 | |
Alexander Motin | c84f9be5c7 | |
наб | 5ea770b0a2 | |
John Wren Kennedy | 3404e887b1 | |
Brian Behlendorf | 2915930f89 | |
John Wren Kennedy | 3c97d7a84b | |
Paul Dagnelie | 5a80c82609 | |
Coleman Kane | 679be593dd | |
Jorgen Lundman | f43b315e17 | |
Tony Hutter | 922fe416b2 | |
наб | e2dcc523a4 | |
наб | dec1ea4dbc | |
Brian Behlendorf | 1a4030b1b5 | |
Brian Behlendorf | 33fa3985a9 | |
Brian Behlendorf | a524f8d6af | |
Tony Hutter | 4ba1a6227a | |
Brian Behlendorf | 6de5c440fa | |
Brian Behlendorf | b8b3b93ebb | |
наб | 586358102e | |
Rich Ercolani | 110d0ba5ca | |
Rich Ercolani | 2ef1ce66f5 | |
Brian Atkinson | d10c35b640 | |
Brian Atkinson | 0b1e6fcc3e | |
Ryan Moeller | cd4f9572d0 | |
Matthew Macy | 6f59f6402d | |
Ryan Moeller | 3fcf17e69d | |
Tony Hutter | 92fcbe04ba | |
Tony Hutter | dfbc33a0e5 | |
Tony Hutter | 91fe213823 | |
Anton Gubarkov | 728cf93b0c | |
наб | 43706c7dee | |
наб | 5cc5996f4e | |
наб | cc6ea631ce | |
наб | b847e538ef | |
Arshad Hussain | 238504fece | |
Tony Hutter | b0b796a94d | |
Tony Hutter | 9d14963de6 | |
Tony Hutter | 88a3751e67 | |
Arshad Hussain | bdd43a2396 | |
Rich Ercolani | 47ada9e5ed | |
Brian Behlendorf | c4a5e56abc | |
Brian Behlendorf | ec1b033413 | |
Damian Szuberski | 8464de1315 | |
Rich Ercolani | cc40a67cf8 | |
George Melikov | c2a69a21ef | |
George Melikov | 866ac70904 | |
Jonathon | f3c85e3ebd | |
Paul Dagnelie | 14770e1030 | |
Attila Fülöp | fb9eee4cc2 | |
Brian Behlendorf | 820c95750b | |
Rich Ercolani | 66c9e15686 | |
Rich Ercolani | c64c17328b | |
Rich Ercolani | 439b4b134d | |
наб | 5957574694 | |
наб | 3e04897edc | |
Rich Ercolani | fb823061b0 | |
George Melikov | 4e8a639d5f | |
Brian Behlendorf | 8009f02748 | |
Jonathon | 4a5316eef4 | |
Paul Dagnelie | e00f3da136 | |
Tony Hutter | ef686e96ec | |
Brian Behlendorf | 7a41ef240a | |
Alexander | 72d16a9b49 | |
Brian Behlendorf | 54c358c3f2 | |
Brian Behlendorf | 560e9fc817 | |
Brian Behlendorf | d642efe83c | |
Alexander Motin | 51e313f610 | |
Alexander Motin | 327f12c291 | |
Alexander Motin | 5d4f7e7566 | |
Serapheim Dimitropoulos | abd0b59e48 | |
Coleman Kane | 6b9d0eda75 | |
Paul Dagnelie | 744cdfd93b | |
Brian Behlendorf | 36d50b60d8 | |
Mark Johnston | 0c4f86be74 | |
Mark Johnston | 88be308b2f | |
Mark Johnston | d6dc79eabc | |
Mark Johnston | 900a444107 | |
George Wilson | 1885e5ebab | |
Antonio Russo | 1ad8fcc054 | |
Rich Ercolani | 05c96b438a | |
Rich Ercolani | ccf6d0a59b | |
Prakash Surya | 61ae6c99f7 | |
Tony Hutter | e9353bc2ef | |
George Amanakis | 87d93731e7 | |
Paul Zuchowski | bd197378e7 | |
jharmening | cd2bb9ca44 | |
Mateusz Guzik | 52d9bc7174 | |
Brian Behlendorf | 6905f6b2c1 | |
Rich Ercolani | cfc82609a2 | |
George Melikov | e26776f14c | |
Chunwei Chen | e68e938f54 | |
Christian Schwarz | ab2110e3e2 | |
Matthew Macy | a909190683 | |
наб | 073f3c7826 | |
Luis Henriques | 5072f37419 | |
Ryan Moeller | 332cd2e313 | |
Adam D. Moss | ac6f332154 | |
Brian Behlendorf | f14b6f2302 | |
Chunwei Chen | bfb2928490 | |
Paul Zuchowski | ecb1b1a31d | |
Rich Ercolani | 412b69dfab | |
Jonathon Fernyhough | d014da0032 | |
Rich Ercolani | 8f93ab53d4 | |
Rich Ercolani | 88891b804b | |
Armin Wehrfritz | 87b5e7fb1d | |
Coleman Kane | 5722dce473 | |
Coleman Kane | 91d5ac85c0 | |
Ryan Moeller | fd8ccce07b | |
Ryan Moeller | c2a3bcc91d | |
Toomas Soome | d1277e2a13 | |
Brian Behlendorf | a59bf29606 | |
Prawn | 28fdc5f811 | |
Mateusz Guzik | a78a93e67e | |
Romain Dolbeau | 9a68ceba10 | |
Daniel Stevenson | 3c7ad493a6 | |
наб | faad85637b | |
наб | 501da8d433 | |
наб | 30620ad8e1 | |
наб | 1d65d1a597 | |
Mateusz Guzik | edf3d7aa43 | |
Paul Zuchowski | 9755cdfd89 | |
Brian Behlendorf | f36e8118fd | |
Yuri Pankov | e69f73c5cf | |
наб | 3430eced80 | |
Brian Behlendorf | 0839934d84 | |
наб | f831d1377f | |
наб | a559c3d0f4 | |
наб | 95e29a7275 | |
наб | 85890d54d9 | |
Ryan Moeller | 12e25a6ec3 | |
Ryan Moeller | 57490d5e13 | |
Ryan Moeller | 214196e9f5 | |
matt-fidd | 932d471bec | |
наб | 77cba40b85 | |
George Melikov | 18d069a20f | |
наб | dfc25ea91c | |
Brian Behlendorf | 7428adc6b7 | |
Ryan Moeller | 30782f2ff5 | |
Ryan Moeller | 43efd5625b | |
Ryan Moeller | 87a520c4e7 | |
Ryan Moeller | d02bcae0c4 | |
Ryan Moeller | d9bcadc6ba | |
Ryan Moeller | 67819ea28d | |
Brian Behlendorf | 79430bf34b | |
Andrew | cabc605aa7 | |
Palash Gandhi | 0740d41e9b | |
Martin Matuška | 16e8e24f9c | |
Mateusz Guzik | bc5afff351 | |
Ryan Moeller | 825d8e1b0f | |
gldisater | f7797f3f5e | |
Ryan Moeller | 2439e95f36 | |
Ryan Moeller | de722e55ca | |
Ryan Moeller | acb4e7b0e1 | |
Mariusz Zaborski | 5a397fda09 | |
Ryan Moeller | 525a7037c7 | |
Mateusz Guzik | 789f3d0e56 | |
Mateusz Guzik | 5d946dfa1c | |
Mateusz Guzik | cd80d6d355 | |
Mateusz Guzik | 140584bfff | |
Mateusz Guzik | 8773e29c23 | |
Mateusz Guzik | bb21c0aa3b | |
George Wilson | 455ea5bb1f | |
Martin Matuška | 7126b0e5ed | |
Ryan Moeller | 7ca0ef36e1 | |
Adam D. Moss | 0d6186cff3 | |
Allan Jude | 6f349d33a5 | |
George Melikov | 226d362b12 | |
Antonio Russo | 497fc5fb06 | |
Christian Schwarz | abb485a34a | |
Ryan Moeller | 0ccffb2634 | |
nssrikanth | 26cb87d22d | |
Brian Behlendorf | 43dbfa3921 | |
Brian Behlendorf | 395583e38e | |
Ryan Moeller | 818bc70c32 | |
Tony Hutter | 6150fbe67f | |
manfromafar | 458bb8c8a1 | |
Ryan Moeller | cda6fdd500 | |
Brian Behlendorf | df8271301e | |
Brian Behlendorf | e219935f10 | |
Thomas Lamprecht | bb9104f1e8 | |
James Wah | 94b240bae0 | |
Jake Howard | e93203e004 | |
Andriy Gapon | ccb453acd0 | |
Coleman Kane | 6c1989923e | |
Coleman Kane | a0eb5a77a0 | |
Brian Behlendorf | fe77c48320 | |
Cedric Maunoury | db9b29895e | |
fbynite | 4d4dd76f0f | |
Christian Schwarz | 286c7f75bb | |
Ryan Moeller | 403703d57a | |
Mark Johnston | f17c843eff | |
Andriy Gapon | f6440fa094 | |
José Luis Salvador Rufo | 62f9691e10 | |
Brian Behlendorf | 73e26fdc09 | |
Tony Hutter | 65a89d9f49 | |
Antonio Russo | 8829ba19b7 | |
наб | 642d86af0d | |
Lorenz Hüdepohl | 07ca7592ad | |
Brian Behlendorf | fb0d807477 | |
George Melikov | 858ea8861c | |
George Melikov | 549841ef9a | |
George Melikov | 96f322e7e2 |
|
@ -25,14 +25,16 @@ Type | Version/Name
|
||||||
--- | ---
|
--- | ---
|
||||||
Distribution Name |
|
Distribution Name |
|
||||||
Distribution Version |
|
Distribution Version |
|
||||||
Linux Kernel |
|
Kernel Version |
|
||||||
Architecture |
|
Architecture |
|
||||||
ZFS Version |
|
OpenZFS Version |
|
||||||
SPL Version |
|
|
||||||
<!--
|
<!--
|
||||||
Commands to find ZFS/SPL versions:
|
Command to find OpenZFS version:
|
||||||
modinfo zfs | grep -iw version
|
zfs version
|
||||||
modinfo spl | grep -iw version
|
|
||||||
|
Commands to find kernel version:
|
||||||
|
uname -r # Linux
|
||||||
|
freebsd-version -r # FreeBSD
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Describe the problem you're observing
|
### Describe the problem you're observing
|
||||||
|
|
|
@ -7,5 +7,5 @@ contact_links:
|
||||||
url: https://lists.freebsd.org/mailman/listinfo/freebsd-fs
|
url: https://lists.freebsd.org/mailman/listinfo/freebsd-fs
|
||||||
about: Get community support for OpenZFS on FreeBSD
|
about: Get community support for OpenZFS on FreeBSD
|
||||||
- name: OpenZFS on IRC
|
- name: OpenZFS on IRC
|
||||||
url: https://webchat.freenode.net/#openzfs
|
url: https://web.libera.chat/#openzfs
|
||||||
about: Use IRC to get community support for OpenZFS
|
about: Use IRC to get community support for OpenZFS
|
||||||
|
|
|
@ -6,7 +6,7 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
checkstyle:
|
checkstyle:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
|
@ -18,12 +18,13 @@ jobs:
|
||||||
sudo apt-get install --yes -qq zlib1g-dev uuid-dev libattr1-dev libblkid-dev libselinux-dev libudev-dev libssl-dev python-dev python-setuptools python-cffi python3 python3-dev python3-setuptools python3-cffi
|
sudo apt-get install --yes -qq zlib1g-dev uuid-dev libattr1-dev libblkid-dev libselinux-dev libudev-dev libssl-dev python-dev python-setuptools python-cffi python3 python3-dev python3-setuptools python3-cffi
|
||||||
# packages for tests
|
# packages for tests
|
||||||
sudo apt-get install --yes -qq parted lsscsi ksh attr acl nfs-kernel-server fio
|
sudo apt-get install --yes -qq parted lsscsi ksh attr acl nfs-kernel-server fio
|
||||||
sudo apt-get install --yes -qq mandoc cppcheck pax-utils abigail-tools # devscripts - enable then bashisms fixed
|
sudo apt-get install --yes -qq mandoc cppcheck pax-utils devscripts
|
||||||
sudo -E pip --quiet install flake8
|
sudo -E pip --quiet install flake8
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: |
|
run: |
|
||||||
sh ./autogen.sh
|
sh ./autogen.sh
|
||||||
./configure
|
./configure
|
||||||
|
make -j$(nproc)
|
||||||
- name: Checkstyle
|
- name: Checkstyle
|
||||||
run: |
|
run: |
|
||||||
make checkstyle
|
make checkstyle
|
||||||
|
@ -31,6 +32,19 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
make lint
|
make lint
|
||||||
- name: CheckABI
|
- name: CheckABI
|
||||||
|
id: CheckABI
|
||||||
run: |
|
run: |
|
||||||
make -j$(nproc)
|
sudo docker run -v $(pwd):/source ghcr.io/openzfs/libabigail make checkabi
|
||||||
make checkabi
|
- name: StoreABI
|
||||||
|
if: failure() && steps.CheckABI.outcome == 'failure'
|
||||||
|
run: |
|
||||||
|
sudo docker run -v $(pwd):/source ghcr.io/openzfs/libabigail make storeabi
|
||||||
|
- name: Prepare artifacts
|
||||||
|
if: failure() && steps.CheckABI.outcome == 'failure'
|
||||||
|
run: |
|
||||||
|
find -name *.abi | tar -cf abi_files.tar -T -
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
if: failure() && steps.CheckABI.outcome == 'failure'
|
||||||
|
with:
|
||||||
|
name: New ABI files (use only if you're sure about interface changes)
|
||||||
|
path: abi_files.tar
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
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 python3-packaging
|
||||||
|
- 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
|
||||||
|
# Workaround for cloud-init bug
|
||||||
|
# see https://github.com/openzfs/zfs/issues/12644
|
||||||
|
FILE=/lib/udev/rules.d/10-cloud-init-hook-hotplug.rules
|
||||||
|
if [ -r "${FILE}" ]; then
|
||||||
|
HASH=$(md5sum "${FILE}" | awk '{ print $1 }')
|
||||||
|
if [ "${HASH}" = "121ff0ef1936cd2ef65aec0458a35772" ]; then
|
||||||
|
# Just shove a zd* exclusion right above the hotplug hook...
|
||||||
|
sudo sed -i -e s/'LABEL="cloudinit_hook"'/'KERNEL=="zd*", GOTO="cloudinit_end"\n&'/ "${FILE}"
|
||||||
|
sudo udevadm control --reload-rules
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# Workaround to provide additional free space for testing.
|
||||||
|
# https://github.com/actions/virtual-environments/issues/2840
|
||||||
|
sudo rm -rf /usr/share/dotnet
|
||||||
|
sudo rm -rf /opt/ghc
|
||||||
|
sudo rm -rf "/usr/local/share/boost"
|
||||||
|
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||||
|
- name: Tests
|
||||||
|
run: |
|
||||||
|
/usr/share/zfs/zfs-tests.sh -vR -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 /var/tmp/test_results -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
|
|
@ -22,7 +22,7 @@ jobs:
|
||||||
xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \
|
xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \
|
||||||
libssl-dev libffi-dev libaio-dev libelf-dev libmount-dev \
|
libssl-dev libffi-dev libaio-dev libelf-dev libmount-dev \
|
||||||
libpam0g-dev pamtester python-dev python-setuptools python-cffi \
|
libpam0g-dev pamtester python-dev python-setuptools python-cffi \
|
||||||
python3 python3-dev python3-setuptools python3-cffi
|
python3 python3-dev python3-setuptools python3-cffi python3-packaging
|
||||||
- name: Autogen.sh
|
- name: Autogen.sh
|
||||||
run: |
|
run: |
|
||||||
sh autogen.sh
|
sh autogen.sh
|
||||||
|
@ -40,9 +40,26 @@ jobs:
|
||||||
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
|
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
|
||||||
sudo depmod
|
sudo depmod
|
||||||
sudo modprobe zfs
|
sudo modprobe zfs
|
||||||
|
# Workaround for cloud-init bug
|
||||||
|
# see https://github.com/openzfs/zfs/issues/12644
|
||||||
|
FILE=/lib/udev/rules.d/10-cloud-init-hook-hotplug.rules
|
||||||
|
if [ -r "${FILE}" ]; then
|
||||||
|
HASH=$(md5sum "${FILE}" | awk '{ print $1 }')
|
||||||
|
if [ "${HASH}" = "121ff0ef1936cd2ef65aec0458a35772" ]; then
|
||||||
|
# Just shove a zd* exclusion right above the hotplug hook...
|
||||||
|
sudo sed -i -e s/'LABEL="cloudinit_hook"'/'KERNEL=="zd*", GOTO="cloudinit_end"\n&'/ "${FILE}"
|
||||||
|
sudo udevadm control --reload-rules
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# Workaround to provide additional free space for testing.
|
||||||
|
# https://github.com/actions/virtual-environments/issues/2840
|
||||||
|
sudo rm -rf /usr/share/dotnet
|
||||||
|
sudo rm -rf /opt/ghc
|
||||||
|
sudo rm -rf "/usr/local/share/boost"
|
||||||
|
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||||
- name: Tests
|
- name: Tests
|
||||||
run: |
|
run: |
|
||||||
/usr/share/zfs/zfs-tests.sh -v -s 3G -r sanity
|
/usr/share/zfs/zfs-tests.sh -vR -s 3G -r sanity
|
||||||
- name: Prepare artifacts
|
- name: Prepare artifacts
|
||||||
if: failure()
|
if: failure()
|
||||||
run: |
|
run: |
|
||||||
|
@ -50,6 +67,8 @@ jobs:
|
||||||
sudo dmesg > $RESULTS_PATH/dmesg
|
sudo dmesg > $RESULTS_PATH/dmesg
|
||||||
sudo cp /var/log/syslog $RESULTS_PATH/
|
sudo cp /var/log/syslog $RESULTS_PATH/
|
||||||
sudo chmod +r $RESULTS_PATH/*
|
sudo chmod +r $RESULTS_PATH/*
|
||||||
|
# Replace ':' in dir names, actions/upload-artifact doesn't support it
|
||||||
|
for f in $(find /var/tmp/test_results -name '*:*'); do mv "$f" "${f//:/__}"; done
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
|
@ -22,8 +22,8 @@ jobs:
|
||||||
xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \
|
xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \
|
||||||
libssl-dev libffi-dev libaio-dev libelf-dev libmount-dev \
|
libssl-dev libffi-dev libaio-dev libelf-dev libmount-dev \
|
||||||
libpam0g-dev \
|
libpam0g-dev \
|
||||||
python-dev python-setuptools python-cffi \
|
python-dev python-setuptools python-cffi python-packaging \
|
||||||
python3 python3-dev python3-setuptools python3-cffi
|
python3 python3-dev python3-setuptools python3-cffi python3-packaging
|
||||||
- name: Autogen.sh
|
- name: Autogen.sh
|
||||||
run: |
|
run: |
|
||||||
sh autogen.sh
|
sh autogen.sh
|
||||||
|
|
4
META
4
META
|
@ -1,10 +1,10 @@
|
||||||
Meta: 1
|
Meta: 1
|
||||||
Name: zfs
|
Name: zfs
|
||||||
Branch: 1.0
|
Branch: 1.0
|
||||||
Version: 2.0.2
|
Version: 2.0.7
|
||||||
Release: 1
|
Release: 1
|
||||||
Release-Tags: relext
|
Release-Tags: relext
|
||||||
License: CDDL
|
License: CDDL
|
||||||
Author: OpenZFS
|
Author: OpenZFS
|
||||||
Linux-Maximum: 5.10
|
Linux-Maximum: 5.15
|
||||||
Linux-Minimum: 3.10
|
Linux-Minimum: 3.10
|
||||||
|
|
15
Makefile.am
15
Makefile.am
|
@ -25,7 +25,6 @@ endif
|
||||||
|
|
||||||
AUTOMAKE_OPTIONS = foreign
|
AUTOMAKE_OPTIONS = foreign
|
||||||
EXTRA_DIST = autogen.sh copy-builtin
|
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 += config/config.awk config/rpm.am config/deb.am config/tgz.am
|
||||||
EXTRA_DIST += META AUTHORS COPYRIGHT LICENSE NEWS NOTICE README.md
|
EXTRA_DIST += META AUTHORS COPYRIGHT LICENSE NEWS NOTICE README.md
|
||||||
EXTRA_DIST += CODE_OF_CONDUCT.md
|
EXTRA_DIST += CODE_OF_CONDUCT.md
|
||||||
|
@ -162,7 +161,7 @@ checkbashisms:
|
||||||
-o -name '90zfs' -prune \
|
-o -name '90zfs' -prune \
|
||||||
-o -type f ! -name 'config*' \
|
-o -type f ! -name 'config*' \
|
||||||
! -name 'libtool' \
|
! -name 'libtool' \
|
||||||
-exec sh -c 'awk "NR==1 && /\#\!.*bin\/sh.*/ {print FILENAME;}" "{}"' \;); \
|
-exec sh -c 'awk "NR==1 && /#!.*bin\/sh.*/ {print FILENAME;}" "{}"' \;); \
|
||||||
else \
|
else \
|
||||||
echo "skipping checkbashisms because checkbashisms is not installed"; \
|
echo "skipping checkbashisms because checkbashisms is not installed"; \
|
||||||
fi
|
fi
|
||||||
|
@ -204,13 +203,13 @@ vcscheck:
|
||||||
PHONY += lint
|
PHONY += lint
|
||||||
lint: cppcheck paxcheck
|
lint: cppcheck paxcheck
|
||||||
|
|
||||||
|
CPPCHECKDIRS = cmd lib module
|
||||||
PHONY += cppcheck
|
PHONY += cppcheck
|
||||||
cppcheck:
|
cppcheck: $(CPPCHECKDIRS)
|
||||||
@if type cppcheck > /dev/null 2>&1; then \
|
@if test -n "$(CPPCHECK)"; then \
|
||||||
cppcheck --quiet --force --error-exitcode=2 --inline-suppr \
|
set -e ; for dir in $(CPPCHECKDIRS) ; do \
|
||||||
--suppressions-list=${top_srcdir}/cppcheck-suppressions.txt \
|
$(MAKE) -C $$dir cppcheck ; \
|
||||||
-UHAVE_SSE2 -UHAVE_AVX512F -UHAVE_UIO_ZEROCOPY \
|
done \
|
||||||
${top_srcdir}; \
|
|
||||||
else \
|
else \
|
||||||
echo "skipping cppcheck because cppcheck is not installed"; \
|
echo "skipping cppcheck because cppcheck is not installed"; \
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,10 +1,20 @@
|
||||||
SUBDIRS = zfs zpool zdb zhack zinject zstream zstreamdump ztest
|
SUBDIRS = zfs zpool zdb zhack zinject zstream zstreamdump ztest
|
||||||
SUBDIRS += fsck_zfs vdev_id raidz_test zfs_ids_to_path
|
SUBDIRS += fsck_zfs vdev_id raidz_test zfs_ids_to_path
|
||||||
|
|
||||||
|
CPPCHECKDIRS = zfs zpool zdb zhack zinject zstream ztest
|
||||||
|
CPPCHECKDIRS += raidz_test zfs_ids_to_path
|
||||||
|
|
||||||
if USING_PYTHON
|
if USING_PYTHON
|
||||||
SUBDIRS += arcstat arc_summary dbufstat
|
SUBDIRS += arcstat arc_summary dbufstat
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if BUILD_LINUX
|
if BUILD_LINUX
|
||||||
SUBDIRS += mount_zfs zed zgenhostid zvol_id zvol_wait
|
SUBDIRS += mount_zfs zed zgenhostid zvol_id zvol_wait
|
||||||
|
CPPCHECKDIRS += mount_zfs zed zgenhostid zvol_id
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
PHONY = cppcheck
|
||||||
|
cppcheck: $(CPPCHECKDIRS)
|
||||||
|
set -e ; for dir in $(CPPCHECKDIRS) ; do \
|
||||||
|
$(MAKE) -C $$dir cppcheck ; \
|
||||||
|
done
|
||||||
|
|
|
@ -58,7 +58,6 @@ SECTION_PATHS = {'arc': 'arcstats',
|
||||||
'dmu': 'dmu_tx',
|
'dmu': 'dmu_tx',
|
||||||
'l2arc': 'arcstats', # L2ARC stuff lives in arcstats
|
'l2arc': 'arcstats', # L2ARC stuff lives in arcstats
|
||||||
'vdev': 'vdev_cache_stats',
|
'vdev': 'vdev_cache_stats',
|
||||||
'xuio': 'xuio_stats',
|
|
||||||
'zfetch': 'zfetchstats',
|
'zfetch': 'zfetchstats',
|
||||||
'zil': 'zil'}
|
'zil': 'zil'}
|
||||||
|
|
||||||
|
|
|
@ -18,3 +18,5 @@ mount_zfs_LDADD = \
|
||||||
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
|
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
|
||||||
|
|
||||||
mount_zfs_LDADD += $(LTLIBINTL)
|
mount_zfs_LDADD += $(LTLIBINTL)
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|
|
@ -367,7 +367,7 @@ main(int argc, char **argv)
|
||||||
"mount the filesystem again.\n"), dataset);
|
"mount the filesystem again.\n"), dataset);
|
||||||
return (MOUNT_SYSERR);
|
return (MOUNT_SYSERR);
|
||||||
}
|
}
|
||||||
/* fallthru */
|
fallthrough;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
(void) fprintf(stderr, gettext("filesystem "
|
(void) fprintf(stderr, gettext("filesystem "
|
||||||
|
|
|
@ -18,3 +18,5 @@ raidz_test_LDADD = \
|
||||||
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la
|
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la
|
||||||
|
|
||||||
raidz_test_LDADD += -lm
|
raidz_test_LDADD += -lm
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|
|
@ -79,6 +79,34 @@
|
||||||
# channel 86:00.0 1 A
|
# channel 86:00.0 1 A
|
||||||
# channel 86:00.0 0 B
|
# 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
|
# # Example vdev_id.conf - alias
|
||||||
# #
|
# #
|
||||||
|
@ -92,9 +120,10 @@ PATH=/bin:/sbin:/usr/bin:/usr/sbin
|
||||||
CONFIG=/etc/zfs/vdev_id.conf
|
CONFIG=/etc/zfs/vdev_id.conf
|
||||||
PHYS_PER_PORT=
|
PHYS_PER_PORT=
|
||||||
DEV=
|
DEV=
|
||||||
MULTIPATH=
|
|
||||||
TOPOLOGY=
|
TOPOLOGY=
|
||||||
BAY=
|
BAY=
|
||||||
|
ENCL_ID=""
|
||||||
|
UNIQ_ENCL_ID=""
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat << EOF
|
cat << EOF
|
||||||
|
@ -107,22 +136,25 @@ Usage: vdev_id [-h]
|
||||||
-e Create enclose device symlinks only (/dev/by-enclosure)
|
-e Create enclose device symlinks only (/dev/by-enclosure)
|
||||||
-g Storage network topology [default="$TOPOLOGY"]
|
-g Storage network topology [default="$TOPOLOGY"]
|
||||||
-m Run in multipath mode
|
-m Run in multipath mode
|
||||||
|
-j Run in multijbod mode
|
||||||
-p number of phy's per switch port [default=$PHYS_PER_PORT]
|
-p number of phy's per switch port [default=$PHYS_PER_PORT]
|
||||||
-h show this summary
|
-h show this summary
|
||||||
EOF
|
EOF
|
||||||
exit 0
|
exit 1
|
||||||
|
# exit with error to avoid processing usage message by a udev rule
|
||||||
}
|
}
|
||||||
|
|
||||||
map_slot() {
|
map_slot() {
|
||||||
LINUX_SLOT=$1
|
LINUX_SLOT=$1
|
||||||
CHANNEL=$2
|
CHANNEL=$2
|
||||||
|
|
||||||
MAPPED_SLOT=`awk "\\$1 == \"slot\" && \\$2 == ${LINUX_SLOT} && \
|
MAPPED_SLOT=$(awk -v linux_slot="$LINUX_SLOT" -v channel="$CHANNEL" \
|
||||||
\\$4 ~ /^${CHANNEL}$|^$/ { print \\$3; exit }" $CONFIG`
|
'$1 == "slot" && $2 == linux_slot && \
|
||||||
|
($4 ~ "^"channel"$" || $4 ~ /^$/) { print $3; exit}' $CONFIG)
|
||||||
if [ -z "$MAPPED_SLOT" ] ; then
|
if [ -z "$MAPPED_SLOT" ] ; then
|
||||||
MAPPED_SLOT=$LINUX_SLOT
|
MAPPED_SLOT=$LINUX_SLOT
|
||||||
fi
|
fi
|
||||||
printf "%d" ${MAPPED_SLOT}
|
printf "%d" "${MAPPED_SLOT}"
|
||||||
}
|
}
|
||||||
|
|
||||||
map_channel() {
|
map_channel() {
|
||||||
|
@ -132,40 +164,120 @@ map_channel() {
|
||||||
|
|
||||||
case $TOPOLOGY in
|
case $TOPOLOGY in
|
||||||
"sas_switch")
|
"sas_switch")
|
||||||
MAPPED_CHAN=`awk "\\$1 == \"channel\" && \\$2 == ${PORT} \
|
MAPPED_CHAN=$(awk -v port="$PORT" \
|
||||||
{ print \\$3; exit }" $CONFIG`
|
'$1 == "channel" && $2 == port \
|
||||||
|
{ print $3; exit }' $CONFIG)
|
||||||
;;
|
;;
|
||||||
"sas_direct"|"scsi")
|
"sas_direct"|"scsi")
|
||||||
MAPPED_CHAN=`awk "\\$1 == \"channel\" && \
|
MAPPED_CHAN=$(awk -v pciID="$PCI_ID" -v port="$PORT" \
|
||||||
\\$2 == \"${PCI_ID}\" && \\$3 == ${PORT} \
|
'$1 == "channel" && $2 == pciID && $3 == port \
|
||||||
{ print \\$4; exit }" $CONFIG`
|
{print $4}' $CONFIG)
|
||||||
;;
|
;;
|
||||||
esac
|
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() {
|
sas_handler() {
|
||||||
if [ -z "$PHYS_PER_PORT" ] ; then
|
if [ -z "$PHYS_PER_PORT" ] ; then
|
||||||
PHYS_PER_PORT=`awk "\\$1 == \"phys_per_port\" \
|
PHYS_PER_PORT=$(awk '$1 == "phys_per_port" \
|
||||||
{print \\$2; exit}" $CONFIG`
|
{print $2; exit}' $CONFIG)
|
||||||
fi
|
fi
|
||||||
PHYS_PER_PORT=${PHYS_PER_PORT:-4}
|
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"
|
echo "Error: phys_per_port value $PHYS_PER_PORT is non-numeric"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$MULTIPATH_MODE" ] ; then
|
if [ -z "$MULTIPATH_MODE" ] ; then
|
||||||
MULTIPATH_MODE=`awk "\\$1 == \"multipath\" \
|
MULTIPATH_MODE=$(awk '$1 == "multipath" \
|
||||||
{print \\$2; exit}" $CONFIG`
|
{print $2; exit}' $CONFIG)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$MULTIJBOD_MODE" ] ; then
|
||||||
|
MULTIJBOD_MODE=$(awk '$1 == "multijbod" \
|
||||||
|
{print $2; exit}' $CONFIG)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Use first running component device if we're handling a dm-mpath device
|
# Use first running component device if we're handling a dm-mpath device
|
||||||
if [ "$MULTIPATH_MODE" = "yes" ] ; then
|
if [ "$MULTIPATH_MODE" = "yes" ] ; then
|
||||||
# If udev didn't tell us the UUID via DM_NAME, check /dev/mapper
|
# If udev didn't tell us the UUID via DM_NAME, check /dev/mapper
|
||||||
if [ -z "$DM_NAME" ] ; then
|
if [ -z "$DM_NAME" ] ; then
|
||||||
DM_NAME=`ls -l --full-time /dev/mapper |
|
DM_NAME=$(ls -l --full-time /dev/mapper |
|
||||||
awk "/\/$DEV$/{print \\$9}"`
|
grep "$DEV"$ | awk '{print $9}')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# For raw disks udev exports DEVTYPE=partition when
|
# For raw disks udev exports DEVTYPE=partition when
|
||||||
|
@ -175,28 +287,50 @@ sas_handler() {
|
||||||
# we have to append the -part suffix directly in the
|
# we have to append the -part suffix directly in the
|
||||||
# helper.
|
# helper.
|
||||||
if [ "$DEVTYPE" != "partition" ] ; then
|
if [ "$DEVTYPE" != "partition" ] ; then
|
||||||
PART=`echo $DM_NAME | awk -Fp '/p/{print "-part"$2}'`
|
# Match p[number], remove the 'p' and prepend "-part"
|
||||||
|
PART=$(echo "$DM_NAME" |
|
||||||
|
awk 'match($0,/p[0-9]+$/) {print "-part"substr($0,RSTART+1,RLENGTH-1)}')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Strip off partition information.
|
# 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
|
if [ -z "$DM_NAME" ] ; then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get the raw scsi device name from multipath -ll. Strip off
|
# Utilize DM device name to gather subordinate block devices
|
||||||
# leading pipe symbols to make field numbering consistent.
|
# using sysfs to avoid userspace utilities
|
||||||
DEV=`multipath -ll $DM_NAME |
|
|
||||||
awk '/running/{gsub("^[|]"," "); print $3 ; exit}'`
|
# If our DEVNAME is something like /dev/dm-177, then we may be
|
||||||
|
# able to get our DMDEV from it.
|
||||||
|
DMDEV=$(echo $DEVNAME | sed 's;/dev/;;g')
|
||||||
|
if [ ! -e /sys/block/$DMDEV/slaves/* ] ; then
|
||||||
|
# It's not there, try looking in /dev/mapper
|
||||||
|
DMDEV=$(ls -l --full-time /dev/mapper | grep $DM_NAME |
|
||||||
|
awk '{gsub("../", " "); print $NF}')
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 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
|
if [ -z "$DEV" ] ; then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if echo $DEV | grep -q ^/devices/ ; then
|
if echo "$DEV" | grep -q ^/devices/ ; then
|
||||||
sys_path=$DEV
|
sys_path=$DEV
|
||||||
else
|
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
|
fi
|
||||||
|
|
||||||
# Use positional parameters as an ad-hoc array
|
# Use positional parameters as an ad-hoc array
|
||||||
|
@ -206,84 +340,104 @@ sas_handler() {
|
||||||
|
|
||||||
# Get path up to /sys/.../hostX
|
# Get path up to /sys/.../hostX
|
||||||
i=1
|
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"
|
scsi_host_dir="$scsi_host_dir/$d"
|
||||||
echo $d | grep -q -E '^host[0-9]+$' && break
|
echo "$d" | grep -q -E '^host[0-9]+$' && break
|
||||||
i=$(($i + 1))
|
i=$((i + 1))
|
||||||
done
|
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
|
return
|
||||||
fi
|
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
|
# In sas_switch mode, the directory four levels beneath
|
||||||
# /sys/.../hostX contains symlinks to phy devices that reveal
|
# /sys/.../hostX contains symlinks to phy devices that reveal
|
||||||
# the switch port number. In sas_direct mode, the phy links one
|
# the switch port number. In sas_direct mode, the phy links one
|
||||||
# directory down reveal the HBA port.
|
# directory down reveal the HBA port.
|
||||||
port_dir=$scsi_host_dir
|
port_dir=$scsi_host_dir
|
||||||
|
|
||||||
case $TOPOLOGY in
|
case $TOPOLOGY in
|
||||||
"sas_switch") j=$(($i + 4)) ;;
|
"sas_switch") j=$((i + 4)) ;;
|
||||||
"sas_direct") j=$(($i + 1)) ;;
|
"sas_direct") j=$((i + 1)) ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
i=$(($i + 1))
|
i=$((i + 1))
|
||||||
|
|
||||||
while [ $i -le $j ] ; do
|
while [ $i -le $j ] ; do
|
||||||
port_dir="$port_dir/$(eval echo \${$i})"
|
port_dir="$port_dir/$(eval echo '$'{$i})"
|
||||||
i=$(($i + 1))
|
i=$((i + 1))
|
||||||
done
|
done
|
||||||
|
|
||||||
PHY=`ls -d $port_dir/phy* 2>/dev/null | head -1 | awk -F: '{print $NF}'`
|
PHY=$(ls -vd "$port_dir"/phy* 2>/dev/null | head -1 | awk -F: '{print $NF}')
|
||||||
if [ -z "$PHY" ] ; then
|
if [ -z "$PHY" ] ; then
|
||||||
PHY=0
|
PHY=0
|
||||||
fi
|
fi
|
||||||
PORT=$(( $PHY / $PHYS_PER_PORT ))
|
PORT=$((PHY / PHYS_PER_PORT))
|
||||||
|
|
||||||
# Look in /sys/.../sas_device/end_device-X for the bay_identifier
|
# Look in /sys/.../sas_device/end_device-X for the bay_identifier
|
||||||
# attribute.
|
# attribute.
|
||||||
end_device_dir=$port_dir
|
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"
|
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"
|
end_device_dir="$end_device_dir/sas_device/$d"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
i=$(($i + 1))
|
i=$((i + 1))
|
||||||
done
|
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=
|
SLOT=
|
||||||
|
|
||||||
case $BAY in
|
case $BAY in
|
||||||
"bay")
|
"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")
|
"phy")
|
||||||
SLOT=`cat $end_device_dir/phy_identifier 2>/dev/null`
|
SLOT=$(cat "$end_device_dir/phy_identifier" 2>/dev/null)
|
||||||
;;
|
;;
|
||||||
"port")
|
"port")
|
||||||
d=$(eval echo \${$i})
|
d=$(eval echo '$'{$i})
|
||||||
SLOT=`echo $d | sed -e 's/^.*://'`
|
SLOT=$(echo "$d" | sed -e 's/^.*://')
|
||||||
;;
|
;;
|
||||||
"id")
|
"id")
|
||||||
i=$(($i + 1))
|
i=$((i + 1))
|
||||||
d=$(eval echo \${$i})
|
d=$(eval echo '$'{$i})
|
||||||
SLOT=`echo $d | sed -e 's/^.*://'`
|
SLOT=$(echo "$d" | sed -e 's/^.*://')
|
||||||
;;
|
;;
|
||||||
"lun")
|
"lun")
|
||||||
i=$(($i + 2))
|
i=$((i + 2))
|
||||||
d=$(eval echo \${$i})
|
d=$(eval echo '$'{$i})
|
||||||
SLOT=`echo $d | sed -e 's/^.*://'`
|
SLOT=$(echo "$d" | sed -e 's/^.*://')
|
||||||
;;
|
;;
|
||||||
"ses")
|
"ses")
|
||||||
# look for this SAS path in all SCSI Enclosure Services
|
# look for this SAS path in all SCSI Enclosure Services
|
||||||
# (SES) enclosures
|
# (SES) enclosures
|
||||||
sas_address=`cat $end_device_dir/sas_address 2>/dev/null`
|
sas_address=$(cat "$end_device_dir/sas_address" 2>/dev/null)
|
||||||
enclosures=`lsscsi -g | \
|
enclosures=$(lsscsi -g | \
|
||||||
sed -n -e '/enclosu/s/^.* \([^ ][^ ]*\) *$/\1/p'`
|
sed -n -e '/enclosu/s/^.* \([^ ][^ ]*\) *$/\1/p')
|
||||||
for enclosure in $enclosures; do
|
for enclosure in $enclosures; do
|
||||||
set -- $(sg_ses -p aes $enclosure | \
|
set -- $(sg_ses -p aes "$enclosure" | \
|
||||||
awk "/device slot number:/{slot=\$12} \
|
awk "/device slot number:/{slot=\$12} \
|
||||||
/SAS address: $sas_address/\
|
/SAS address: $sas_address/\
|
||||||
{print slot}")
|
{print slot}")
|
||||||
|
@ -298,42 +452,55 @@ sas_handler() {
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CHAN=`map_channel $PCI_ID $PORT`
|
if [ "$MULTIJBOD_MODE" = "yes" ] ; then
|
||||||
SLOT=`map_slot $SLOT $CHAN`
|
CHAN=$(map_channel "$PCI_ID" "$PORT")
|
||||||
|
SLOT=$(map_slot "$SLOT" "$CHAN")
|
||||||
|
JBOD=$(map_jbod "$DEV")
|
||||||
|
|
||||||
if [ -z "$CHAN" ] ; then
|
if [ -z "$CHAN" ] ; then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
echo ${CHAN}${SLOT}${PART}
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
scsi_handler() {
|
scsi_handler() {
|
||||||
if [ -z "$FIRST_BAY_NUMBER" ] ; then
|
if [ -z "$FIRST_BAY_NUMBER" ] ; then
|
||||||
FIRST_BAY_NUMBER=`awk "\\$1 == \"first_bay_number\" \
|
FIRST_BAY_NUMBER=$(awk '$1 == "first_bay_number" \
|
||||||
{print \\$2; exit}" $CONFIG`
|
{print $2; exit}' $CONFIG)
|
||||||
fi
|
fi
|
||||||
FIRST_BAY_NUMBER=${FIRST_BAY_NUMBER:-0}
|
FIRST_BAY_NUMBER=${FIRST_BAY_NUMBER:-0}
|
||||||
|
|
||||||
if [ -z "$PHYS_PER_PORT" ] ; then
|
if [ -z "$PHYS_PER_PORT" ] ; then
|
||||||
PHYS_PER_PORT=`awk "\\$1 == \"phys_per_port\" \
|
PHYS_PER_PORT=$(awk '$1 == "phys_per_port" \
|
||||||
{print \\$2; exit}" $CONFIG`
|
{print $2; exit}' $CONFIG)
|
||||||
fi
|
fi
|
||||||
PHYS_PER_PORT=${PHYS_PER_PORT:-4}
|
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"
|
echo "Error: phys_per_port value $PHYS_PER_PORT is non-numeric"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$MULTIPATH_MODE" ] ; then
|
if [ -z "$MULTIPATH_MODE" ] ; then
|
||||||
MULTIPATH_MODE=`awk "\\$1 == \"multipath\" \
|
MULTIPATH_MODE=$(awk '$1 == "multipath" \
|
||||||
{print \\$2; exit}" $CONFIG`
|
{print $2; exit}' $CONFIG)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Use first running component device if we're handling a dm-mpath device
|
# Use first running component device if we're handling a dm-mpath device
|
||||||
if [ "$MULTIPATH_MODE" = "yes" ] ; then
|
if [ "$MULTIPATH_MODE" = "yes" ] ; then
|
||||||
# If udev didn't tell us the UUID via DM_NAME, check /dev/mapper
|
# If udev didn't tell us the UUID via DM_NAME, check /dev/mapper
|
||||||
if [ -z "$DM_NAME" ] ; then
|
if [ -z "$DM_NAME" ] ; then
|
||||||
DM_NAME=`ls -l --full-time /dev/mapper |
|
DM_NAME=$(ls -l --full-time /dev/mapper |
|
||||||
awk "/\/$DEV$/{print \\$9}"`
|
grep "$DEV"$ | awk '{print $9}')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# For raw disks udev exports DEVTYPE=partition when
|
# For raw disks udev exports DEVTYPE=partition when
|
||||||
|
@ -343,28 +510,30 @@ scsi_handler() {
|
||||||
# we have to append the -part suffix directly in the
|
# we have to append the -part suffix directly in the
|
||||||
# helper.
|
# helper.
|
||||||
if [ "$DEVTYPE" != "partition" ] ; then
|
if [ "$DEVTYPE" != "partition" ] ; then
|
||||||
PART=`echo $DM_NAME | awk -Fp '/p/{print "-part"$2}'`
|
# Match p[number], remove the 'p' and prepend "-part"
|
||||||
|
PART=$(echo "$DM_NAME" |
|
||||||
|
awk 'match($0,/p[0-9]+$/) {print "-part"substr($0,RSTART+1,RLENGTH-1)}')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Strip off partition information.
|
# 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
|
if [ -z "$DM_NAME" ] ; then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get the raw scsi device name from multipath -ll. Strip off
|
# Get the raw scsi device name from multipath -ll. Strip off
|
||||||
# leading pipe symbols to make field numbering consistent.
|
# leading pipe symbols to make field numbering consistent.
|
||||||
DEV=`multipath -ll $DM_NAME |
|
DEV=$(multipath -ll "$DM_NAME" |
|
||||||
awk '/running/{gsub("^[|]"," "); print $3 ; exit}'`
|
awk '/running/{gsub("^[|]"," "); print $3 ; exit}')
|
||||||
if [ -z "$DEV" ] ; then
|
if [ -z "$DEV" ] ; then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if echo $DEV | grep -q ^/devices/ ; then
|
if echo "$DEV" | grep -q ^/devices/ ; then
|
||||||
sys_path=$DEV
|
sys_path=$DEV
|
||||||
else
|
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
|
fi
|
||||||
|
|
||||||
# expect sys_path like this, for example:
|
# expect sys_path like this, for example:
|
||||||
|
@ -377,44 +546,47 @@ scsi_handler() {
|
||||||
|
|
||||||
# Get path up to /sys/.../hostX
|
# Get path up to /sys/.../hostX
|
||||||
i=1
|
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"
|
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
|
done
|
||||||
|
|
||||||
if [ $i = $num_dirs ] ; then
|
if [ $i = "$num_dirs" ] ; then
|
||||||
return
|
return
|
||||||
fi
|
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
|
# In scsi mode, the directory two levels beneath
|
||||||
# /sys/.../hostX reveals the port and slot.
|
# /sys/.../hostX reveals the port and slot.
|
||||||
port_dir=$scsi_host_dir
|
port_dir=$scsi_host_dir
|
||||||
j=$(($i + 2))
|
j=$((i + 2))
|
||||||
|
|
||||||
i=$(($i + 1))
|
i=$((i + 1))
|
||||||
while [ $i -le $j ] ; do
|
while [ $i -le $j ] ; do
|
||||||
port_dir="$port_dir/$(eval echo \${$i})"
|
port_dir="$port_dir/$(eval echo '$'{$i})"
|
||||||
i=$(($i + 1))
|
i=$((i + 1))
|
||||||
done
|
done
|
||||||
|
|
||||||
set -- $(echo $port_dir | sed -e 's/^.*:\([^:]*\):\([^:]*\)$/\1 \2/')
|
set -- $(echo "$port_dir" | sed -e 's/^.*:\([^:]*\):\([^:]*\)$/\1 \2/')
|
||||||
PORT=$1
|
PORT=$1
|
||||||
SLOT=$(($2 + $FIRST_BAY_NUMBER))
|
SLOT=$(($2 + FIRST_BAY_NUMBER))
|
||||||
|
|
||||||
if [ -z "$SLOT" ] ; then
|
if [ -z "$SLOT" ] ; then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CHAN=`map_channel $PCI_ID $PORT`
|
CHAN=$(map_channel "$PCI_ID" "$PORT")
|
||||||
SLOT=`map_slot $SLOT $CHAN`
|
SLOT=$(map_slot "$SLOT" "$CHAN")
|
||||||
|
|
||||||
if [ -z "$CHAN" ] ; then
|
if [ -z "$CHAN" ] ; then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
echo ${CHAN}${SLOT}${PART}
|
echo "${CHAN}${SLOT}${PART}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Figure out the name for the enclosure symlink
|
# Figure out the name for the enclosure symlink
|
||||||
|
@ -425,7 +597,7 @@ enclosure_handler () {
|
||||||
|
|
||||||
# Get the enclosure ID ("0:0:0:0")
|
# Get the enclosure ID ("0:0:0:0")
|
||||||
ENC=$(basename $(readlink -m "/sys/$DEVPATH/../.."))
|
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
|
# Not an enclosure, bail out
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
@ -433,14 +605,14 @@ enclosure_handler () {
|
||||||
# Get the long sysfs device path to our enclosure. Looks like:
|
# 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
|
# /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:
|
# Grab the full path to the hosts port dir:
|
||||||
# /devices/pci0000:00/0000:00:03.0/0000:05:00.0/host0/port-0:0
|
# /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
|
# 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
|
# The PCI directory is two directories up from the port directory
|
||||||
# /sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0
|
# /sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0
|
||||||
|
@ -451,7 +623,7 @@ enclosure_handler () {
|
||||||
|
|
||||||
# Name our device according to vdev_id.conf (like "L0" or "U1").
|
# Name our device according to vdev_id.conf (like "L0" or "U1").
|
||||||
NAME=$(awk "/channel/{if (\$1 == \"channel\" && \$2 == \"$PCI_ID\" && \
|
NAME=$(awk "/channel/{if (\$1 == \"channel\" && \$2 == \"$PCI_ID\" && \
|
||||||
\$3 == \"$PORT_ID\") {print \$4int(count[\$4])}; count[\$4]++}" $CONFIG)
|
\$3 == \"$PORT_ID\") {print \$4\$3}}" $CONFIG)
|
||||||
|
|
||||||
echo "${NAME}"
|
echo "${NAME}"
|
||||||
}
|
}
|
||||||
|
@ -487,9 +659,11 @@ alias_handler () {
|
||||||
# ambiguity seems unavoidable, so devices using this facility
|
# ambiguity seems unavoidable, so devices using this facility
|
||||||
# must not use such names.
|
# must not use such names.
|
||||||
DM_PART=
|
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
|
if [ "$DEVTYPE" != "partition" ] ; then
|
||||||
DM_PART=`echo $DM_NAME | awk -Fp '/p/{print "-part"$2}'`
|
# Match p[number], remove the 'p' and prepend "-part"
|
||||||
|
DM_PART=$(echo "$DM_NAME" |
|
||||||
|
awk 'match($0,/p[0-9]+$/) {print "-part"substr($0,RSTART+1,RLENGTH-1)}')
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -497,21 +671,25 @@ alias_handler () {
|
||||||
for link in $DEVLINKS ; do
|
for link in $DEVLINKS ; do
|
||||||
# Remove partition information to match key of top-level device.
|
# Remove partition information to match key of top-level device.
|
||||||
if [ -n "$DM_PART" ] ; then
|
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
|
fi
|
||||||
# Check both the fully qualified and the base name of link.
|
# Check both the fully qualified and the base name of link.
|
||||||
for l in $link `basename $link` ; do
|
for l in $link $(basename "$link") ; do
|
||||||
alias=`awk "\\$1 == \"alias\" && \\$3 == \"${l}\" \
|
if [ ! -z "$l" ]; then
|
||||||
{ print \\$2; exit }" $CONFIG`
|
alias=$(awk -v var="$l" '($1 == "alias") && \
|
||||||
|
($3 == var) \
|
||||||
|
{ print $2; exit }' $CONFIG)
|
||||||
if [ -n "$alias" ] ; then
|
if [ -n "$alias" ] ; then
|
||||||
echo ${alias}${DM_PART}
|
echo "${alias}${DM_PART}"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
while getopts 'c:d:eg:mp:h' OPTION; do
|
# main
|
||||||
|
while getopts 'c:d:eg:jmp:h' OPTION; do
|
||||||
case ${OPTION} in
|
case ${OPTION} in
|
||||||
c)
|
c)
|
||||||
CONFIG=${OPTARG}
|
CONFIG=${OPTARG}
|
||||||
|
@ -524,7 +702,9 @@ while getopts 'c:d:eg:mp:h' OPTION; do
|
||||||
# create the enclosure device symlinks only. We also need
|
# create the enclosure device symlinks only. We also need
|
||||||
# "enclosure_symlinks yes" set in vdev_id.config to actually create the
|
# "enclosure_symlinks yes" set in vdev_id.config to actually create the
|
||||||
# symlink.
|
# 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
|
if [ "$ENCLOSURE_MODE" != "yes" ] ; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
@ -535,6 +715,9 @@ while getopts 'c:d:eg:mp:h' OPTION; do
|
||||||
p)
|
p)
|
||||||
PHYS_PER_PORT=${OPTARG}
|
PHYS_PER_PORT=${OPTARG}
|
||||||
;;
|
;;
|
||||||
|
j)
|
||||||
|
MULTIJBOD_MODE=yes
|
||||||
|
;;
|
||||||
m)
|
m)
|
||||||
MULTIPATH_MODE=yes
|
MULTIPATH_MODE=yes
|
||||||
;;
|
;;
|
||||||
|
@ -544,9 +727,9 @@ while getopts 'c:d:eg:mp:h' OPTION; do
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ ! -r $CONFIG ] ; then
|
if [ ! -r "$CONFIG" ] ; then
|
||||||
echo "Error: Config file \"$CONFIG\" not found"
|
echo "Error: Config file \"$CONFIG\" not found"
|
||||||
exit 0
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$DEV" ] && [ -z "$ENCLOSURE_MODE" ] ; then
|
if [ -z "$DEV" ] && [ -z "$ENCLOSURE_MODE" ] ; then
|
||||||
|
@ -555,11 +738,11 @@ if [ -z "$DEV" ] && [ -z "$ENCLOSURE_MODE" ] ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$TOPOLOGY" ] ; then
|
if [ -z "$TOPOLOGY" ] ; then
|
||||||
TOPOLOGY=`awk "\\$1 == \"topology\" {print \\$2; exit}" $CONFIG`
|
TOPOLOGY=$(awk '($1 == "topology") {print $2; exit}' "$CONFIG")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$BAY" ] ; then
|
if [ -z "$BAY" ] ; then
|
||||||
BAY=`awk "\\$1 == \"slot\" {print \\$2; exit}" $CONFIG`
|
BAY=$(awk '($1 == "slot") {print $2; exit}' "$CONFIG")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
TOPOLOGY=${TOPOLOGY:-sas_direct}
|
TOPOLOGY=${TOPOLOGY:-sas_direct}
|
||||||
|
@ -572,7 +755,7 @@ if [ "$ENCLOSURE_MODE" = "yes" ] && [ "$TOPOLOGY" = "sas_direct" ] ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Just create the symlinks to the enclosure devices and then exit.
|
# 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
|
if [ -z "$ENCLOSURE_PREFIX" ] ; then
|
||||||
ENCLOSURE_PREFIX="enc"
|
ENCLOSURE_PREFIX="enc"
|
||||||
fi
|
fi
|
||||||
|
@ -582,16 +765,16 @@ if [ "$ENCLOSURE_MODE" = "yes" ] && [ "$TOPOLOGY" = "sas_direct" ] ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# First check if an alias was defined for this device.
|
# First check if an alias was defined for this device.
|
||||||
ID_VDEV=`alias_handler`
|
ID_VDEV=$(alias_handler)
|
||||||
|
|
||||||
if [ -z "$ID_VDEV" ] ; then
|
if [ -z "$ID_VDEV" ] ; then
|
||||||
BAY=${BAY:-bay}
|
BAY=${BAY:-bay}
|
||||||
case $TOPOLOGY in
|
case $TOPOLOGY in
|
||||||
sas_direct|sas_switch)
|
sas_direct|sas_switch)
|
||||||
ID_VDEV=`sas_handler`
|
ID_VDEV=$(sas_handler)
|
||||||
;;
|
;;
|
||||||
scsi)
|
scsi)
|
||||||
ID_VDEV=`scsi_handler`
|
ID_VDEV=$(scsi_handler)
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Error: unknown topology $TOPOLOGY"
|
echo "Error: unknown topology $TOPOLOGY"
|
||||||
|
|
|
@ -14,3 +14,5 @@ zdb_LDADD = \
|
||||||
$(abs_top_builddir)/lib/libzpool/libzpool.la \
|
$(abs_top_builddir)/lib/libzpool/libzpool.la \
|
||||||
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
||||||
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
|
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|
132
cmd/zdb/zdb.c
132
cmd/zdb/zdb.c
|
@ -161,12 +161,6 @@ static int dump_bpobj_cb(void *arg, const blkptr_t *bp, boolean_t free,
|
||||||
dmu_tx_t *tx);
|
dmu_tx_t *tx);
|
||||||
|
|
||||||
typedef struct sublivelist_verify {
|
typedef struct sublivelist_verify {
|
||||||
/* all ALLOC'd blkptr_t in one sub-livelist */
|
|
||||||
zfs_btree_t sv_all_allocs;
|
|
||||||
|
|
||||||
/* all FREE'd blkptr_t in one sub-livelist */
|
|
||||||
zfs_btree_t sv_all_frees;
|
|
||||||
|
|
||||||
/* FREE's that haven't yet matched to an ALLOC, in one sub-livelist */
|
/* FREE's that haven't yet matched to an ALLOC, in one sub-livelist */
|
||||||
zfs_btree_t sv_pair;
|
zfs_btree_t sv_pair;
|
||||||
|
|
||||||
|
@ -225,29 +219,68 @@ typedef struct sublivelist_verify_block {
|
||||||
|
|
||||||
static void zdb_print_blkptr(const blkptr_t *bp, int flags);
|
static void zdb_print_blkptr(const blkptr_t *bp, int flags);
|
||||||
|
|
||||||
|
typedef struct sublivelist_verify_block_refcnt {
|
||||||
|
/* block pointer entry in livelist being verified */
|
||||||
|
blkptr_t svbr_blk;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Refcount gets incremented to 1 when we encounter the first
|
||||||
|
* FREE entry for the svfbr block pointer and a node for it
|
||||||
|
* is created in our ZDB verification/tracking metadata.
|
||||||
|
*
|
||||||
|
* As we encounter more FREE entries we increment this counter
|
||||||
|
* and similarly decrement it whenever we find the respective
|
||||||
|
* ALLOC entries for this block.
|
||||||
|
*
|
||||||
|
* When the refcount gets to 0 it means that all the FREE and
|
||||||
|
* ALLOC entries of this block have paired up and we no longer
|
||||||
|
* need to track it in our verification logic (e.g. the node
|
||||||
|
* containing this struct in our verification data structure
|
||||||
|
* should be freed).
|
||||||
|
*
|
||||||
|
* [refer to sublivelist_verify_blkptr() for the actual code]
|
||||||
|
*/
|
||||||
|
uint32_t svbr_refcnt;
|
||||||
|
} sublivelist_verify_block_refcnt_t;
|
||||||
|
|
||||||
|
static int
|
||||||
|
sublivelist_block_refcnt_compare(const void *larg, const void *rarg)
|
||||||
|
{
|
||||||
|
const sublivelist_verify_block_refcnt_t *l = larg;
|
||||||
|
const sublivelist_verify_block_refcnt_t *r = rarg;
|
||||||
|
return (livelist_compare(&l->svbr_blk, &r->svbr_blk));
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sublivelist_verify_blkptr(void *arg, const blkptr_t *bp, boolean_t free,
|
sublivelist_verify_blkptr(void *arg, const blkptr_t *bp, boolean_t free,
|
||||||
dmu_tx_t *tx)
|
dmu_tx_t *tx)
|
||||||
{
|
{
|
||||||
ASSERT3P(tx, ==, NULL);
|
ASSERT3P(tx, ==, NULL);
|
||||||
struct sublivelist_verify *sv = arg;
|
struct sublivelist_verify *sv = arg;
|
||||||
char blkbuf[BP_SPRINTF_LEN];
|
sublivelist_verify_block_refcnt_t current = {
|
||||||
|
.svbr_blk = *bp,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start with 1 in case this is the first free entry.
|
||||||
|
* This field is not used for our B-Tree comparisons
|
||||||
|
* anyway.
|
||||||
|
*/
|
||||||
|
.svbr_refcnt = 1,
|
||||||
|
};
|
||||||
|
|
||||||
zfs_btree_index_t where;
|
zfs_btree_index_t where;
|
||||||
|
sublivelist_verify_block_refcnt_t *pair =
|
||||||
|
zfs_btree_find(&sv->sv_pair, ¤t, &where);
|
||||||
if (free) {
|
if (free) {
|
||||||
zfs_btree_add(&sv->sv_pair, bp);
|
if (pair == NULL) {
|
||||||
/* Check if the FREE is a duplicate */
|
/* first free entry for this block pointer */
|
||||||
if (zfs_btree_find(&sv->sv_all_frees, bp, &where) != NULL) {
|
zfs_btree_add(&sv->sv_pair, ¤t);
|
||||||
snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), bp,
|
|
||||||
free);
|
|
||||||
(void) printf("\tERROR: Duplicate FREE: %s\n", blkbuf);
|
|
||||||
} else {
|
} else {
|
||||||
zfs_btree_add_idx(&sv->sv_all_frees, bp, &where);
|
pair->svbr_refcnt++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Check if the ALLOC has been freed */
|
if (pair == NULL) {
|
||||||
if (zfs_btree_find(&sv->sv_pair, bp, &where) != NULL) {
|
/* block that is currently marked as allocated */
|
||||||
zfs_btree_remove_idx(&sv->sv_pair, &where);
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < SPA_DVAS_PER_BP; i++) {
|
for (int i = 0; i < SPA_DVAS_PER_BP; i++) {
|
||||||
if (DVA_IS_EMPTY(&bp->blk_dva[i]))
|
if (DVA_IS_EMPTY(&bp->blk_dva[i]))
|
||||||
break;
|
break;
|
||||||
|
@ -262,16 +295,16 @@ sublivelist_verify_blkptr(void *arg, const blkptr_t *bp, boolean_t free,
|
||||||
&svb, &where);
|
&svb, &where);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/* Check if the ALLOC is a duplicate */
|
|
||||||
if (zfs_btree_find(&sv->sv_all_allocs, bp, &where) != NULL) {
|
|
||||||
snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), bp,
|
|
||||||
free);
|
|
||||||
(void) printf("\tERROR: Duplicate ALLOC: %s\n", blkbuf);
|
|
||||||
} else {
|
} else {
|
||||||
zfs_btree_add_idx(&sv->sv_all_allocs, bp, &where);
|
/* alloc matches a free entry */
|
||||||
|
pair->svbr_refcnt--;
|
||||||
|
if (pair->svbr_refcnt == 0) {
|
||||||
|
/* all allocs and frees have been matched */
|
||||||
|
zfs_btree_remove_idx(&sv->sv_pair, &where);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,32 +312,22 @@ static int
|
||||||
sublivelist_verify_func(void *args, dsl_deadlist_entry_t *dle)
|
sublivelist_verify_func(void *args, dsl_deadlist_entry_t *dle)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
char blkbuf[BP_SPRINTF_LEN];
|
|
||||||
struct sublivelist_verify *sv = args;
|
struct sublivelist_verify *sv = args;
|
||||||
|
|
||||||
zfs_btree_create(&sv->sv_all_allocs, livelist_compare,
|
zfs_btree_create(&sv->sv_pair, sublivelist_block_refcnt_compare,
|
||||||
sizeof (blkptr_t));
|
sizeof (sublivelist_verify_block_refcnt_t));
|
||||||
|
|
||||||
zfs_btree_create(&sv->sv_all_frees, livelist_compare,
|
|
||||||
sizeof (blkptr_t));
|
|
||||||
|
|
||||||
zfs_btree_create(&sv->sv_pair, livelist_compare,
|
|
||||||
sizeof (blkptr_t));
|
|
||||||
|
|
||||||
err = bpobj_iterate_nofree(&dle->dle_bpobj, sublivelist_verify_blkptr,
|
err = bpobj_iterate_nofree(&dle->dle_bpobj, sublivelist_verify_blkptr,
|
||||||
sv, NULL);
|
sv, NULL);
|
||||||
|
|
||||||
zfs_btree_clear(&sv->sv_all_allocs);
|
sublivelist_verify_block_refcnt_t *e;
|
||||||
zfs_btree_destroy(&sv->sv_all_allocs);
|
|
||||||
|
|
||||||
zfs_btree_clear(&sv->sv_all_frees);
|
|
||||||
zfs_btree_destroy(&sv->sv_all_frees);
|
|
||||||
|
|
||||||
blkptr_t *e;
|
|
||||||
zfs_btree_index_t *cookie = NULL;
|
zfs_btree_index_t *cookie = NULL;
|
||||||
while ((e = zfs_btree_destroy_nodes(&sv->sv_pair, &cookie)) != NULL) {
|
while ((e = zfs_btree_destroy_nodes(&sv->sv_pair, &cookie)) != NULL) {
|
||||||
snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), e, B_TRUE);
|
char blkbuf[BP_SPRINTF_LEN];
|
||||||
(void) printf("\tERROR: Unmatched FREE: %s\n", blkbuf);
|
snprintf_blkptr_compact(blkbuf, sizeof (blkbuf),
|
||||||
|
&e->svbr_blk, B_TRUE);
|
||||||
|
(void) printf("\tERROR: %d unmatched FREE(s): %s\n",
|
||||||
|
e->svbr_refcnt, blkbuf);
|
||||||
}
|
}
|
||||||
zfs_btree_destroy(&sv->sv_pair);
|
zfs_btree_destroy(&sv->sv_pair);
|
||||||
|
|
||||||
|
@ -613,10 +636,14 @@ mv_populate_livelist_allocs(metaslab_verify_t *mv, sublivelist_verify_t *sv)
|
||||||
/*
|
/*
|
||||||
* [Livelist Check]
|
* [Livelist Check]
|
||||||
* Iterate through all the sublivelists and:
|
* Iterate through all the sublivelists and:
|
||||||
* - report leftover frees
|
* - report leftover frees (**)
|
||||||
* - report double ALLOCs/FREEs
|
|
||||||
* - record leftover ALLOCs together with their TXG [see Cross Check]
|
* - record leftover ALLOCs together with their TXG [see Cross Check]
|
||||||
*
|
*
|
||||||
|
* (**) Note: Double ALLOCs are valid in datasets that have dedup
|
||||||
|
* enabled. Similarly double FREEs are allowed as well but
|
||||||
|
* only if they pair up with a corresponding ALLOC entry once
|
||||||
|
* we our done with our sublivelist iteration.
|
||||||
|
*
|
||||||
* [Spacemap Check]
|
* [Spacemap Check]
|
||||||
* for each metaslab:
|
* for each metaslab:
|
||||||
* - iterate over spacemap and then the metaslab's entries in the
|
* - iterate over spacemap and then the metaslab's entries in the
|
||||||
|
@ -2184,7 +2211,8 @@ snprintf_zstd_header(spa_t *spa, char *blkbuf, size_t buflen,
|
||||||
(void) snprintf(blkbuf + strlen(blkbuf),
|
(void) snprintf(blkbuf + strlen(blkbuf),
|
||||||
buflen - strlen(blkbuf),
|
buflen - strlen(blkbuf),
|
||||||
" ZSTD:size=%u:version=%u:level=%u:EMBEDDED",
|
" ZSTD:size=%u:version=%u:level=%u:EMBEDDED",
|
||||||
zstd_hdr.c_len, zstd_hdr.version, zstd_hdr.level);
|
zstd_hdr.c_len, zfs_get_hdrversion(&zstd_hdr),
|
||||||
|
zfs_get_hdrlevel(&zstd_hdr));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2208,7 +2236,8 @@ snprintf_zstd_header(spa_t *spa, char *blkbuf, size_t buflen,
|
||||||
(void) snprintf(blkbuf + strlen(blkbuf),
|
(void) snprintf(blkbuf + strlen(blkbuf),
|
||||||
buflen - strlen(blkbuf),
|
buflen - strlen(blkbuf),
|
||||||
" ZSTD:size=%u:version=%u:level=%u:NORMAL",
|
" ZSTD:size=%u:version=%u:level=%u:NORMAL",
|
||||||
zstd_hdr.c_len, zstd_hdr.version, zstd_hdr.level);
|
zstd_hdr.c_len, zfs_get_hdrversion(&zstd_hdr),
|
||||||
|
zfs_get_hdrlevel(&zstd_hdr));
|
||||||
|
|
||||||
abd_return_buf_copy(pabd, buf, BP_GET_LSIZE(bp));
|
abd_return_buf_copy(pabd, buf, BP_GET_LSIZE(bp));
|
||||||
}
|
}
|
||||||
|
@ -4060,7 +4089,7 @@ cksum_record_compare(const void *x1, const void *x2)
|
||||||
const cksum_record_t *l = (cksum_record_t *)x1;
|
const cksum_record_t *l = (cksum_record_t *)x1;
|
||||||
const cksum_record_t *r = (cksum_record_t *)x2;
|
const cksum_record_t *r = (cksum_record_t *)x2;
|
||||||
int arraysize = ARRAY_SIZE(l->cksum.zc_word);
|
int arraysize = ARRAY_SIZE(l->cksum.zc_word);
|
||||||
int difference;
|
int difference = 0;
|
||||||
|
|
||||||
for (int i = 0; i < arraysize; i++) {
|
for (int i = 0; i < arraysize; i++) {
|
||||||
difference = TREE_CMP(l->cksum.zc_word[i], r->cksum.zc_word[i]);
|
difference = TREE_CMP(l->cksum.zc_word[i], r->cksum.zc_word[i]);
|
||||||
|
@ -4535,7 +4564,7 @@ dump_path_impl(objset_t *os, uint64_t obj, char *name)
|
||||||
case DMU_OT_DIRECTORY_CONTENTS:
|
case DMU_OT_DIRECTORY_CONTENTS:
|
||||||
if (s != NULL && *(s + 1) != '\0')
|
if (s != NULL && *(s + 1) != '\0')
|
||||||
return (dump_path_impl(os, child_obj, s + 1));
|
return (dump_path_impl(os, child_obj, s + 1));
|
||||||
/*FALLTHROUGH*/
|
fallthrough;
|
||||||
case DMU_OT_PLAIN_FILE_CONTENTS:
|
case DMU_OT_PLAIN_FILE_CONTENTS:
|
||||||
dump_object(os, child_obj, dump_opt['v'], &header, NULL, 0);
|
dump_object(os, child_obj, dump_opt['v'], &header, NULL, 0);
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -5840,7 +5869,8 @@ zdb_leak_init_prepare_indirect_vdevs(spa_t *spa, zdb_cb_t *zcb)
|
||||||
*/
|
*/
|
||||||
VERIFY0(vdev_metaslab_init(vd, 0));
|
VERIFY0(vdev_metaslab_init(vd, 0));
|
||||||
|
|
||||||
vdev_indirect_mapping_t *vim = vd->vdev_indirect_mapping;
|
vdev_indirect_mapping_t *vim __maybe_unused =
|
||||||
|
vd->vdev_indirect_mapping;
|
||||||
uint64_t vim_idx = 0;
|
uint64_t vim_idx = 0;
|
||||||
for (uint64_t m = 0; m < vd->vdev_ms_count; m++) {
|
for (uint64_t m = 0; m < vd->vdev_ms_count; m++) {
|
||||||
|
|
||||||
|
@ -6933,7 +6963,7 @@ verify_checkpoint_vdev_spacemaps(spa_t *checkpoint, spa_t *current)
|
||||||
for (uint64_t c = ckpoint_rvd->vdev_children;
|
for (uint64_t c = ckpoint_rvd->vdev_children;
|
||||||
c < current_rvd->vdev_children; c++) {
|
c < current_rvd->vdev_children; c++) {
|
||||||
vdev_t *current_vd = current_rvd->vdev_child[c];
|
vdev_t *current_vd = current_rvd->vdev_child[c];
|
||||||
ASSERT3P(current_vd->vdev_checkpoint_sm, ==, NULL);
|
VERIFY3P(current_vd->vdev_checkpoint_sm, ==, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,3 +47,5 @@ zed_LDADD += -lrt $(LIBUDEV_LIBS) $(LIBUUID_LIBS)
|
||||||
zed_LDFLAGS = -pthread
|
zed_LDFLAGS = -pthread
|
||||||
|
|
||||||
EXTRA_DIST = agents/README.md
|
EXTRA_DIST = agents/README.md
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# Turn off/on the VDEV's enclosure fault LEDs when the pool's state changes.
|
# Turn off/on vdevs' enclosure fault LEDs when their pool's state changes.
|
||||||
#
|
#
|
||||||
# Turn the VDEV's fault LED on if it becomes FAULTED, DEGRADED or UNAVAIL.
|
# Turn a vdev's fault LED on if it becomes FAULTED, DEGRADED or UNAVAIL.
|
||||||
# Turn the LED off when it's back ONLINE again.
|
# Turn its LED off when it's back ONLINE again.
|
||||||
#
|
#
|
||||||
# This script run in two basic modes:
|
# This script run in two basic modes:
|
||||||
#
|
#
|
||||||
# 1. If $ZEVENT_VDEV_ENC_SYSFS_PATH and $ZEVENT_VDEV_STATE_STR are set, then
|
# 1. If $ZEVENT_VDEV_ENC_SYSFS_PATH and $ZEVENT_VDEV_STATE_STR are set, then
|
||||||
# only set the LED for that particular VDEV. This is the case for statechange
|
# only set the LED for that particular vdev. This is the case for statechange
|
||||||
# events and some vdev_* events.
|
# events and some vdev_* events.
|
||||||
#
|
#
|
||||||
# 2. If those vars are not set, then check the state of all VDEVs in the pool
|
# 2. If those vars are not set, then check the state of all vdevs in the pool
|
||||||
# and set the LEDs accordingly. This is the case for pool_import events.
|
# and set the LEDs accordingly. This is the case for pool_import events.
|
||||||
#
|
#
|
||||||
# Note that this script requires that your enclosure be supported by the
|
# Note that this script requires that your enclosure be supported by the
|
||||||
# Linux SCSI enclosure services (ses) driver. The script will do nothing
|
# Linux SCSI Enclosure services (SES) driver. The script will do nothing
|
||||||
# if you have no enclosure, or if your enclosure isn't supported.
|
# if you have no enclosure, or if your enclosure isn't supported.
|
||||||
#
|
#
|
||||||
# Exit codes:
|
# Exit codes:
|
||||||
|
@ -29,7 +29,8 @@
|
||||||
[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
|
[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
|
||||||
. "${ZED_ZEDLET_DIR}/zed-functions.sh"
|
. "${ZED_ZEDLET_DIR}/zed-functions.sh"
|
||||||
|
|
||||||
if [ ! -d /sys/class/enclosure ] ; then
|
if [ ! -d /sys/class/enclosure ] && [ ! -d /sys/bus/pci/slots ] ; then
|
||||||
|
# No JBOD enclosure or NVMe slots
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -59,6 +60,10 @@ check_and_set_led()
|
||||||
file="$1"
|
file="$1"
|
||||||
val="$2"
|
val="$2"
|
||||||
|
|
||||||
|
if [ -z "$val" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -e "$file" ] ; then
|
if [ ! -e "$file" ] ; then
|
||||||
return 3
|
return 3
|
||||||
fi
|
fi
|
||||||
|
@ -66,11 +71,11 @@ check_and_set_led()
|
||||||
# If another process is accessing the LED when we attempt to update it,
|
# If another process is accessing the LED when we attempt to update it,
|
||||||
# the update will be lost so retry until the LED actually changes or we
|
# the update will be lost so retry until the LED actually changes or we
|
||||||
# timeout.
|
# timeout.
|
||||||
for _ in $(seq 1 5); do
|
for _ in 1 2 3 4 5; do
|
||||||
# We want to check the current state first, since writing to the
|
# We want to check the current state first, since writing to the
|
||||||
# 'fault' entry always causes a SES command, even if the
|
# 'fault' entry always causes a SES command, even if the
|
||||||
# current state is already what you want.
|
# current state is already what you want.
|
||||||
current=$(cat "${file}")
|
read -r current < "${file}"
|
||||||
|
|
||||||
# On some enclosures if you write 1 to fault, and read it back,
|
# On some enclosures if you write 1 to fault, and read it back,
|
||||||
# it will return 2. Treat all non-zero values as 1 for
|
# it will return 2. Treat all non-zero values as 1 for
|
||||||
|
@ -88,24 +93,81 @@ check_and_set_led()
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
state_to_val()
|
# Fault LEDs for JBODs and NVMe drives are handled a little differently.
|
||||||
|
#
|
||||||
|
# On JBODs the fault LED is called 'fault' and on a path like this:
|
||||||
|
#
|
||||||
|
# /sys/class/enclosure/0:0:1:0/SLOT 10/fault
|
||||||
|
#
|
||||||
|
# On NVMe it's called 'attention' and on a path like this:
|
||||||
|
#
|
||||||
|
# /sys/bus/pci/slot/0/attention
|
||||||
|
#
|
||||||
|
# This function returns the full path to the fault LED file for a given
|
||||||
|
# enclosure/slot directory.
|
||||||
|
#
|
||||||
|
path_to_led()
|
||||||
{
|
{
|
||||||
state="$1"
|
dir=$1
|
||||||
if [ "$state" = "FAULTED" ] || [ "$state" = "DEGRADED" ] || \
|
if [ -f "$dir/fault" ] ; then
|
||||||
[ "$state" = "UNAVAIL" ] ; then
|
echo "$dir/fault"
|
||||||
echo 1
|
elif [ -f "$dir/attention" ] ; then
|
||||||
elif [ "$state" = "ONLINE" ] ; then
|
echo "$dir/attention"
|
||||||
echo 0
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# process_pool ([pool])
|
state_to_val()
|
||||||
|
{
|
||||||
|
state="$1"
|
||||||
|
case "$state" in
|
||||||
|
FAULTED|DEGRADED|UNAVAIL)
|
||||||
|
echo 1
|
||||||
|
;;
|
||||||
|
ONLINE)
|
||||||
|
echo 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# Iterate through a pool (or pools) and set the VDEV's enclosure slot LEDs to
|
# Given a nvme name like 'nvme0n1', pass back its slot directory
|
||||||
# the VDEV's state.
|
# like "/sys/bus/pci/slots/0"
|
||||||
|
#
|
||||||
|
nvme_dev_to_slot()
|
||||||
|
{
|
||||||
|
dev="$1"
|
||||||
|
|
||||||
|
# Get the address "0000:01:00.0"
|
||||||
|
address=$(cat "/sys/class/block/$dev/device/address")
|
||||||
|
|
||||||
|
# For each /sys/bus/pci/slots subdir that is an actual number
|
||||||
|
# (rather than weird directories like "1-3/").
|
||||||
|
# shellcheck disable=SC2010
|
||||||
|
for i in $(ls /sys/bus/pci/slots/ | grep -E "^[0-9]+$") ; do
|
||||||
|
this_address=$(cat "/sys/bus/pci/slots/$i/address")
|
||||||
|
|
||||||
|
# The format of address is a little different between
|
||||||
|
# /sys/class/block/$dev/device/address and
|
||||||
|
# /sys/bus/pci/slots/
|
||||||
|
#
|
||||||
|
# address= "0000:01:00.0"
|
||||||
|
# this_address = "0000:01:00"
|
||||||
|
#
|
||||||
|
if echo "$address" | grep -Eq ^"$this_address" ; then
|
||||||
|
echo "/sys/bus/pci/slots/$i"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# process_pool (pool)
|
||||||
|
#
|
||||||
|
# Iterate through a pool and set the vdevs' enclosure slot LEDs to
|
||||||
|
# those vdevs' state.
|
||||||
#
|
#
|
||||||
# Arguments
|
# Arguments
|
||||||
# pool: Optional pool name. If not specified, iterate though all pools.
|
# pool: Pool name.
|
||||||
#
|
#
|
||||||
# Return
|
# Return
|
||||||
# 0 on success, 3 on missing sysfs path
|
# 0 on success, 3 on missing sysfs path
|
||||||
|
@ -113,19 +175,27 @@ state_to_val()
|
||||||
process_pool()
|
process_pool()
|
||||||
{
|
{
|
||||||
pool="$1"
|
pool="$1"
|
||||||
|
|
||||||
|
# The output will be the vdevs only (from "grep '/dev/'"):
|
||||||
|
#
|
||||||
|
# U45 ONLINE 0 0 0 /dev/sdk 0
|
||||||
|
# U46 ONLINE 0 0 0 /dev/sdm 0
|
||||||
|
# U47 ONLINE 0 0 0 /dev/sdn 0
|
||||||
|
# U50 ONLINE 0 0 0 /dev/sdbn 0
|
||||||
|
#
|
||||||
|
ZPOOL_SCRIPTS_AS_ROOT=1 $ZPOOL status -c upath,fault_led "$pool" | grep '/dev/' | (
|
||||||
rc=0
|
rc=0
|
||||||
|
while read -r vdev state _ _ _ therest; do
|
||||||
# Lookup all the current LED values and paths in parallel
|
|
||||||
#shellcheck disable=SC2016
|
|
||||||
cmd='echo led_token=$(cat "$VDEV_ENC_SYSFS_PATH/fault"),"$VDEV_ENC_SYSFS_PATH",'
|
|
||||||
out=$($ZPOOL status -vc "$cmd" "$pool" | grep 'led_token=')
|
|
||||||
|
|
||||||
#shellcheck disable=SC2034
|
|
||||||
echo "$out" | while read -r vdev state read write chksum therest; do
|
|
||||||
# Read out current LED value and path
|
# Read out current LED value and path
|
||||||
tmp=$(echo "$therest" | sed 's/^.*led_token=//g')
|
# Get dev name (like 'sda')
|
||||||
vdev_enc_sysfs_path=$(echo "$tmp" | awk -F ',' '{print $2}')
|
dev=$(basename "$(echo "$therest" | awk '{print $(NF-1)}')")
|
||||||
current_val=$(echo "$tmp" | awk -F ',' '{print $1}')
|
vdev_enc_sysfs_path=$(realpath "/sys/class/block/$dev/device/enclosure_device"*)
|
||||||
|
if [ ! -d "$vdev_enc_sysfs_path" ] ; then
|
||||||
|
# This is not a JBOD disk, but it could be a PCI NVMe drive
|
||||||
|
vdev_enc_sysfs_path=$(nvme_dev_to_slot "$dev")
|
||||||
|
fi
|
||||||
|
|
||||||
|
current_val=$(echo "$therest" | awk '{print $NF}')
|
||||||
|
|
||||||
if [ "$current_val" != "0" ] ; then
|
if [ "$current_val" != "0" ] ; then
|
||||||
current_val=1
|
current_val=1
|
||||||
|
@ -136,40 +206,33 @@ process_pool()
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -e "$vdev_enc_sysfs_path/fault" ] ; then
|
led_path=$(path_to_led "$vdev_enc_sysfs_path")
|
||||||
#shellcheck disable=SC2030
|
if [ ! -e "$led_path" ] ; then
|
||||||
rc=1
|
rc=3
|
||||||
zed_log_msg "vdev $vdev '$file/fault' doesn't exist"
|
zed_log_msg "vdev $vdev '$led_path' doesn't exist"
|
||||||
continue;
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
val=$(state_to_val "$state")
|
val=$(state_to_val "$state")
|
||||||
|
|
||||||
if [ "$current_val" = "$val" ] ; then
|
if [ "$current_val" = "$val" ] ; then
|
||||||
# LED is already set correctly
|
# LED is already set correctly
|
||||||
continue;
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! check_and_set_led "$vdev_enc_sysfs_path/fault" "$val"; then
|
if ! check_and_set_led "$led_path" "$val"; then
|
||||||
rc=1
|
rc=3
|
||||||
fi
|
fi
|
||||||
|
|
||||||
done
|
done
|
||||||
|
exit "$rc"; )
|
||||||
#shellcheck disable=SC2031
|
|
||||||
if [ "$rc" = "0" ] ; then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
# We didn't see a sysfs entry that we wanted to set
|
|
||||||
return 3
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ -n "$ZEVENT_VDEV_ENC_SYSFS_PATH" ] && [ -n "$ZEVENT_VDEV_STATE_STR" ] ; then
|
if [ -n "$ZEVENT_VDEV_ENC_SYSFS_PATH" ] && [ -n "$ZEVENT_VDEV_STATE_STR" ] ; then
|
||||||
# Got a statechange for an individual VDEV
|
# Got a statechange for an individual vdev
|
||||||
val=$(state_to_val "$ZEVENT_VDEV_STATE_STR")
|
val=$(state_to_val "$ZEVENT_VDEV_STATE_STR")
|
||||||
vdev=$(basename "$ZEVENT_VDEV_PATH")
|
vdev=$(basename "$ZEVENT_VDEV_PATH")
|
||||||
check_and_set_led "$ZEVENT_VDEV_ENC_SYSFS_PATH/fault" "$val"
|
ledpath=$(path_to_led "$ZEVENT_VDEV_ENC_SYSFS_PATH")
|
||||||
|
check_and_set_led "$ledpath" "$val"
|
||||||
else
|
else
|
||||||
# Process the entire pool
|
# Process the entire pool
|
||||||
poolname=$(zed_guid_to_pool "$ZEVENT_POOL_GUID")
|
poolname=$(zed_guid_to_pool "$ZEVENT_POOL_GUID")
|
||||||
|
|
|
@ -89,8 +89,8 @@
|
||||||
|
|
||||||
##
|
##
|
||||||
# Turn on/off enclosure LEDs when drives get DEGRADED/FAULTED. This works for
|
# Turn on/off enclosure LEDs when drives get DEGRADED/FAULTED. This works for
|
||||||
# device mapper and multipath devices as well. Your enclosure must be
|
# device mapper and multipath devices as well. This works with JBOD enclosures
|
||||||
# supported by the Linux SES driver for this to work.
|
# and NVMe PCI drives (assuming they're supported by Linux in sysfs).
|
||||||
#
|
#
|
||||||
ZED_USE_ENCLOSURE_LEDS=1
|
ZED_USE_ENCLOSURE_LEDS=1
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,7 @@ _zed_exec_fork_child(uint64_t eid, const char *dir, const char *prog,
|
||||||
zed_log_msg(LOG_WARNING, "Killing hung \"%s\" pid=%d",
|
zed_log_msg(LOG_WARNING, "Killing hung \"%s\" pid=%d",
|
||||||
prog, pid);
|
prog, pid);
|
||||||
(void) kill(pid, SIGKILL);
|
(void) kill(pid, SIGKILL);
|
||||||
|
(void) waitpid(pid, &status, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,11 @@
|
||||||
* You may not use this file except in compliance with the license.
|
* You may not use this file except in compliance with the license.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/resource.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -160,6 +160,13 @@ zed_file_is_locked(int fd)
|
||||||
return (lock.l_pid);
|
return (lock.l_pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if __APPLE__
|
||||||
|
#define PROC_SELF_FD "/dev/fd"
|
||||||
|
#else /* Linux-compatible layout */
|
||||||
|
#define PROC_SELF_FD "/proc/self/fd"
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close all open file descriptors greater than or equal to [lowfd].
|
* Close all open file descriptors greater than or equal to [lowfd].
|
||||||
* Any errors encountered while closing file descriptors are ignored.
|
* Any errors encountered while closing file descriptors are ignored.
|
||||||
|
@ -167,20 +174,21 @@ zed_file_is_locked(int fd)
|
||||||
void
|
void
|
||||||
zed_file_close_from(int lowfd)
|
zed_file_close_from(int lowfd)
|
||||||
{
|
{
|
||||||
const int maxfd_def = 256;
|
int errno_bak = errno;
|
||||||
int errno_bak;
|
int maxfd = 0;
|
||||||
struct rlimit rl;
|
|
||||||
int maxfd;
|
|
||||||
int fd;
|
int fd;
|
||||||
|
DIR *fddir;
|
||||||
|
struct dirent *fdent;
|
||||||
|
|
||||||
errno_bak = errno;
|
if ((fddir = opendir(PROC_SELF_FD)) != NULL) {
|
||||||
|
while ((fdent = readdir(fddir)) != NULL) {
|
||||||
if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
|
fd = atoi(fdent->d_name);
|
||||||
maxfd = maxfd_def;
|
if (fd > maxfd && fd != dirfd(fddir))
|
||||||
} else if (rl.rlim_max == RLIM_INFINITY) {
|
maxfd = fd;
|
||||||
maxfd = maxfd_def;
|
}
|
||||||
|
(void) closedir(fddir);
|
||||||
} else {
|
} else {
|
||||||
maxfd = rl.rlim_max;
|
maxfd = sysconf(_SC_OPEN_MAX);
|
||||||
}
|
}
|
||||||
for (fd = lowfd; fd < maxfd; fd++)
|
for (fd = lowfd; fd < maxfd; fd++)
|
||||||
(void) close(fd);
|
(void) close(fd);
|
||||||
|
|
|
@ -21,3 +21,5 @@ zfs_LDADD += $(LTLIBINTL)
|
||||||
if BUILD_FREEBSD
|
if BUILD_FREEBSD
|
||||||
zfs_LDADD += -lgeom -ljail
|
zfs_LDADD += -lgeom -ljail
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|
|
@ -730,6 +730,32 @@ finish_progress(char *done)
|
||||||
pt_header = NULL;
|
pt_header = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function checks if the passed fd refers to /dev/null or /dev/zero */
|
||||||
|
#ifdef __linux__
|
||||||
|
static boolean_t
|
||||||
|
is_dev_nullzero(int fd)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
fstat(fd, &st);
|
||||||
|
return (major(st.st_rdev) == 1 && (minor(st.st_rdev) == 3 /* null */ ||
|
||||||
|
minor(st.st_rdev) == 5 /* zero */));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
note_dev_error(int err, int fd)
|
||||||
|
{
|
||||||
|
#ifdef __linux__
|
||||||
|
if (err == EINVAL && is_dev_nullzero(fd)) {
|
||||||
|
(void) fprintf(stderr,
|
||||||
|
gettext("Error: Writing directly to /dev/{null,zero} files"
|
||||||
|
" on certain kernels is not currently implemented.\n"
|
||||||
|
"(As a workaround, "
|
||||||
|
"try \"zfs send [...] | cat > /dev/null\")\n"));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
zfs_mount_and_share(libzfs_handle_t *hdl, const char *dataset, zfs_type_t type)
|
zfs_mount_and_share(libzfs_handle_t *hdl, const char *dataset, zfs_type_t type)
|
||||||
{
|
{
|
||||||
|
@ -4448,11 +4474,16 @@ zfs_do_send(int argc, char **argv)
|
||||||
|
|
||||||
err = zfs_send_saved(zhp, &flags, STDOUT_FILENO,
|
err = zfs_send_saved(zhp, &flags, STDOUT_FILENO,
|
||||||
resume_token);
|
resume_token);
|
||||||
|
if (err != 0)
|
||||||
|
note_dev_error(errno, STDOUT_FILENO);
|
||||||
zfs_close(zhp);
|
zfs_close(zhp);
|
||||||
return (err != 0);
|
return (err != 0);
|
||||||
} else if (resume_token != NULL) {
|
} else if (resume_token != NULL) {
|
||||||
return (zfs_send_resume(g_zfs, &flags, STDOUT_FILENO,
|
err = zfs_send_resume(g_zfs, &flags, STDOUT_FILENO,
|
||||||
resume_token));
|
resume_token);
|
||||||
|
if (err != 0)
|
||||||
|
note_dev_error(errno, STDOUT_FILENO);
|
||||||
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -4496,6 +4527,8 @@ zfs_do_send(int argc, char **argv)
|
||||||
err = zfs_send_one(zhp, fromname, STDOUT_FILENO, &flags,
|
err = zfs_send_one(zhp, fromname, STDOUT_FILENO, &flags,
|
||||||
redactbook);
|
redactbook);
|
||||||
zfs_close(zhp);
|
zfs_close(zhp);
|
||||||
|
if (err != 0)
|
||||||
|
note_dev_error(errno, STDOUT_FILENO);
|
||||||
return (err != 0);
|
return (err != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4572,6 +4605,7 @@ zfs_do_send(int argc, char **argv)
|
||||||
nvlist_free(dbgnv);
|
nvlist_free(dbgnv);
|
||||||
}
|
}
|
||||||
zfs_close(zhp);
|
zfs_close(zhp);
|
||||||
|
note_dev_error(errno, STDOUT_FILENO);
|
||||||
|
|
||||||
return (err != 0);
|
return (err != 0);
|
||||||
}
|
}
|
||||||
|
@ -6790,9 +6824,6 @@ report_mount_progress(int current, int total)
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
char info[32];
|
char info[32];
|
||||||
|
|
||||||
/* report 1..n instead of 0..n-1 */
|
|
||||||
++current;
|
|
||||||
|
|
||||||
/* display header if we're here for the first time */
|
/* display header if we're here for the first time */
|
||||||
if (current == 1) {
|
if (current == 1) {
|
||||||
set_progress_header(gettext("Mounting ZFS filesystems"));
|
set_progress_header(gettext("Mounting ZFS filesystems"));
|
||||||
|
@ -7313,6 +7344,7 @@ unshare_unmount(int op, int argc, char **argv)
|
||||||
if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) ==
|
if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) ==
|
||||||
ZFS_CANMOUNT_NOAUTO)
|
ZFS_CANMOUNT_NOAUTO)
|
||||||
continue;
|
continue;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,3 +7,5 @@ zfs_ids_to_path_SOURCES = \
|
||||||
|
|
||||||
zfs_ids_to_path_LDADD = \
|
zfs_ids_to_path_LDADD = \
|
||||||
$(abs_top_builddir)/lib/libzfs/libzfs.la
|
$(abs_top_builddir)/lib/libzfs/libzfs.la
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|
|
@ -3,3 +3,5 @@ include $(top_srcdir)/config/Rules.am
|
||||||
sbin_PROGRAMS = zgenhostid
|
sbin_PROGRAMS = zgenhostid
|
||||||
|
|
||||||
zgenhostid_SOURCES = zgenhostid.c
|
zgenhostid_SOURCES = zgenhostid.c
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|
|
@ -12,3 +12,5 @@ zhack_LDADD = \
|
||||||
$(abs_top_builddir)/lib/libzpool/libzpool.la \
|
$(abs_top_builddir)/lib/libzpool/libzpool.la \
|
||||||
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
||||||
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
|
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|
|
@ -11,3 +11,5 @@ zinject_LDADD = \
|
||||||
$(abs_top_builddir)/lib/libzfs/libzfs.la \
|
$(abs_top_builddir)/lib/libzfs/libzfs.la \
|
||||||
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
||||||
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
|
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|
|
@ -25,7 +25,8 @@ zpool_LDADD = \
|
||||||
$(abs_top_builddir)/lib/libzfs/libzfs.la \
|
$(abs_top_builddir)/lib/libzfs/libzfs.la \
|
||||||
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
||||||
$(abs_top_builddir)/lib/libnvpair/libnvpair.la \
|
$(abs_top_builddir)/lib/libnvpair/libnvpair.la \
|
||||||
$(abs_top_builddir)/lib/libuutil/libuutil.la
|
$(abs_top_builddir)/lib/libuutil/libuutil.la \
|
||||||
|
$(abs_top_builddir)/lib/libzutil/libzutil.la
|
||||||
|
|
||||||
zpool_LDADD += $(LTLIBINTL)
|
zpool_LDADD += $(LTLIBINTL)
|
||||||
|
|
||||||
|
@ -34,6 +35,8 @@ zpool_LDADD += -lgeom
|
||||||
endif
|
endif
|
||||||
zpool_LDADD += -lm $(LIBBLKID_LIBS) $(LIBUUID_LIBS)
|
zpool_LDADD += -lm $(LIBBLKID_LIBS) $(LIBUUID_LIBS)
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|
||||||
zpoolconfdir = $(sysconfdir)/zfs/zpool.d
|
zpoolconfdir = $(sysconfdir)/zfs/zpool.d
|
||||||
zpoolexecdir = $(zfsexecdir)/zpool.d
|
zpoolexecdir = $(zfsexecdir)/zpool.d
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,13 @@ for i in $scripts ; do
|
||||||
val=$(ls "$VDEV_ENC_SYSFS_PATH/../device/scsi_generic" 2>/dev/null)
|
val=$(ls "$VDEV_ENC_SYSFS_PATH/../device/scsi_generic" 2>/dev/null)
|
||||||
;;
|
;;
|
||||||
fault_led)
|
fault_led)
|
||||||
|
# JBODs fault LED is called 'fault', NVMe fault LED is called
|
||||||
|
# 'attention'.
|
||||||
|
if [ -f "$VDEV_ENC_SYSFS_PATH/fault" ] ; then
|
||||||
val=$(cat "$VDEV_ENC_SYSFS_PATH/fault" 2>/dev/null)
|
val=$(cat "$VDEV_ENC_SYSFS_PATH/fault" 2>/dev/null)
|
||||||
|
elif [ -f "$VDEV_ENC_SYSFS_PATH/attention" ] ; then
|
||||||
|
val=$(cat "$VDEV_ENC_SYSFS_PATH/attention" 2>/dev/null)
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
locate_led)
|
locate_led)
|
||||||
val=$(cat "$VDEV_ENC_SYSFS_PATH/locate" 2>/dev/null)
|
val=$(cat "$VDEV_ENC_SYSFS_PATH/locate" 2>/dev/null)
|
||||||
|
|
|
@ -264,51 +264,6 @@ for_each_pool(int argc, char **argv, boolean_t unavail,
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
for_each_vdev_cb(zpool_handle_t *zhp, nvlist_t *nv, pool_vdev_iter_f func,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
nvlist_t **child;
|
|
||||||
uint_t c, children;
|
|
||||||
int ret = 0;
|
|
||||||
int i;
|
|
||||||
char *type;
|
|
||||||
|
|
||||||
const char *list[] = {
|
|
||||||
ZPOOL_CONFIG_SPARES,
|
|
||||||
ZPOOL_CONFIG_L2CACHE,
|
|
||||||
ZPOOL_CONFIG_CHILDREN
|
|
||||||
};
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(list); i++) {
|
|
||||||
if (nvlist_lookup_nvlist_array(nv, list[i], &child,
|
|
||||||
&children) == 0) {
|
|
||||||
for (c = 0; c < children; c++) {
|
|
||||||
uint64_t ishole = 0;
|
|
||||||
|
|
||||||
(void) nvlist_lookup_uint64(child[c],
|
|
||||||
ZPOOL_CONFIG_IS_HOLE, &ishole);
|
|
||||||
|
|
||||||
if (ishole)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ret |= for_each_vdev_cb(zhp, child[c], func,
|
|
||||||
data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
|
|
||||||
return (ret);
|
|
||||||
|
|
||||||
/* Don't run our function on root vdevs */
|
|
||||||
if (strcmp(type, VDEV_TYPE_ROOT) != 0) {
|
|
||||||
ret |= func(zhp, nv, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the equivalent of for_each_pool() for vdevs. It iterates thorough
|
* This is the equivalent of for_each_pool() for vdevs. It iterates thorough
|
||||||
* all vdevs in the pool, ignoring root vdevs and holes, calling func() on
|
* all vdevs in the pool, ignoring root vdevs and holes, calling func() on
|
||||||
|
@ -327,7 +282,7 @@ for_each_vdev(zpool_handle_t *zhp, pool_vdev_iter_f func, void *data)
|
||||||
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
|
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
|
||||||
&nvroot) == 0);
|
&nvroot) == 0);
|
||||||
}
|
}
|
||||||
return (for_each_vdev_cb(zhp, nvroot, func, data));
|
return (for_each_vdev_cb((void *) zhp, nvroot, func, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -598,7 +553,7 @@ vdev_run_cmd_thread(void *cb_cmd_data)
|
||||||
|
|
||||||
/* For each vdev in the pool run a command */
|
/* For each vdev in the pool run a command */
|
||||||
static int
|
static int
|
||||||
for_each_vdev_run_cb(zpool_handle_t *zhp, nvlist_t *nv, void *cb_vcdl)
|
for_each_vdev_run_cb(void *zhp_data, nvlist_t *nv, void *cb_vcdl)
|
||||||
{
|
{
|
||||||
vdev_cmd_data_list_t *vcdl = cb_vcdl;
|
vdev_cmd_data_list_t *vcdl = cb_vcdl;
|
||||||
vdev_cmd_data_t *data;
|
vdev_cmd_data_t *data;
|
||||||
|
@ -606,6 +561,7 @@ for_each_vdev_run_cb(zpool_handle_t *zhp, nvlist_t *nv, void *cb_vcdl)
|
||||||
char *vname = NULL;
|
char *vname = NULL;
|
||||||
char *vdev_enc_sysfs_path = NULL;
|
char *vdev_enc_sysfs_path = NULL;
|
||||||
int i, match = 0;
|
int i, match = 0;
|
||||||
|
zpool_handle_t *zhp = zhp_data;
|
||||||
|
|
||||||
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) != 0)
|
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) != 0)
|
||||||
return (1);
|
return (1);
|
||||||
|
|
|
@ -2586,8 +2586,8 @@ print_class_vdevs(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t *nv,
|
||||||
/*
|
/*
|
||||||
* Display the status for the given pool.
|
* Display the status for the given pool.
|
||||||
*/
|
*/
|
||||||
static void
|
static int
|
||||||
show_import(nvlist_t *config)
|
show_import(nvlist_t *config, boolean_t report_error)
|
||||||
{
|
{
|
||||||
uint64_t pool_state;
|
uint64_t pool_state;
|
||||||
vdev_stat_t *vs;
|
vdev_stat_t *vs;
|
||||||
|
@ -2619,6 +2619,13 @@ show_import(nvlist_t *config)
|
||||||
|
|
||||||
reason = zpool_import_status(config, &msgid, &errata);
|
reason = zpool_import_status(config, &msgid, &errata);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we're importing using a cachefile, then we won't report any
|
||||||
|
* errors unless we are in the scan phase of the import.
|
||||||
|
*/
|
||||||
|
if (reason != ZPOOL_STATUS_OK && !report_error)
|
||||||
|
return (reason);
|
||||||
|
|
||||||
(void) printf(gettext(" pool: %s\n"), name);
|
(void) printf(gettext(" pool: %s\n"), name);
|
||||||
(void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
|
(void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
|
||||||
(void) printf(gettext(" state: %s"), health);
|
(void) printf(gettext(" state: %s"), health);
|
||||||
|
@ -2933,6 +2940,7 @@ show_import(nvlist_t *config)
|
||||||
"be part of this pool, though their\n\texact "
|
"be part of this pool, though their\n\texact "
|
||||||
"configuration cannot be determined.\n"));
|
"configuration cannot be determined.\n"));
|
||||||
}
|
}
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean_t
|
static boolean_t
|
||||||
|
@ -3071,6 +3079,121 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
|
||||||
|
char *orig_name, char *new_name,
|
||||||
|
boolean_t do_destroyed, boolean_t pool_specified, boolean_t do_all,
|
||||||
|
importargs_t *import)
|
||||||
|
{
|
||||||
|
nvlist_t *config = NULL;
|
||||||
|
nvlist_t *found_config = NULL;
|
||||||
|
uint64_t pool_state;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* At this point we have a list of import candidate configs. Even if
|
||||||
|
* we were searching by pool name or guid, we still need to
|
||||||
|
* post-process the list to deal with pool state and possible
|
||||||
|
* duplicate names.
|
||||||
|
*/
|
||||||
|
int err = 0;
|
||||||
|
nvpair_t *elem = NULL;
|
||||||
|
boolean_t first = B_TRUE;
|
||||||
|
while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
|
||||||
|
|
||||||
|
verify(nvpair_value_nvlist(elem, &config) == 0);
|
||||||
|
|
||||||
|
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
|
||||||
|
&pool_state) == 0);
|
||||||
|
if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
|
||||||
|
continue;
|
||||||
|
if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
verify(nvlist_add_nvlist(config, ZPOOL_LOAD_POLICY,
|
||||||
|
import->policy) == 0);
|
||||||
|
|
||||||
|
if (!pool_specified) {
|
||||||
|
if (first)
|
||||||
|
first = B_FALSE;
|
||||||
|
else if (!do_all)
|
||||||
|
(void) printf("\n");
|
||||||
|
|
||||||
|
if (do_all) {
|
||||||
|
err |= do_import(config, NULL, mntopts,
|
||||||
|
props, flags);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* If we're importing from cachefile, then
|
||||||
|
* we don't want to report errors until we
|
||||||
|
* are in the scan phase of the import. If
|
||||||
|
* we get an error, then we return that error
|
||||||
|
* to invoke the scan phase.
|
||||||
|
*/
|
||||||
|
if (import->cachefile && !import->scan)
|
||||||
|
err = show_import(config, B_FALSE);
|
||||||
|
else
|
||||||
|
(void) show_import(config, B_TRUE);
|
||||||
|
}
|
||||||
|
} else if (import->poolname != NULL) {
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are searching for a pool based on name.
|
||||||
|
*/
|
||||||
|
verify(nvlist_lookup_string(config,
|
||||||
|
ZPOOL_CONFIG_POOL_NAME, &name) == 0);
|
||||||
|
|
||||||
|
if (strcmp(name, import->poolname) == 0) {
|
||||||
|
if (found_config != NULL) {
|
||||||
|
(void) fprintf(stderr, gettext(
|
||||||
|
"cannot import '%s': more than "
|
||||||
|
"one matching pool\n"),
|
||||||
|
import->poolname);
|
||||||
|
(void) fprintf(stderr, gettext(
|
||||||
|
"import by numeric ID instead\n"));
|
||||||
|
err = B_TRUE;
|
||||||
|
}
|
||||||
|
found_config = config;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uint64_t guid;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Search for a pool by guid.
|
||||||
|
*/
|
||||||
|
verify(nvlist_lookup_uint64(config,
|
||||||
|
ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
|
||||||
|
|
||||||
|
if (guid == import->guid)
|
||||||
|
found_config = config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we were searching for a specific pool, verify that we found a
|
||||||
|
* pool, and then do the import.
|
||||||
|
*/
|
||||||
|
if (pool_specified && err == 0) {
|
||||||
|
if (found_config == NULL) {
|
||||||
|
(void) fprintf(stderr, gettext("cannot import '%s': "
|
||||||
|
"no such pool available\n"), orig_name);
|
||||||
|
err = B_TRUE;
|
||||||
|
} else {
|
||||||
|
err |= do_import(found_config, new_name,
|
||||||
|
mntopts, props, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we were just looking for pools, report an error if none were
|
||||||
|
* found.
|
||||||
|
*/
|
||||||
|
if (!pool_specified && first)
|
||||||
|
(void) fprintf(stderr,
|
||||||
|
gettext("no pools available to import\n"));
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct target_exists_args {
|
typedef struct target_exists_args {
|
||||||
const char *poolname;
|
const char *poolname;
|
||||||
uint64_t poolguid;
|
uint64_t poolguid;
|
||||||
|
@ -3198,12 +3321,15 @@ zpool_do_checkpoint(int argc, char **argv)
|
||||||
/*
|
/*
|
||||||
* zpool import [-d dir] [-D]
|
* zpool import [-d dir] [-D]
|
||||||
* import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l]
|
* import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l]
|
||||||
* [-d dir | -c cachefile] [-f] -a
|
* [-d dir | -c cachefile | -s] [-f] -a
|
||||||
* import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l]
|
* import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l]
|
||||||
* [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool]
|
* [-d dir | -c cachefile | -s] [-f] [-n] [-F] <pool | id>
|
||||||
|
* [newpool]
|
||||||
*
|
*
|
||||||
* -c Read pool information from a cachefile instead of searching
|
* -c Read pool information from a cachefile instead of searching
|
||||||
* devices.
|
* devices. If importing from a cachefile config fails, then
|
||||||
|
* fallback to searching for devices only in the directories that
|
||||||
|
* exist in the cachefile.
|
||||||
*
|
*
|
||||||
* -d Scan in a specific directory, other than /dev/. More than
|
* -d Scan in a specific directory, other than /dev/. More than
|
||||||
* one directory can be specified using multiple '-d' options.
|
* one directory can be specified using multiple '-d' options.
|
||||||
|
@ -3259,15 +3385,11 @@ zpool_do_import(int argc, char **argv)
|
||||||
boolean_t do_all = B_FALSE;
|
boolean_t do_all = B_FALSE;
|
||||||
boolean_t do_destroyed = B_FALSE;
|
boolean_t do_destroyed = B_FALSE;
|
||||||
char *mntopts = NULL;
|
char *mntopts = NULL;
|
||||||
nvpair_t *elem;
|
|
||||||
nvlist_t *config;
|
|
||||||
uint64_t searchguid = 0;
|
uint64_t searchguid = 0;
|
||||||
char *searchname = NULL;
|
char *searchname = NULL;
|
||||||
char *propval;
|
char *propval;
|
||||||
nvlist_t *found_config;
|
|
||||||
nvlist_t *policy = NULL;
|
nvlist_t *policy = NULL;
|
||||||
nvlist_t *props = NULL;
|
nvlist_t *props = NULL;
|
||||||
boolean_t first;
|
|
||||||
int flags = ZFS_IMPORT_NORMAL;
|
int flags = ZFS_IMPORT_NORMAL;
|
||||||
uint32_t rewind_policy = ZPOOL_NO_REWIND;
|
uint32_t rewind_policy = ZPOOL_NO_REWIND;
|
||||||
boolean_t dryrun = B_FALSE;
|
boolean_t dryrun = B_FALSE;
|
||||||
|
@ -3275,7 +3397,8 @@ zpool_do_import(int argc, char **argv)
|
||||||
boolean_t xtreme_rewind = B_FALSE;
|
boolean_t xtreme_rewind = B_FALSE;
|
||||||
boolean_t do_scan = B_FALSE;
|
boolean_t do_scan = B_FALSE;
|
||||||
boolean_t pool_exists = B_FALSE;
|
boolean_t pool_exists = B_FALSE;
|
||||||
uint64_t pool_state, txg = -1ULL;
|
boolean_t pool_specified = B_FALSE;
|
||||||
|
uint64_t txg = -1ULL;
|
||||||
char *cachefile = NULL;
|
char *cachefile = NULL;
|
||||||
importargs_t idata = { 0 };
|
importargs_t idata = { 0 };
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
@ -3397,6 +3520,11 @@ zpool_do_import(int argc, char **argv)
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cachefile && do_scan) {
|
||||||
|
(void) fprintf(stderr, gettext("-c is incompatible with -s\n"));
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
if ((flags & ZFS_IMPORT_LOAD_KEYS) && (flags & ZFS_IMPORT_ONLY)) {
|
if ((flags & ZFS_IMPORT_LOAD_KEYS) && (flags & ZFS_IMPORT_ONLY)) {
|
||||||
(void) fprintf(stderr, gettext("-l is incompatible with -N\n"));
|
(void) fprintf(stderr, gettext("-l is incompatible with -N\n"));
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
|
@ -3477,7 +3605,7 @@ zpool_do_import(int argc, char **argv)
|
||||||
searchname = argv[0];
|
searchname = argv[0];
|
||||||
searchguid = 0;
|
searchguid = 0;
|
||||||
}
|
}
|
||||||
found_config = NULL;
|
pool_specified = B_TRUE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* User specified a name or guid. Ensure it's unique.
|
* User specified a name or guid. Ensure it's unique.
|
||||||
|
@ -3556,97 +3684,32 @@ zpool_do_import(int argc, char **argv)
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
err = import_pools(pools, props, mntopts, flags, argv[0],
|
||||||
* At this point we have a list of import candidate configs. Even if
|
argc == 1 ? NULL : argv[1], do_destroyed, pool_specified,
|
||||||
* we were searching by pool name or guid, we still need to
|
do_all, &idata);
|
||||||
* post-process the list to deal with pool state and possible
|
|
||||||
* duplicate names.
|
|
||||||
*/
|
|
||||||
err = 0;
|
|
||||||
elem = NULL;
|
|
||||||
first = B_TRUE;
|
|
||||||
while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
|
|
||||||
|
|
||||||
verify(nvpair_value_nvlist(elem, &config) == 0);
|
|
||||||
|
|
||||||
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
|
|
||||||
&pool_state) == 0);
|
|
||||||
if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
|
|
||||||
continue;
|
|
||||||
if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
verify(nvlist_add_nvlist(config, ZPOOL_LOAD_POLICY,
|
|
||||||
policy) == 0);
|
|
||||||
|
|
||||||
if (argc == 0) {
|
|
||||||
if (first)
|
|
||||||
first = B_FALSE;
|
|
||||||
else if (!do_all)
|
|
||||||
(void) printf("\n");
|
|
||||||
|
|
||||||
if (do_all) {
|
|
||||||
err |= do_import(config, NULL, mntopts,
|
|
||||||
props, flags);
|
|
||||||
} else {
|
|
||||||
show_import(config);
|
|
||||||
}
|
|
||||||
} else if (searchname != NULL) {
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We are searching for a pool based on name.
|
* If we're using the cachefile and we failed to import, then
|
||||||
|
* fallback to scanning the directory for pools that match
|
||||||
|
* those in the cachefile.
|
||||||
*/
|
*/
|
||||||
verify(nvlist_lookup_string(config,
|
if (err != 0 && cachefile != NULL) {
|
||||||
ZPOOL_CONFIG_POOL_NAME, &name) == 0);
|
(void) printf(gettext("cachefile import failed, retrying\n"));
|
||||||
|
|
||||||
if (strcmp(name, searchname) == 0) {
|
|
||||||
if (found_config != NULL) {
|
|
||||||
(void) fprintf(stderr, gettext(
|
|
||||||
"cannot import '%s': more than "
|
|
||||||
"one matching pool\n"), searchname);
|
|
||||||
(void) fprintf(stderr, gettext(
|
|
||||||
"import by numeric ID instead\n"));
|
|
||||||
err = B_TRUE;
|
|
||||||
}
|
|
||||||
found_config = config;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
uint64_t guid;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Search for a pool by guid.
|
* We use the scan flag to gather the directories that exist
|
||||||
|
* in the cachefile. If we need to fallback to searching for
|
||||||
|
* the pool config, we will only search devices in these
|
||||||
|
* directories.
|
||||||
*/
|
*/
|
||||||
verify(nvlist_lookup_uint64(config,
|
idata.scan = B_TRUE;
|
||||||
ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
|
nvlist_free(pools);
|
||||||
|
pools = zpool_search_import(g_zfs, &idata, &libzfs_config_ops);
|
||||||
|
|
||||||
if (guid == searchguid)
|
err = import_pools(pools, props, mntopts, flags, argv[0],
|
||||||
found_config = config;
|
argc == 1 ? NULL : argv[1], do_destroyed, pool_specified,
|
||||||
|
do_all, &idata);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we were searching for a specific pool, verify that we found a
|
|
||||||
* pool, and then do the import.
|
|
||||||
*/
|
|
||||||
if (argc != 0 && err == 0) {
|
|
||||||
if (found_config == NULL) {
|
|
||||||
(void) fprintf(stderr, gettext("cannot import '%s': "
|
|
||||||
"no such pool available\n"), argv[0]);
|
|
||||||
err = B_TRUE;
|
|
||||||
} else {
|
|
||||||
err |= do_import(found_config, argc == 1 ? NULL :
|
|
||||||
argv[1], mntopts, props, flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we were just looking for pools, report an error if none were
|
|
||||||
* found.
|
|
||||||
*/
|
|
||||||
if (argc == 0 && first)
|
|
||||||
(void) fprintf(stderr,
|
|
||||||
gettext("no pools available to import\n"));
|
|
||||||
|
|
||||||
error:
|
error:
|
||||||
nvlist_free(props);
|
nvlist_free(props);
|
||||||
|
@ -4852,8 +4915,8 @@ get_interval_count(int *argcp, char **argv, float *iv,
|
||||||
|
|
||||||
if (*end == '\0' && errno == 0) {
|
if (*end == '\0' && errno == 0) {
|
||||||
if (interval == 0) {
|
if (interval == 0) {
|
||||||
(void) fprintf(stderr, gettext("interval "
|
(void) fprintf(stderr, gettext(
|
||||||
"cannot be zero\n"));
|
"interval cannot be zero\n"));
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -4883,8 +4946,8 @@ get_interval_count(int *argcp, char **argv, float *iv,
|
||||||
|
|
||||||
if (*end == '\0' && errno == 0) {
|
if (*end == '\0' && errno == 0) {
|
||||||
if (interval == 0) {
|
if (interval == 0) {
|
||||||
(void) fprintf(stderr, gettext("interval "
|
(void) fprintf(stderr, gettext(
|
||||||
"cannot be zero\n"));
|
"interval cannot be zero\n"));
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4986,11 +5049,12 @@ get_stat_flags(zpool_list_t *list)
|
||||||
* Return 1 if cb_data->cb_vdev_names[0] is this vdev's name, 0 otherwise.
|
* Return 1 if cb_data->cb_vdev_names[0] is this vdev's name, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
is_vdev_cb(zpool_handle_t *zhp, nvlist_t *nv, void *cb_data)
|
is_vdev_cb(void *zhp_data, nvlist_t *nv, void *cb_data)
|
||||||
{
|
{
|
||||||
iostat_cbdata_t *cb = cb_data;
|
iostat_cbdata_t *cb = cb_data;
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
zpool_handle_t *zhp = zhp_data;
|
||||||
|
|
||||||
name = zpool_vdev_name(g_zfs, zhp, nv, cb->cb_name_flags);
|
name = zpool_vdev_name(g_zfs, zhp, nv, cb->cb_name_flags);
|
||||||
|
|
||||||
|
@ -5887,7 +5951,7 @@ print_one_column(zpool_prop_t prop, uint64_t value, const char *str,
|
||||||
break;
|
break;
|
||||||
case ZPOOL_PROP_HEALTH:
|
case ZPOOL_PROP_HEALTH:
|
||||||
width = 8;
|
width = 8;
|
||||||
snprintf(propval, sizeof (propval), "%-*s", (int)width, str);
|
(void) strlcpy(propval, str, sizeof (propval));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
zfs_nicenum_format(value, propval, sizeof (propval), format);
|
zfs_nicenum_format(value, propval, sizeof (propval), format);
|
||||||
|
@ -7735,8 +7799,8 @@ print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs)
|
||||||
* do not print estimated time if hours_left is more than
|
* do not print estimated time if hours_left is more than
|
||||||
* 30 days
|
* 30 days
|
||||||
*/
|
*/
|
||||||
(void) printf(gettext(" %s copied out of %s at %s/s, "
|
(void) printf(gettext(
|
||||||
"%.2f%% done"),
|
"\t%s copied out of %s at %s/s, %.2f%% done"),
|
||||||
examined_buf, total_buf, rate_buf, 100 * fraction_done);
|
examined_buf, total_buf, rate_buf, 100 * fraction_done);
|
||||||
if (hours_left < (30 * 24)) {
|
if (hours_left < (30 * 24)) {
|
||||||
(void) printf(gettext(", %lluh%um to go\n"),
|
(void) printf(gettext(", %lluh%um to go\n"),
|
||||||
|
@ -7751,8 +7815,8 @@ print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs)
|
||||||
if (prs->prs_mapping_memory > 0) {
|
if (prs->prs_mapping_memory > 0) {
|
||||||
char mem_buf[7];
|
char mem_buf[7];
|
||||||
zfs_nicenum(prs->prs_mapping_memory, mem_buf, sizeof (mem_buf));
|
zfs_nicenum(prs->prs_mapping_memory, mem_buf, sizeof (mem_buf));
|
||||||
(void) printf(gettext(" %s memory used for "
|
(void) printf(gettext(
|
||||||
"removed device mappings\n"),
|
"\t%s memory used for removed device mappings\n"),
|
||||||
mem_buf);
|
mem_buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <libnvpair.h>
|
#include <libnvpair.h>
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
|
#include <libzutil.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -67,7 +68,6 @@ int for_each_pool(int, char **, boolean_t unavail, zprop_list_t **,
|
||||||
boolean_t, zpool_iter_f, void *);
|
boolean_t, zpool_iter_f, void *);
|
||||||
|
|
||||||
/* Vdev list functions */
|
/* Vdev list functions */
|
||||||
typedef int (*pool_vdev_iter_f)(zpool_handle_t *, nvlist_t *, void *);
|
|
||||||
int for_each_vdev(zpool_handle_t *zhp, pool_vdev_iter_f func, void *data);
|
int for_each_vdev(zpool_handle_t *zhp, pool_vdev_iter_f func, void *data);
|
||||||
|
|
||||||
typedef struct zpool_list zpool_list_t;
|
typedef struct zpool_list zpool_list_t;
|
||||||
|
|
|
@ -13,3 +13,5 @@ zstream_LDADD = \
|
||||||
$(abs_top_builddir)/lib/libzfs/libzfs.la \
|
$(abs_top_builddir)/lib/libzfs/libzfs.la \
|
||||||
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
|
||||||
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
|
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|
|
@ -248,6 +248,7 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
|
||||||
fflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
|
fflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
|
||||||
fflags &= ~(DMU_BACKUP_FEATURE_DEDUP |
|
fflags &= ~(DMU_BACKUP_FEATURE_DEDUP |
|
||||||
DMU_BACKUP_FEATURE_DEDUPPROPS);
|
DMU_BACKUP_FEATURE_DEDUPPROPS);
|
||||||
|
/* cppcheck-suppress syntaxError */
|
||||||
DMU_SET_FEATUREFLAGS(drrb->drr_versioninfo, fflags);
|
DMU_SET_FEATUREFLAGS(drrb->drr_versioninfo, fflags);
|
||||||
|
|
||||||
int sz = drr->drr_payloadlen;
|
int sz = drr->drr_payloadlen;
|
||||||
|
|
|
@ -21,3 +21,5 @@ ztest_LDADD = \
|
||||||
|
|
||||||
ztest_LDADD += -lm
|
ztest_LDADD += -lm
|
||||||
ztest_LDFLAGS = -pthread
|
ztest_LDFLAGS = -pthread
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|
|
@ -132,7 +132,7 @@
|
||||||
#include <libnvpair.h>
|
#include <libnvpair.h>
|
||||||
#include <libzutil.h>
|
#include <libzutil.h>
|
||||||
#include <sys/crypto/icp.h>
|
#include <sys/crypto/icp.h>
|
||||||
#ifdef __GLIBC__
|
#if (__GLIBC__ && !__UCLIBC__)
|
||||||
#include <execinfo.h> /* for backtrace() */
|
#include <execinfo.h> /* for backtrace() */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -556,7 +556,7 @@ dump_debug_buffer(void)
|
||||||
static void sig_handler(int signo)
|
static void sig_handler(int signo)
|
||||||
{
|
{
|
||||||
struct sigaction action;
|
struct sigaction action;
|
||||||
#ifdef __GLIBC__ /* backtrace() is a GNU extension */
|
#if (__GLIBC__ && !__UCLIBC__) /* backtrace() is a GNU extension */
|
||||||
int nptrs;
|
int nptrs;
|
||||||
void *buffer[BACKTRACE_SZ];
|
void *buffer[BACKTRACE_SZ];
|
||||||
|
|
||||||
|
@ -2163,8 +2163,8 @@ ztest_get_done(zgd_t *zgd, int error)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ztest_get_data(void *arg, lr_write_t *lr, char *buf, struct lwb *lwb,
|
ztest_get_data(void *arg, uint64_t arg2, lr_write_t *lr, char *buf,
|
||||||
zio_t *zio)
|
struct lwb *lwb, zio_t *zio)
|
||||||
{
|
{
|
||||||
ztest_ds_t *zd = arg;
|
ztest_ds_t *zd = arg;
|
||||||
objset_t *os = zd->zd_os;
|
objset_t *os = zd->zd_os;
|
||||||
|
|
|
@ -8,3 +8,5 @@ udev_PROGRAMS = zvol_id
|
||||||
|
|
||||||
zvol_id_SOURCES = \
|
zvol_id_SOURCES = \
|
||||||
zvol_id_main.c
|
zvol_id_main.c
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/CppCheck.am
|
||||||
|
|
|
@ -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)
|
|
@ -3,6 +3,7 @@
|
||||||
# should include these rules and override or extend them as needed.
|
# should include these rules and override or extend them as needed.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
PHONY =
|
||||||
DEFAULT_INCLUDES = \
|
DEFAULT_INCLUDES = \
|
||||||
-include $(top_builddir)/zfs_config.h \
|
-include $(top_builddir)/zfs_config.h \
|
||||||
-I$(top_builddir)/include \
|
-I$(top_builddir)/include \
|
||||||
|
@ -25,6 +26,7 @@ AM_LIBTOOLFLAGS = --silent
|
||||||
AM_CFLAGS = -std=gnu99 -Wall -Wstrict-prototypes -Wmissing-prototypes
|
AM_CFLAGS = -std=gnu99 -Wall -Wstrict-prototypes -Wmissing-prototypes
|
||||||
AM_CFLAGS += -fno-strict-aliasing
|
AM_CFLAGS += -fno-strict-aliasing
|
||||||
AM_CFLAGS += $(NO_OMIT_FRAME_POINTER)
|
AM_CFLAGS += $(NO_OMIT_FRAME_POINTER)
|
||||||
|
AM_CFLAGS += $(IMPLICIT_FALLTHROUGH)
|
||||||
AM_CFLAGS += $(DEBUG_CFLAGS)
|
AM_CFLAGS += $(DEBUG_CFLAGS)
|
||||||
AM_CFLAGS += $(ASAN_CFLAGS)
|
AM_CFLAGS += $(ASAN_CFLAGS)
|
||||||
AM_CFLAGS += $(CODE_COVERAGE_CFLAGS) $(NO_FORMAT_ZERO_LENGTH)
|
AM_CFLAGS += $(CODE_COVERAGE_CFLAGS) $(NO_FORMAT_ZERO_LENGTH)
|
||||||
|
|
|
@ -161,6 +161,29 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_UNUSED_BUT_SET_VARIABLE], [
|
||||||
AC_SUBST([NO_UNUSED_BUT_SET_VARIABLE])
|
AC_SUBST([NO_UNUSED_BUT_SET_VARIABLE])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # Check if gcc supports -Wimplicit-fallthrough option.
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_IMPLICIT_FALLTHROUGH], [
|
||||||
|
AC_MSG_CHECKING([whether $CC supports -Wimplicit-fallthrough])
|
||||||
|
|
||||||
|
saved_flags="$CFLAGS"
|
||||||
|
CFLAGS="$CFLAGS -Werror -Wimplicit-fallthrough"
|
||||||
|
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
|
||||||
|
IMPLICIT_FALLTHROUGH=-Wimplicit-fallthrough
|
||||||
|
AC_DEFINE([HAVE_IMPLICIT_FALLTHROUGH], 1,
|
||||||
|
[Define if compiler supports -Wimplicit-fallthrough])
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
], [
|
||||||
|
IMPLICIT_FALLTHROUGH=
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
|
||||||
|
CFLAGS="$saved_flags"
|
||||||
|
AC_SUBST([IMPLICIT_FALLTHROUGH])
|
||||||
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Check if gcc supports -fno-omit-frame-pointer option.
|
dnl # Check if gcc supports -fno-omit-frame-pointer option.
|
||||||
dnl #
|
dnl #
|
||||||
|
|
|
@ -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])
|
||||||
|
])
|
|
@ -46,6 +46,21 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
|
||||||
])
|
])
|
||||||
AC_SUBST(DEFINE_PYZFS)
|
AC_SUBST(DEFINE_PYZFS)
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # Python "packaging" (or, failing that, "distlib") module is required to build and install pyzfs
|
||||||
|
dnl #
|
||||||
|
AS_IF([test "x$enable_pyzfs" = xcheck -o "x$enable_pyzfs" = xyes], [
|
||||||
|
ZFS_AC_PYTHON_MODULE([packaging], [], [
|
||||||
|
ZFS_AC_PYTHON_MODULE([distlib], [], [
|
||||||
|
AS_IF([test "x$enable_pyzfs" = xyes], [
|
||||||
|
AC_MSG_ERROR("Python $PYTHON_VERSION packaging and distlib modules are not installed")
|
||||||
|
], [test "x$enable_pyzfs" != xno], [
|
||||||
|
enable_pyzfs=no
|
||||||
|
])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Require python-devel libraries
|
dnl # Require python-devel libraries
|
||||||
dnl #
|
dnl #
|
||||||
|
|
|
@ -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
|
|
@ -97,9 +97,18 @@ AC_DEFUN([AX_PYTHON_DEVEL],[
|
||||||
# Check for a version of Python >= 2.1.0
|
# Check for a version of Python >= 2.1.0
|
||||||
#
|
#
|
||||||
AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
|
AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
|
||||||
ac_supports_python_ver=`$PYTHON -c "import sys; \
|
ac_supports_python_ver=`cat<<EOD | $PYTHON -
|
||||||
ver = sys.version.split ()[[0]]; \
|
from __future__ import print_function;
|
||||||
print (ver >= '2.1.0')"`
|
import sys;
|
||||||
|
try:
|
||||||
|
from packaging import version;
|
||||||
|
except ImportError:
|
||||||
|
from distlib import version;
|
||||||
|
ver = sys.version.split ()[[0]];
|
||||||
|
(tst_cmp, tst_ver) = ">= '2.1.0'".split ();
|
||||||
|
tst_ver = tst_ver.strip ("'");
|
||||||
|
eval ("print (version.LegacyVersion (ver)"+ tst_cmp +"version.LegacyVersion (tst_ver))")
|
||||||
|
EOD`
|
||||||
if test "$ac_supports_python_ver" != "True"; then
|
if test "$ac_supports_python_ver" != "True"; then
|
||||||
if test -z "$PYTHON_NOVERSIONCHECK"; then
|
if test -z "$PYTHON_NOVERSIONCHECK"; then
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
|
@ -126,9 +135,21 @@ to something else than an empty string.
|
||||||
#
|
#
|
||||||
if test -n "$1"; then
|
if test -n "$1"; then
|
||||||
AC_MSG_CHECKING([for a version of Python $1])
|
AC_MSG_CHECKING([for a version of Python $1])
|
||||||
ac_supports_python_ver=`$PYTHON -c "import sys; \
|
# Why the strip ()? Because if we don't, version.parse
|
||||||
ver = sys.version.split ()[[0]]; \
|
# will, for example, report 3.10.0 >= '3.11.0'
|
||||||
print (ver $1)"`
|
ac_supports_python_ver=`cat<<EOD | $PYTHON -
|
||||||
|
|
||||||
|
from __future__ import print_function;
|
||||||
|
import sys;
|
||||||
|
try:
|
||||||
|
from packaging import version;
|
||||||
|
except ImportError:
|
||||||
|
from distlib import version;
|
||||||
|
ver = sys.version.split ()[[0]];
|
||||||
|
(tst_cmp, tst_ver) = "$1".split ();
|
||||||
|
tst_ver = tst_ver.strip ("'");
|
||||||
|
eval ("print (version.LegacyVersion (ver)"+ tst_cmp +"version.LegacyVersion (tst_ver))")
|
||||||
|
EOD`
|
||||||
if test "$ac_supports_python_ver" = "True"; then
|
if test "$ac_supports_python_ver" = "True"; then
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
else
|
else
|
||||||
|
|
|
@ -162,6 +162,9 @@ dnl #
|
||||||
dnl # 3.1 API change,
|
dnl # 3.1 API change,
|
||||||
dnl # Check if inode_operations contains the function get_acl
|
dnl # Check if inode_operations contains the function get_acl
|
||||||
dnl #
|
dnl #
|
||||||
|
dnl # 5.15 API change,
|
||||||
|
dnl # Added the bool rcu argument to get_acl for rcu path walk.
|
||||||
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_get_acl], [
|
ZFS_LINUX_TEST_SRC([inode_operations_get_acl], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
@ -174,22 +177,55 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
|
||||||
.get_acl = get_acl_fn,
|
.get_acl = get_acl_fn,
|
||||||
};
|
};
|
||||||
],[])
|
],[])
|
||||||
|
|
||||||
|
ZFS_LINUX_TEST_SRC([inode_operations_get_acl_rcu], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
|
||||||
|
struct posix_acl *get_acl_fn(struct inode *inode, int type,
|
||||||
|
bool rcu) { return NULL; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.get_acl = get_acl_fn,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
|
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
|
||||||
AC_MSG_CHECKING([whether iops->get_acl() exists])
|
AC_MSG_CHECKING([whether iops->get_acl() exists])
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_get_acl], [
|
ZFS_LINUX_TEST_RESULT([inode_operations_get_acl], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_GET_ACL, 1, [iops->get_acl() exists])
|
||||||
|
],[
|
||||||
|
ZFS_LINUX_TEST_RESULT([inode_operations_get_acl_rcu], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_GET_ACL_RCU, 1, [iops->get_acl() takes rcu])
|
||||||
],[
|
],[
|
||||||
ZFS_LINUX_TEST_ERROR([iops->get_acl()])
|
ZFS_LINUX_TEST_ERROR([iops->get_acl()])
|
||||||
])
|
])
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 3.14 API change,
|
dnl # 3.14 API change,
|
||||||
dnl # Check if inode_operations contains the function set_acl
|
dnl # Check if inode_operations contains the function set_acl
|
||||||
dnl #
|
dnl #
|
||||||
|
dnl # 5.12 API change,
|
||||||
|
dnl # set_acl() added a user_namespace* parameter first
|
||||||
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
|
||||||
|
ZFS_LINUX_TEST_SRC([inode_operations_set_acl_userns], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
|
||||||
|
int set_acl_fn(struct user_namespace *userns,
|
||||||
|
struct inode *inode, struct posix_acl *acl,
|
||||||
|
int type) { return 0; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.set_acl = set_acl_fn,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_set_acl], [
|
ZFS_LINUX_TEST_SRC([inode_operations_set_acl], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
|
@ -205,12 +241,18 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
|
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
|
||||||
AC_MSG_CHECKING([whether iops->set_acl() exists])
|
AC_MSG_CHECKING([whether iops->set_acl() exists])
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [
|
ZFS_LINUX_TEST_RESULT([inode_operations_set_acl_userns], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
|
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
|
||||||
|
AC_DEFINE(HAVE_SET_ACL_USERNS, 1, [iops->set_acl() takes 4 args])
|
||||||
|
],[
|
||||||
|
ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists, takes 3 args])
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
|
|
|
@ -191,6 +191,24 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_SET_DEV], [
|
||||||
], [], [ZFS_META_LICENSE])
|
], [], [ZFS_META_LICENSE])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 5.16 API
|
||||||
|
dnl #
|
||||||
|
dnl # bio_set_dev is no longer a helper macro and is now an inline function,
|
||||||
|
dnl # meaning that the function it calls internally can no longer be overridden
|
||||||
|
dnl # by our code
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_SET_DEV_MACRO], [
|
||||||
|
ZFS_LINUX_TEST_SRC([bio_set_dev_macro], [
|
||||||
|
#include <linux/bio.h>
|
||||||
|
#include <linux/fs.h>
|
||||||
|
],[
|
||||||
|
#ifndef bio_set_dev
|
||||||
|
#error Not a macro
|
||||||
|
#endif
|
||||||
|
], [], [ZFS_META_LICENSE])
|
||||||
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_BIO_SET_DEV], [
|
AC_DEFUN([ZFS_AC_KERNEL_BIO_SET_DEV], [
|
||||||
AC_MSG_CHECKING([whether bio_set_dev() is available])
|
AC_MSG_CHECKING([whether bio_set_dev() is available])
|
||||||
ZFS_LINUX_TEST_RESULT([bio_set_dev], [
|
ZFS_LINUX_TEST_RESULT([bio_set_dev], [
|
||||||
|
@ -205,6 +223,15 @@ AC_DEFUN([ZFS_AC_KERNEL_BIO_SET_DEV], [
|
||||||
AC_DEFINE(HAVE_BIO_SET_DEV_GPL_ONLY, 1,
|
AC_DEFINE(HAVE_BIO_SET_DEV_GPL_ONLY, 1,
|
||||||
[bio_set_dev() GPL-only])
|
[bio_set_dev() GPL-only])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([whether bio_set_dev() is a macro])
|
||||||
|
ZFS_LINUX_TEST_RESULT([bio_set_dev_macro], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_BIO_SET_DEV_MACRO, 1,
|
||||||
|
[bio_set_dev() is a macro])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
|
@ -294,9 +321,8 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_SUBMIT_BIO], [
|
||||||
ZFS_LINUX_TEST_SRC([submit_bio], [
|
ZFS_LINUX_TEST_SRC([submit_bio], [
|
||||||
#include <linux/bio.h>
|
#include <linux/bio.h>
|
||||||
],[
|
],[
|
||||||
blk_qc_t blk_qc;
|
|
||||||
struct bio *bio = NULL;
|
struct bio *bio = NULL;
|
||||||
blk_qc = submit_bio(bio);
|
(void) submit_bio(bio);
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -369,6 +395,85 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKG_TRYGET], [
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 5.12 API,
|
||||||
|
dnl #
|
||||||
|
dnl # The Linux 5.12 kernel updated struct bio to create a new bi_bdev member
|
||||||
|
dnl # and bio->bi_disk was moved to bio->bi_bdev->bd_disk
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_BDEV_DISK], [
|
||||||
|
ZFS_LINUX_TEST_SRC([bio_bdev_disk], [
|
||||||
|
#include <linux/blk_types.h>
|
||||||
|
#include <linux/blkdev.h>
|
||||||
|
],[
|
||||||
|
struct bio *b = NULL;
|
||||||
|
struct gendisk *d = b->bi_bdev->bd_disk;
|
||||||
|
blk_register_queue(d);
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_BIO_BDEV_DISK], [
|
||||||
|
AC_MSG_CHECKING([whether bio->bi_bdev->bd_disk exists])
|
||||||
|
ZFS_LINUX_TEST_RESULT([bio_bdev_disk], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_BIO_BDEV_DISK, 1, [bio->bi_bdev->bd_disk exists])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 5.16 API
|
||||||
|
dnl #
|
||||||
|
dnl # The Linux 5.16 API for submit_bio changed the return type to be
|
||||||
|
dnl # void instead of int
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BDEV_SUBMIT_BIO_RETURNS_VOID], [
|
||||||
|
ZFS_LINUX_TEST_SRC([bio_bdev_submit_bio_void], [
|
||||||
|
#include <linux/blkdev.h>
|
||||||
|
],[
|
||||||
|
struct block_device_operations *bdev = NULL;
|
||||||
|
__attribute__((unused)) void(*f)(struct bio *) = bdev->submit_bio;
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_BDEV_SUBMIT_BIO_RETURNS_VOID], [
|
||||||
|
AC_MSG_CHECKING(
|
||||||
|
[whether block_device_operations->submit_bio() returns void])
|
||||||
|
ZFS_LINUX_TEST_RESULT([bio_bdev_submit_bio_void], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_BDEV_SUBMIT_BIO_RETURNS_VOID, 1,
|
||||||
|
[block_device_operations->submit_bio() returns void])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 5.16 API
|
||||||
|
dnl #
|
||||||
|
dnl # The Linux 5.16 API moved struct blkcg_gq into linux/blk-cgroup.h, which
|
||||||
|
dnl # has been around since 2015. This test looks for the presence of that
|
||||||
|
dnl # header, so that it can be conditionally included where it exists, but
|
||||||
|
dnl # still be backward compatible with kernels that pre-date its introduction.
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_CGROUP_HEADER], [
|
||||||
|
ZFS_LINUX_TEST_SRC([blk_cgroup_header], [
|
||||||
|
#include <linux/blk-cgroup.h>
|
||||||
|
], [])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_BLK_CGROUP_HEADER], [
|
||||||
|
AC_MSG_CHECKING([for existence of linux/blk-cgroup.h])
|
||||||
|
ZFS_LINUX_TEST_RESULT([blk_cgroup_header],[
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_LINUX_BLK_CGROUP_HEADER, 1,
|
||||||
|
[linux/blk-cgroup.h exists])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO], [
|
||||||
ZFS_AC_KERNEL_SRC_REQ
|
ZFS_AC_KERNEL_SRC_REQ
|
||||||
ZFS_AC_KERNEL_SRC_BIO_OPS
|
ZFS_AC_KERNEL_SRC_BIO_OPS
|
||||||
|
@ -379,6 +484,10 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO], [
|
||||||
ZFS_AC_KERNEL_SRC_BIO_SUBMIT_BIO
|
ZFS_AC_KERNEL_SRC_BIO_SUBMIT_BIO
|
||||||
ZFS_AC_KERNEL_SRC_BIO_CURRENT_BIO_LIST
|
ZFS_AC_KERNEL_SRC_BIO_CURRENT_BIO_LIST
|
||||||
ZFS_AC_KERNEL_SRC_BLKG_TRYGET
|
ZFS_AC_KERNEL_SRC_BLKG_TRYGET
|
||||||
|
ZFS_AC_KERNEL_SRC_BIO_BDEV_DISK
|
||||||
|
ZFS_AC_KERNEL_SRC_BDEV_SUBMIT_BIO_RETURNS_VOID
|
||||||
|
ZFS_AC_KERNEL_SRC_BIO_SET_DEV_MACRO
|
||||||
|
ZFS_AC_KERNEL_SRC_BLK_CGROUP_HEADER
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_BIO], [
|
AC_DEFUN([ZFS_AC_KERNEL_BIO], [
|
||||||
|
@ -400,4 +509,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BIO], [
|
||||||
ZFS_AC_KERNEL_BIO_SUBMIT_BIO
|
ZFS_AC_KERNEL_BIO_SUBMIT_BIO
|
||||||
ZFS_AC_KERNEL_BIO_CURRENT_BIO_LIST
|
ZFS_AC_KERNEL_BIO_CURRENT_BIO_LIST
|
||||||
ZFS_AC_KERNEL_BLKG_TRYGET
|
ZFS_AC_KERNEL_BLKG_TRYGET
|
||||||
|
ZFS_AC_KERNEL_BIO_BDEV_DISK
|
||||||
|
ZFS_AC_KERNEL_BDEV_SUBMIT_BIO_RETURNS_VOID
|
||||||
|
ZFS_AC_KERNEL_BLK_CGROUP_HEADER
|
||||||
])
|
])
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API change removes BIO_MAX_PAGES in favor of bio_max_segs()
|
||||||
|
dnl # which will handle the logic of setting the upper-bound to a
|
||||||
|
dnl # BIO_MAX_PAGES, internally.
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_MAX_SEGS], [
|
||||||
|
ZFS_LINUX_TEST_SRC([bio_max_segs], [
|
||||||
|
#include <linux/bio.h>
|
||||||
|
],[
|
||||||
|
bio_max_segs(1);
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_BIO_MAX_SEGS], [
|
||||||
|
AC_MSG_CHECKING([whether bio_max_segs() exists])
|
||||||
|
ZFS_LINUX_TEST_RESULT([bio_max_segs], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
|
||||||
|
AC_DEFINE([HAVE_BIO_MAX_SEGS], 1, [bio_max_segs() is implemented])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
|
@ -48,7 +48,45 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_BDI], [
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 2.6.32 - 4.x API,
|
dnl # 5.9: added blk_queue_update_readahead(),
|
||||||
|
dnl # 5.15: renamed to disk_update_readahead()
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_UPDATE_READAHEAD], [
|
||||||
|
ZFS_LINUX_TEST_SRC([blk_queue_update_readahead], [
|
||||||
|
#include <linux/blkdev.h>
|
||||||
|
],[
|
||||||
|
struct request_queue q;
|
||||||
|
blk_queue_update_readahead(&q);
|
||||||
|
])
|
||||||
|
|
||||||
|
ZFS_LINUX_TEST_SRC([disk_update_readahead], [
|
||||||
|
#include <linux/blkdev.h>
|
||||||
|
],[
|
||||||
|
struct gendisk disk;
|
||||||
|
disk_update_readahead(&disk);
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_UPDATE_READAHEAD], [
|
||||||
|
AC_MSG_CHECKING([whether blk_queue_update_readahead() exists])
|
||||||
|
ZFS_LINUX_TEST_RESULT([blk_queue_update_readahead], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_BLK_QUEUE_UPDATE_READAHEAD, 1,
|
||||||
|
[blk_queue_update_readahead() exists])
|
||||||
|
],[
|
||||||
|
AC_MSG_CHECKING([whether disk_update_readahead() exists])
|
||||||
|
ZFS_LINUX_TEST_RESULT([disk_update_readahead], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_DISK_UPDATE_READAHEAD, 1,
|
||||||
|
[disk_update_readahead() exists])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # 2.6.32 API,
|
||||||
dnl # blk_queue_discard()
|
dnl # blk_queue_discard()
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD], [
|
||||||
|
@ -280,6 +318,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS], [
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE], [
|
||||||
ZFS_AC_KERNEL_SRC_BLK_QUEUE_PLUG
|
ZFS_AC_KERNEL_SRC_BLK_QUEUE_PLUG
|
||||||
ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI
|
ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI
|
||||||
|
ZFS_AC_KERNEL_SRC_BLK_QUEUE_UPDATE_READAHEAD
|
||||||
ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD
|
ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD
|
||||||
ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE
|
ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE
|
||||||
ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAG_SET
|
ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAG_SET
|
||||||
|
@ -292,6 +331,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE], [
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE], [
|
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE], [
|
||||||
ZFS_AC_KERNEL_BLK_QUEUE_PLUG
|
ZFS_AC_KERNEL_BLK_QUEUE_PLUG
|
||||||
ZFS_AC_KERNEL_BLK_QUEUE_BDI
|
ZFS_AC_KERNEL_BLK_QUEUE_BDI
|
||||||
|
ZFS_AC_KERNEL_BLK_QUEUE_UPDATE_READAHEAD
|
||||||
ZFS_AC_KERNEL_BLK_QUEUE_DISCARD
|
ZFS_AC_KERNEL_BLK_QUEUE_DISCARD
|
||||||
ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE
|
ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE
|
||||||
ZFS_AC_KERNEL_BLK_QUEUE_FLAG_SET
|
ZFS_AC_KERNEL_BLK_QUEUE_FLAG_SET
|
||||||
|
|
|
@ -294,6 +294,27 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BDEV_WHOLE], [
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # 5.13 API change
|
||||||
|
dnl # blkdev_get_by_path() no longer handles ERESTARTSYS
|
||||||
|
dnl #
|
||||||
|
dnl # Unfortunately we're forced to rely solely on the kernel version
|
||||||
|
dnl # number in order to determine the expected behavior. This was an
|
||||||
|
dnl # internal change to blkdev_get_by_dev(), see commit a8ed1a0607.
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_ERESTARTSYS], [
|
||||||
|
AC_MSG_CHECKING([whether blkdev_get_by_path() handles ERESTARTSYS])
|
||||||
|
AS_VERSION_COMPARE([$LINUX_VERSION], [5.13.0], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_BLKDEV_GET_ERESTARTSYS, 1,
|
||||||
|
[blkdev_get_by_path() handles ERESTARTSYS])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
|
||||||
ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH
|
ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH
|
||||||
ZFS_AC_KERNEL_SRC_BLKDEV_PUT
|
ZFS_AC_KERNEL_SRC_BLKDEV_PUT
|
||||||
|
@ -318,4 +339,5 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [
|
||||||
ZFS_AC_KERNEL_BLKDEV_CHECK_DISK_CHANGE
|
ZFS_AC_KERNEL_BLKDEV_CHECK_DISK_CHANGE
|
||||||
ZFS_AC_KERNEL_BLKDEV_BDEV_CHECK_MEDIA_CHANGE
|
ZFS_AC_KERNEL_BLKDEV_BDEV_CHECK_MEDIA_CHANGE
|
||||||
ZFS_AC_KERNEL_BLKDEV_BDEV_WHOLE
|
ZFS_AC_KERNEL_BLKDEV_BDEV_WHOLE
|
||||||
|
ZFS_AC_KERNEL_BLKDEV_GET_ERESTARTSYS
|
||||||
])
|
])
|
||||||
|
|
|
@ -52,12 +52,44 @@ AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # 5.13 API change
|
||||||
|
dnl # block_device_operations->revalidate_disk() was removed
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [
|
||||||
|
ZFS_LINUX_TEST_SRC([block_device_operations_revalidate_disk], [
|
||||||
|
#include <linux/blkdev.h>
|
||||||
|
|
||||||
|
int blk_revalidate_disk(struct gendisk *disk) {
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct block_device_operations
|
||||||
|
bops __attribute__ ((unused)) = {
|
||||||
|
.revalidate_disk = blk_revalidate_disk,
|
||||||
|
};
|
||||||
|
], [], [$NO_UNUSED_BUT_SET_VARIABLE])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [
|
||||||
|
AC_MSG_CHECKING([whether bops->revalidate_disk() exists])
|
||||||
|
ZFS_LINUX_TEST_RESULT([block_device_operations_revalidate_disk], [
|
||||||
|
AC_DEFINE([HAVE_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [1],
|
||||||
|
[Define if revalidate_disk() in block_device_operations])
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS], [
|
||||||
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
|
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
|
||||||
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
|
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
|
||||||
|
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS], [
|
AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS], [
|
||||||
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
|
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
|
||||||
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
|
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
|
||||||
|
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK
|
||||||
])
|
])
|
||||||
|
|
|
@ -2,6 +2,9 @@ dnl #
|
||||||
dnl # Handle differences in kernel FPU code.
|
dnl # Handle differences in kernel FPU code.
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Kernel
|
dnl # Kernel
|
||||||
|
dnl # 5.16: XCR code put into asm/fpu/xcr.h
|
||||||
|
dnl # HAVE_KERNEL_FPU_XCR_HEADER
|
||||||
|
dnl #
|
||||||
dnl # 5.0: Wrappers have been introduced to save/restore the FPU state.
|
dnl # 5.0: Wrappers have been introduced to save/restore the FPU state.
|
||||||
dnl # This change was made to the 4.19.38 and 4.14.120 LTS kernels.
|
dnl # This change was made to the 4.19.38 and 4.14.120 LTS kernels.
|
||||||
dnl # HAVE_KERNEL_FPU_INTERNAL
|
dnl # HAVE_KERNEL_FPU_INTERNAL
|
||||||
|
@ -25,6 +28,18 @@ AC_DEFUN([ZFS_AC_KERNEL_FPU_HEADER], [
|
||||||
AC_DEFINE(HAVE_KERNEL_FPU_API_HEADER, 1,
|
AC_DEFINE(HAVE_KERNEL_FPU_API_HEADER, 1,
|
||||||
[kernel has asm/fpu/api.h])
|
[kernel has asm/fpu/api.h])
|
||||||
AC_MSG_RESULT(asm/fpu/api.h)
|
AC_MSG_RESULT(asm/fpu/api.h)
|
||||||
|
AC_MSG_CHECKING([whether fpu/xcr header is available])
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <asm/fpu/xcr.h>
|
||||||
|
],[
|
||||||
|
],[
|
||||||
|
AC_DEFINE(HAVE_KERNEL_FPU_XCR_HEADER, 1,
|
||||||
|
[kernel has asm/fpu/xcr.h])
|
||||||
|
AC_MSG_RESULT(asm/fpu/xcr.h)
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no asm/fpu/xcr.h)
|
||||||
|
])
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(i387.h & xcr.h)
|
AC_MSG_RESULT(i387.h & xcr.h)
|
||||||
])
|
])
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API
|
||||||
|
dnl #
|
||||||
|
dnl # generic_fillattr in linux/fs.h now requires a struct user_namespace*
|
||||||
|
dnl # as the first arg, to support idmapped mounts.
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS], [
|
||||||
|
ZFS_LINUX_TEST_SRC([generic_fillattr_userns], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
],[
|
||||||
|
struct user_namespace *userns = NULL;
|
||||||
|
struct inode *in = NULL;
|
||||||
|
struct kstat *k = NULL;
|
||||||
|
generic_fillattr(userns, in, k);
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS], [
|
||||||
|
AC_MSG_CHECKING([whether generic_fillattr requres struct user_namespace*])
|
||||||
|
ZFS_LINUX_TEST_RESULT([generic_fillattr_userns], [
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_DEFINE(HAVE_GENERIC_FILLATTR_USERNS, 1,
|
||||||
|
[generic_fillattr requires struct user_namespace*])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
|
@ -2,6 +2,17 @@ dnl #
|
||||||
dnl # Check for generic io accounting interface.
|
dnl # Check for generic io accounting interface.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT], [
|
||||||
|
ZFS_LINUX_TEST_SRC([disk_io_acct], [
|
||||||
|
#include <linux/blkdev.h>
|
||||||
|
], [
|
||||||
|
struct gendisk *disk = NULL;
|
||||||
|
struct bio *bio = NULL;
|
||||||
|
unsigned long start_time;
|
||||||
|
|
||||||
|
start_time = disk_start_io_acct(disk, bio_sectors(bio), bio_op(bio));
|
||||||
|
disk_end_io_acct(disk, bio_op(bio), start_time);
|
||||||
|
])
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([bio_io_acct], [
|
ZFS_LINUX_TEST_SRC([bio_io_acct], [
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
], [
|
], [
|
||||||
|
@ -38,6 +49,19 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT], [
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT], [
|
AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT], [
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API,
|
||||||
|
dnl #
|
||||||
|
dnl # bio_start_io_acct() and bio_end_io_acct() became GPL-exported
|
||||||
|
dnl # so use disk_start_io_acct() and disk_end_io_acct() instead
|
||||||
|
dnl #
|
||||||
|
AC_MSG_CHECKING([whether generic disk_*_io_acct() are available])
|
||||||
|
ZFS_LINUX_TEST_RESULT([disk_io_acct], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_DISK_IO_ACCT, 1, [disk_*_io_acct() available])
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 5.7 API,
|
dnl # 5.7 API,
|
||||||
dnl #
|
dnl #
|
||||||
|
@ -84,4 +108,5 @@ AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT], [
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
|
@ -1,7 +1,25 @@
|
||||||
dnl #
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
|
||||||
dnl # 3.6 API change
|
dnl #
|
||||||
dnl #
|
dnl # 5.12 API change that added the struct user_namespace* arg
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE_FLAGS], [
|
dnl # to the front of this function type's arg list.
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([create_userns], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
|
||||||
|
int inode_create(struct user_namespace *userns,
|
||||||
|
struct inode *inode ,struct dentry *dentry,
|
||||||
|
umode_t umode, bool flag) { return 0; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.create = inode_create,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # 3.6 API change
|
||||||
|
dnl #
|
||||||
ZFS_LINUX_TEST_SRC([create_flags], [
|
ZFS_LINUX_TEST_SRC([create_flags], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
@ -16,11 +34,20 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE_FLAGS], [
|
||||||
],[])
|
],[])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_CREATE_FLAGS], [
|
AC_DEFUN([ZFS_AC_KERNEL_CREATE], [
|
||||||
|
AC_MSG_CHECKING([whether iops->create() takes struct user_namespace*])
|
||||||
|
ZFS_LINUX_TEST_RESULT([create_userns], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_IOPS_CREATE_USERNS, 1,
|
||||||
|
[iops->create() takes struct user_namespace*])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether iops->create() passes flags])
|
AC_MSG_CHECKING([whether iops->create() passes flags])
|
||||||
ZFS_LINUX_TEST_RESULT([create_flags], [
|
ZFS_LINUX_TEST_RESULT([create_flags], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
],[
|
],[
|
||||||
ZFS_LINUX_TEST_ERROR([iops->create()])
|
ZFS_LINUX_TEST_ERROR([iops->create()])
|
||||||
])
|
])
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
|
@ -1,8 +1,29 @@
|
||||||
dnl #
|
|
||||||
dnl # Linux 4.11 API
|
|
||||||
dnl # See torvalds/linux@a528d35
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 5.12 API
|
||||||
|
dnl # The getattr I/O operations handler type was extended to require
|
||||||
|
dnl # a struct user_namespace* as its first arg, to support idmapped
|
||||||
|
dnl # mounts.
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([inode_operations_getattr_userns], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
|
||||||
|
int test_getattr(
|
||||||
|
struct user_namespace *userns,
|
||||||
|
const struct path *p, struct kstat *k,
|
||||||
|
u32 request_mask, unsigned int query_flags)
|
||||||
|
{ return 0; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.getattr = test_getattr,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 4.11 API
|
||||||
|
dnl # See torvalds/linux@a528d35
|
||||||
|
dnl #
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_getattr_path], [
|
ZFS_LINUX_TEST_SRC([inode_operations_getattr_path], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
|
@ -33,6 +54,20 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
|
AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
|
||||||
|
dnl #
|
||||||
|
dnl # Kernel 5.12 test
|
||||||
|
dnl #
|
||||||
|
AC_MSG_CHECKING([whether iops->getattr() takes user_namespace])
|
||||||
|
ZFS_LINUX_TEST_RESULT([inode_operations_getattr_userns], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_USERNS_IOPS_GETATTR, 1,
|
||||||
|
[iops->getattr() takes struct user_namespace*])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # Kernel 4.11 test
|
||||||
|
dnl #
|
||||||
AC_MSG_CHECKING([whether iops->getattr() takes a path])
|
AC_MSG_CHECKING([whether iops->getattr() takes a path])
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_getattr_path], [
|
ZFS_LINUX_TEST_RESULT([inode_operations_getattr_path], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
|
@ -41,6 +76,9 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # Kernel < 4.11 test
|
||||||
|
dnl #
|
||||||
AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
|
AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_getattr_vfsmount], [
|
ZFS_LINUX_TEST_RESULT([inode_operations_getattr_vfsmount], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
|
@ -50,4 +88,5 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
|
@ -11,13 +11,32 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OWNER_OR_CAPABLE], [
|
||||||
struct inode *ip = NULL;
|
struct inode *ip = NULL;
|
||||||
(void) inode_owner_or_capable(ip);
|
(void) inode_owner_or_capable(ip);
|
||||||
])
|
])
|
||||||
|
|
||||||
|
ZFS_LINUX_TEST_SRC([inode_owner_or_capable_idmapped], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
],[
|
||||||
|
struct inode *ip = NULL;
|
||||||
|
(void) inode_owner_or_capable(&init_user_ns, ip);
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE], [
|
AC_DEFUN([ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE], [
|
||||||
AC_MSG_CHECKING([whether inode_owner_or_capable() exists])
|
AC_MSG_CHECKING([whether inode_owner_or_capable() exists])
|
||||||
ZFS_LINUX_TEST_RESULT([inode_owner_or_capable], [
|
ZFS_LINUX_TEST_RESULT([inode_owner_or_capable], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE, 1,
|
||||||
|
[inode_owner_or_capable() exists])
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
|
AC_MSG_CHECKING(
|
||||||
|
[whether inode_owner_or_capable() takes user_ns])
|
||||||
|
ZFS_LINUX_TEST_RESULT([inode_owner_or_capable_idmapped], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE_IDMAPPED, 1,
|
||||||
|
[inode_owner_or_capable() takes user_ns])
|
||||||
],[
|
],[
|
||||||
ZFS_LINUX_TEST_ERROR([capability])
|
ZFS_LINUX_TEST_ERROR([capability])
|
||||||
])
|
])
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
|
@ -42,6 +42,13 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN], [
|
||||||
struct block_device_operations o;
|
struct block_device_operations o;
|
||||||
o.submit_bio = NULL;
|
o.submit_bio = NULL;
|
||||||
])
|
])
|
||||||
|
|
||||||
|
ZFS_LINUX_TEST_SRC([blk_alloc_disk], [
|
||||||
|
#include <linux/blkdev.h>
|
||||||
|
],[
|
||||||
|
struct gendisk *disk __attribute__ ((unused));
|
||||||
|
disk = blk_alloc_disk(NUMA_NO_NODE);
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
|
AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
|
||||||
|
@ -56,6 +63,19 @@ AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
|
||||||
|
|
||||||
AC_DEFINE(HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS, 1,
|
AC_DEFINE(HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS, 1,
|
||||||
[submit_bio is member of struct block_device_operations])
|
[submit_bio is member of struct block_device_operations])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 5.14 API Change:
|
||||||
|
dnl # blk_alloc_queue() + alloc_disk() combo replaced by
|
||||||
|
dnl # a single call to blk_alloc_disk().
|
||||||
|
dnl #
|
||||||
|
AC_MSG_CHECKING([whether blk_alloc_disk() exists])
|
||||||
|
ZFS_LINUX_TEST_RESULT([blk_alloc_disk], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE([HAVE_BLK_ALLOC_DISK], 1, [blk_alloc_disk() exists])
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
dnl #
|
|
||||||
dnl # 3.3 API change
|
|
||||||
dnl # The VFS .create, .mkdir and .mknod callbacks were updated to take a
|
|
||||||
dnl # umode_t type rather than an int. The expectation is that any backport
|
|
||||||
dnl # would also change all three prototypes. However, if it turns out that
|
|
||||||
dnl # some distribution doesn't backport the whole thing this could be
|
|
||||||
dnl # broken apart into three separate checks.
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR_UMODE_T], [
|
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_mkdir], [
|
|
||||||
#include <linux/fs.h>
|
|
||||||
|
|
||||||
int mkdir(struct inode *inode, struct dentry *dentry,
|
|
||||||
umode_t umode) { return 0; }
|
|
||||||
|
|
||||||
static const struct inode_operations
|
|
||||||
iops __attribute__ ((unused)) = {
|
|
||||||
.mkdir = mkdir,
|
|
||||||
};
|
|
||||||
],[])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_MKDIR_UMODE_T], [
|
|
||||||
AC_MSG_CHECKING([whether iops->create()/mkdir()/mknod() take umode_t])
|
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_mkdir], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_MKDIR_UMODE_T, 1,
|
|
||||||
[iops->create()/mkdir()/mknod() take umode_t])
|
|
||||||
],[
|
|
||||||
ZFS_LINUX_TEST_ERROR([mkdir()])
|
|
||||||
])
|
|
||||||
])
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
dnl #
|
||||||
|
dnl # Supported mkdir() interfaces checked newest to oldest.
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR], [
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API change
|
||||||
|
dnl # The struct user_namespace arg was added as the first argument to
|
||||||
|
dnl # mkdir()
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([mkdir_user_namespace], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
|
||||||
|
int mkdir(struct user_namespace *userns,
|
||||||
|
struct inode *inode, struct dentry *dentry,
|
||||||
|
umode_t umode) { return 0; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.mkdir = mkdir,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # 3.3 API change
|
||||||
|
dnl # The VFS .create, .mkdir and .mknod callbacks were updated to take a
|
||||||
|
dnl # umode_t type rather than an int. The expectation is that any backport
|
||||||
|
dnl # would also change all three prototypes. However, if it turns out that
|
||||||
|
dnl # some distribution doesn't backport the whole thing this could be
|
||||||
|
dnl # broken apart into three separate checks.
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([inode_operations_mkdir], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
|
||||||
|
int mkdir(struct inode *inode, struct dentry *dentry,
|
||||||
|
umode_t umode) { return 0; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.mkdir = mkdir,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_MKDIR], [
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API change
|
||||||
|
dnl # The struct user_namespace arg was added as the first argument to
|
||||||
|
dnl # mkdir() of the iops structure.
|
||||||
|
dnl #
|
||||||
|
AC_MSG_CHECKING([whether iops->mkdir() takes struct user_namespace*])
|
||||||
|
ZFS_LINUX_TEST_RESULT([mkdir_user_namespace], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_IOPS_MKDIR_USERNS, 1,
|
||||||
|
[iops->mkdir() takes struct user_namespace*])
|
||||||
|
],[
|
||||||
|
AC_MSG_CHECKING([whether iops->mkdir() takes umode_t])
|
||||||
|
ZFS_LINUX_TEST_RESULT([inode_operations_mkdir], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_MKDIR_UMODE_T, 1,
|
||||||
|
[iops->mkdir() takes umode_t])
|
||||||
|
],[
|
||||||
|
ZFS_LINUX_TEST_ERROR([mkdir()])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
])
|
|
@ -0,0 +1,30 @@
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_MKNOD], [
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API change that added the struct user_namespace* arg
|
||||||
|
dnl # to the front of this function type's arg list.
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([mknod_userns], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
|
||||||
|
int tmp_mknod(struct user_namespace *userns,
|
||||||
|
struct inode *inode ,struct dentry *dentry,
|
||||||
|
umode_t u, dev_t d) { return 0; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.mknod = tmp_mknod,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_MKNOD], [
|
||||||
|
AC_MSG_CHECKING([whether iops->mknod() takes struct user_namespace*])
|
||||||
|
ZFS_LINUX_TEST_RESULT([mknod_userns], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_IOPS_MKNOD_USERNS, 1,
|
||||||
|
[iops->mknod() takes struct user_namespace*])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
|
@ -0,0 +1,26 @@
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 5.16 no longer allows directly calling wait_on_page_bit, and
|
||||||
|
dnl # instead requires you to call folio-specific functions. In this case,
|
||||||
|
dnl # wait_on_page_bit(pg, PG_writeback) becomes
|
||||||
|
dnl # folio_wait_bit(pg, PG_writeback)
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_PAGEMAP_FOLIO_WAIT_BIT], [
|
||||||
|
ZFS_LINUX_TEST_SRC([pagemap_has_folio_wait_bit], [
|
||||||
|
#include <linux/pagemap.h>
|
||||||
|
],[
|
||||||
|
static struct folio *f = NULL;
|
||||||
|
|
||||||
|
folio_wait_bit(f, PG_writeback);
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_PAGEMAP_FOLIO_WAIT_BIT], [
|
||||||
|
AC_MSG_CHECKING([folio_wait_bit() exists])
|
||||||
|
ZFS_LINUX_TEST_RESULT([pagemap_has_folio_wait_bit], [
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_DEFINE(HAVE_PAGEMAP_FOLIO_WAIT_BIT, 1,
|
||||||
|
[folio_wait_bit() exists])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
])
|
|
@ -1,10 +1,10 @@
|
||||||
dnl #
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME], [
|
||||||
dnl # 4.9 API change,
|
dnl #
|
||||||
dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
|
dnl # 4.9 API change,
|
||||||
dnl # flags.
|
dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
|
||||||
dnl #
|
dnl # flags.
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS], [
|
dnl #
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_rename], [
|
ZFS_LINUX_TEST_SRC([inode_operations_rename_flags], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
int rename_fn(struct inode *sip, struct dentry *sdp,
|
int rename_fn(struct inode *sip, struct dentry *sdp,
|
||||||
struct inode *tip, struct dentry *tdp,
|
struct inode *tip, struct dentry *tdp,
|
||||||
|
@ -15,15 +15,41 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS], [
|
||||||
.rename = rename_fn,
|
.rename = rename_fn,
|
||||||
};
|
};
|
||||||
],[])
|
],[])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API change,
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 5.12 introduced passing struct user_namespace* as the first argument
|
||||||
|
dnl # of the rename() and other inode_operations members.
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([inode_operations_rename_userns], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
int rename_fn(struct user_namespace *user_ns, struct inode *sip,
|
||||||
|
struct dentry *sdp, struct inode *tip, struct dentry *tdp,
|
||||||
|
unsigned int flags) { return 0; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.rename = rename_fn,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_RENAME_WANTS_FLAGS], [
|
AC_DEFUN([ZFS_AC_KERNEL_RENAME], [
|
||||||
AC_MSG_CHECKING([whether iops->rename() wants flags])
|
AC_MSG_CHECKING([whether iops->rename() takes struct user_namespace*])
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_rename], [
|
ZFS_LINUX_TEST_RESULT([inode_operations_rename_userns], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_IOPS_RENAME_USERNS, 1,
|
||||||
|
[iops->rename() takes struct user_namespace*])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
|
ZFS_LINUX_TEST_RESULT([inode_operations_rename_flags], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1,
|
AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1,
|
||||||
[iops->rename() wants flags])
|
[iops->rename() wants flags])
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
dnl #
|
|
||||||
dnl # 4.9 API change
|
|
||||||
dnl # The inode_change_ok() function has been renamed setattr_prepare()
|
|
||||||
dnl # and updated to take a dentry rather than an inode.
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_SETATTR_PREPARE], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_SETATTR_PREPARE], [
|
||||||
|
dnl #
|
||||||
|
dnl # 4.9 API change
|
||||||
|
dnl # The inode_change_ok() function has been renamed setattr_prepare()
|
||||||
|
dnl # and updated to take a dentry rather than an inode.
|
||||||
|
dnl #
|
||||||
ZFS_LINUX_TEST_SRC([setattr_prepare], [
|
ZFS_LINUX_TEST_SRC([setattr_prepare], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
], [
|
], [
|
||||||
|
@ -12,16 +12,41 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_SETATTR_PREPARE], [
|
||||||
int error __attribute__ ((unused)) =
|
int error __attribute__ ((unused)) =
|
||||||
setattr_prepare(dentry, attr);
|
setattr_prepare(dentry, attr);
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API change
|
||||||
|
dnl # The setattr_prepare() function has been changed to accept a new argument
|
||||||
|
dnl # for struct user_namespace*
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([setattr_prepare_userns], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
], [
|
||||||
|
struct dentry *dentry = NULL;
|
||||||
|
struct iattr *attr = NULL;
|
||||||
|
struct user_namespace *userns = NULL;
|
||||||
|
int error __attribute__ ((unused)) =
|
||||||
|
setattr_prepare(userns, dentry, attr);
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SETATTR_PREPARE], [
|
AC_DEFUN([ZFS_AC_KERNEL_SETATTR_PREPARE], [
|
||||||
AC_MSG_CHECKING([whether setattr_prepare() is available])
|
AC_MSG_CHECKING([whether setattr_prepare() is available and accepts struct user_namespace*])
|
||||||
|
ZFS_LINUX_TEST_RESULT_SYMBOL([setattr_prepare_userns],
|
||||||
|
[setattr_prepare], [fs/attr.c], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_SETATTR_PREPARE_USERNS, 1,
|
||||||
|
[setattr_prepare() accepts user_namespace])
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([whether setattr_prepare() is available, doesn't accept user_namespace])
|
||||||
ZFS_LINUX_TEST_RESULT_SYMBOL([setattr_prepare],
|
ZFS_LINUX_TEST_RESULT_SYMBOL([setattr_prepare],
|
||||||
[setattr_prepare], [fs/attr.c], [
|
[setattr_prepare], [fs/attr.c], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_SETATTR_PREPARE, 1,
|
AC_DEFINE(HAVE_SETATTR_PREPARE_NO_USERNS, 1,
|
||||||
[setattr_prepare() is available])
|
[setattr_prepare() is available, doesn't accept user_namespace])
|
||||||
], [
|
], [
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
dnl #
|
||||||
|
dnl # 4.20 API change
|
||||||
|
dnl # Added kernel_siginfo_t
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_SIGINFO], [
|
||||||
|
ZFS_LINUX_TEST_SRC([siginfo], [
|
||||||
|
#include <linux/signal_types.h>
|
||||||
|
],[
|
||||||
|
kernel_siginfo_t info __attribute__ ((unused));
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SIGINFO], [
|
||||||
|
AC_MSG_CHECKING([whether kernel_siginfo_t tyepedef exists])
|
||||||
|
ZFS_LINUX_TEST_RESULT([siginfo], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_SIGINFO, 1, [kernel_siginfo_t exists])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
|
@ -0,0 +1,21 @@
|
||||||
|
dnl #
|
||||||
|
dnl # 4.4 API change
|
||||||
|
dnl # Added kernel_signal_stop
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_SIGNAL_STOP], [
|
||||||
|
ZFS_LINUX_TEST_SRC([signal_stop], [
|
||||||
|
#include <linux/sched/signal.h>
|
||||||
|
],[
|
||||||
|
kernel_signal_stop();
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SIGNAL_STOP], [
|
||||||
|
AC_MSG_CHECKING([whether signal_stop() exists])
|
||||||
|
ZFS_LINUX_TEST_RESULT([signal_stop], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_SIGNAL_STOP, 1, [signal_stop() exists])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
|
@ -0,0 +1,21 @@
|
||||||
|
dnl #
|
||||||
|
dnl # 4.17 API change
|
||||||
|
dnl # Added set_special_state() function
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_SET_SPECIAL_STATE], [
|
||||||
|
ZFS_LINUX_TEST_SRC([set_special_state], [
|
||||||
|
#include <linux/sched.h>
|
||||||
|
],[
|
||||||
|
set_special_state(TASK_STOPPED);
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SET_SPECIAL_STATE], [
|
||||||
|
AC_MSG_CHECKING([whether set_special_state() exists])
|
||||||
|
ZFS_LINUX_TEST_RESULT([set_special_state], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_SET_SPECIAL_STATE, 1, [set_special_state() exists])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
|
@ -0,0 +1,32 @@
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 5.15 gets rid of -isystem and external <stdarg.h> inclusion
|
||||||
|
dnl # and ships its own <linux/stdarg.h>. Check if this header file does
|
||||||
|
dnl # exist and provide all necessary definitions for variable argument
|
||||||
|
dnl # functions. Adjust the inclusion of <stdarg.h> according to the
|
||||||
|
dnl # results.
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_STANDALONE_LINUX_STDARG], [
|
||||||
|
ZFS_LINUX_TEST_SRC([has_standalone_linux_stdarg], [
|
||||||
|
#include <linux/stdarg.h>
|
||||||
|
|
||||||
|
#if !defined(va_start) || !defined(va_end) || \
|
||||||
|
!defined(va_arg) || !defined(va_copy)
|
||||||
|
#error "<linux/stdarg.h> is invalid"
|
||||||
|
#endif
|
||||||
|
],[])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_STANDALONE_LINUX_STDARG], [
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 5.15 ships its own stdarg.h and doesn't allow to
|
||||||
|
dnl # include compiler headers.
|
||||||
|
dnl #
|
||||||
|
AC_MSG_CHECKING([whether standalone <linux/stdarg.h> exists])
|
||||||
|
ZFS_LINUX_TEST_RESULT([has_standalone_linux_stdarg], [
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_DEFINE(HAVE_STANDALONE_LINUX_STDARG, 1,
|
||||||
|
[standalone <linux/stdarg.h> exists])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
])
|
|
@ -0,0 +1,30 @@
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_SYMLINK], [
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API change that added the struct user_namespace* arg
|
||||||
|
dnl # to the front of this function type's arg list.
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([symlink_userns], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
|
||||||
|
int tmp_symlink(struct user_namespace *userns,
|
||||||
|
struct inode *inode ,struct dentry *dentry,
|
||||||
|
const char *path) { return 0; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.symlink = tmp_symlink,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SYMLINK], [
|
||||||
|
AC_MSG_CHECKING([whether iops->symlink() takes struct user_namespace*])
|
||||||
|
ZFS_LINUX_TEST_RESULT([symlink_userns], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_IOPS_SYMLINK_USERNS, 1,
|
||||||
|
[iops->symlink() takes struct user_namespace*])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
|
@ -3,6 +3,20 @@ dnl # 3.11 API change
|
||||||
dnl # Add support for i_op->tmpfile
|
dnl # Add support for i_op->tmpfile
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_TMPFILE], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_TMPFILE], [
|
||||||
|
dnl #
|
||||||
|
dnl # 5.11 API change
|
||||||
|
dnl # add support for userns parameter to tmpfile
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([inode_operations_tmpfile_userns], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
int tmpfile(struct user_namespace *userns,
|
||||||
|
struct inode *inode, struct dentry *dentry,
|
||||||
|
umode_t mode) { return 0; }
|
||||||
|
static struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.tmpfile = tmpfile,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_tmpfile], [
|
ZFS_LINUX_TEST_SRC([inode_operations_tmpfile], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
int tmpfile(struct inode *inode, struct dentry *dentry,
|
int tmpfile(struct inode *inode, struct dentry *dentry,
|
||||||
|
@ -16,10 +30,16 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_TMPFILE], [
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_TMPFILE], [
|
AC_DEFUN([ZFS_AC_KERNEL_TMPFILE], [
|
||||||
AC_MSG_CHECKING([whether i_op->tmpfile() exists])
|
AC_MSG_CHECKING([whether i_op->tmpfile() exists])
|
||||||
|
ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile_userns], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
|
||||||
|
AC_DEFINE(HAVE_TMPFILE_USERNS, 1, [i_op->tmpfile() has userns])
|
||||||
|
],[
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile], [
|
ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
|
AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
|
@ -99,6 +99,14 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_IOV_ITER], [
|
||||||
|
|
||||||
bytes = copy_from_iter((void *)&buf, size, &iter);
|
bytes = copy_from_iter((void *)&buf, size, &iter);
|
||||||
])
|
])
|
||||||
|
|
||||||
|
ZFS_LINUX_TEST_SRC([iov_iter_type], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
|
],[
|
||||||
|
struct iov_iter iter = { 0 };
|
||||||
|
__attribute__((unused)) enum iter_type i = iov_iter_type(&iter);
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_VFS_IOV_ITER], [
|
AC_DEFUN([ZFS_AC_KERNEL_VFS_IOV_ITER], [
|
||||||
|
@ -193,6 +201,20 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_IOV_ITER], [
|
||||||
enable_vfs_iov_iter="no"
|
enable_vfs_iov_iter="no"
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # This checks for iov_iter_type() in linux/uio.h. It is not
|
||||||
|
dnl # required, however, and the module will compiled without it
|
||||||
|
dnl # using direct access of the member attribute
|
||||||
|
dnl #
|
||||||
|
AC_MSG_CHECKING([whether iov_iter_type() is available])
|
||||||
|
ZFS_LINUX_TEST_RESULT([iov_iter_type], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_IOV_ITER_TYPE, 1,
|
||||||
|
[iov_iter_type() is available])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # As of the 4.9 kernel support is provided for iovecs, kvecs,
|
dnl # As of the 4.9 kernel support is provided for iovecs, kvecs,
|
||||||
dnl # bvecs and pipes in the iov_iter structure. As long as the
|
dnl # bvecs and pipes in the iov_iter structure. As long as the
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 5.14 adds a change to require set_page_dirty to be manually
|
||||||
|
dnl # wired up in struct address_space_operations. Determine if this needs
|
||||||
|
dnl # to be done. This patch set also introduced __set_page_dirty_nobuffers
|
||||||
|
dnl # declaration in linux/pagemap.h, so these tests look for the presence
|
||||||
|
dnl # of that function to tell the compiler to assign set_page_dirty in
|
||||||
|
dnl # module/os/linux/zfs/zpl_file.c
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_SET_PAGE_DIRTY_NOBUFFERS], [
|
||||||
|
ZFS_LINUX_TEST_SRC([vfs_has_set_page_dirty_nobuffers], [
|
||||||
|
#include <linux/pagemap.h>
|
||||||
|
#include <linux/fs.h>
|
||||||
|
|
||||||
|
static const struct address_space_operations
|
||||||
|
aops __attribute__ ((unused)) = {
|
||||||
|
.set_page_dirty = __set_page_dirty_nobuffers,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_VFS_SET_PAGE_DIRTY_NOBUFFERS], [
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 5.14 change requires set_page_dirty() to be assigned
|
||||||
|
dnl # in address_space_operations()
|
||||||
|
dnl #
|
||||||
|
AC_MSG_CHECKING([__set_page_dirty_nobuffers exists])
|
||||||
|
ZFS_LINUX_TEST_RESULT([vfs_has_set_page_dirty_nobuffers], [
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_DEFINE(HAVE_VFS_SET_PAGE_DIRTY_NOBUFFERS, 1,
|
||||||
|
[__set_page_dirty_nobuffers exists])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
])
|
|
@ -152,6 +152,21 @@ dnl #
|
||||||
dnl # Supported xattr handler set() interfaces checked newest to oldest.
|
dnl # Supported xattr handler set() interfaces checked newest to oldest.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET], [
|
||||||
|
ZFS_LINUX_TEST_SRC([xattr_handler_set_userns], [
|
||||||
|
#include <linux/xattr.h>
|
||||||
|
|
||||||
|
int set(const struct xattr_handler *handler,
|
||||||
|
struct user_namespace *mnt_userns,
|
||||||
|
struct dentry *dentry, struct inode *inode,
|
||||||
|
const char *name, const void *buffer,
|
||||||
|
size_t size, int flags)
|
||||||
|
{ return 0; }
|
||||||
|
static const struct xattr_handler
|
||||||
|
xops __attribute__ ((unused)) = {
|
||||||
|
.set = set,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([xattr_handler_set_dentry_inode], [
|
ZFS_LINUX_TEST_SRC([xattr_handler_set_dentry_inode], [
|
||||||
#include <linux/xattr.h>
|
#include <linux/xattr.h>
|
||||||
|
|
||||||
|
@ -193,11 +208,23 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET], [
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
|
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API change,
|
||||||
|
dnl # The xattr_handler->set() callback was changed to 8 arguments, and
|
||||||
|
dnl # struct user_namespace* was inserted as arg #2
|
||||||
|
dnl #
|
||||||
|
AC_MSG_CHECKING([whether xattr_handler->set() wants dentry, inode, and user_namespace])
|
||||||
|
ZFS_LINUX_TEST_RESULT([xattr_handler_set_userns], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_XATTR_SET_USERNS, 1,
|
||||||
|
[xattr_handler->set() takes user_namespace])
|
||||||
|
],[
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 4.7 API change,
|
dnl # 4.7 API change,
|
||||||
dnl # The xattr_handler->set() callback was changed to take both
|
dnl # The xattr_handler->set() callback was changed to take both
|
||||||
dnl # dentry and inode.
|
dnl # dentry and inode.
|
||||||
dnl #
|
dnl #
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
AC_MSG_CHECKING([whether xattr_handler->set() wants dentry and inode])
|
AC_MSG_CHECKING([whether xattr_handler->set() wants dentry and inode])
|
||||||
ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry_inode], [
|
ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry_inode], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
|
@ -236,6 +263,7 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
|
|
|
@ -79,9 +79,9 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
|
||||||
ZFS_AC_KERNEL_SRC_EVICT_INODE
|
ZFS_AC_KERNEL_SRC_EVICT_INODE
|
||||||
ZFS_AC_KERNEL_SRC_DIRTY_INODE
|
ZFS_AC_KERNEL_SRC_DIRTY_INODE
|
||||||
ZFS_AC_KERNEL_SRC_SHRINKER
|
ZFS_AC_KERNEL_SRC_SHRINKER
|
||||||
ZFS_AC_KERNEL_SRC_MKDIR_UMODE_T
|
ZFS_AC_KERNEL_SRC_MKDIR
|
||||||
ZFS_AC_KERNEL_SRC_LOOKUP_FLAGS
|
ZFS_AC_KERNEL_SRC_LOOKUP_FLAGS
|
||||||
ZFS_AC_KERNEL_SRC_CREATE_FLAGS
|
ZFS_AC_KERNEL_SRC_CREATE
|
||||||
ZFS_AC_KERNEL_SRC_GET_LINK
|
ZFS_AC_KERNEL_SRC_GET_LINK
|
||||||
ZFS_AC_KERNEL_SRC_PUT_LINK
|
ZFS_AC_KERNEL_SRC_PUT_LINK
|
||||||
ZFS_AC_KERNEL_SRC_TMPFILE
|
ZFS_AC_KERNEL_SRC_TMPFILE
|
||||||
|
@ -115,7 +115,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
|
||||||
ZFS_AC_KERNEL_SRC_KUIDGID_T
|
ZFS_AC_KERNEL_SRC_KUIDGID_T
|
||||||
ZFS_AC_KERNEL_SRC_KUID_HELPERS
|
ZFS_AC_KERNEL_SRC_KUID_HELPERS
|
||||||
ZFS_AC_KERNEL_SRC_MODULE_PARAM_CALL_CONST
|
ZFS_AC_KERNEL_SRC_MODULE_PARAM_CALL_CONST
|
||||||
ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS
|
ZFS_AC_KERNEL_SRC_RENAME
|
||||||
ZFS_AC_KERNEL_SRC_CURRENT_TIME
|
ZFS_AC_KERNEL_SRC_CURRENT_TIME
|
||||||
ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES
|
ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES
|
||||||
ZFS_AC_KERNEL_SRC_IN_COMPAT_SYSCALL
|
ZFS_AC_KERNEL_SRC_IN_COMPAT_SYSCALL
|
||||||
|
@ -124,6 +124,16 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
|
||||||
ZFS_AC_KERNEL_SRC_TOTALHIGH_PAGES
|
ZFS_AC_KERNEL_SRC_TOTALHIGH_PAGES
|
||||||
ZFS_AC_KERNEL_SRC_KSTRTOUL
|
ZFS_AC_KERNEL_SRC_KSTRTOUL
|
||||||
ZFS_AC_KERNEL_SRC_PERCPU
|
ZFS_AC_KERNEL_SRC_PERCPU
|
||||||
|
ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS
|
||||||
|
ZFS_AC_KERNEL_SRC_MKNOD
|
||||||
|
ZFS_AC_KERNEL_SRC_SYMLINK
|
||||||
|
ZFS_AC_KERNEL_SRC_BIO_MAX_SEGS
|
||||||
|
ZFS_AC_KERNEL_SRC_SIGNAL_STOP
|
||||||
|
ZFS_AC_KERNEL_SRC_SIGINFO
|
||||||
|
ZFS_AC_KERNEL_SRC_SET_SPECIAL_STATE
|
||||||
|
ZFS_AC_KERNEL_SRC_VFS_SET_PAGE_DIRTY_NOBUFFERS
|
||||||
|
ZFS_AC_KERNEL_SRC_STANDALONE_LINUX_STDARG
|
||||||
|
ZFS_AC_KERNEL_SRC_PAGEMAP_FOLIO_WAIT_BIT
|
||||||
|
|
||||||
AC_MSG_CHECKING([for available kernel interfaces])
|
AC_MSG_CHECKING([for available kernel interfaces])
|
||||||
ZFS_LINUX_TEST_COMPILE_ALL([kabi])
|
ZFS_LINUX_TEST_COMPILE_ALL([kabi])
|
||||||
|
@ -176,9 +186,9 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
|
||||||
ZFS_AC_KERNEL_EVICT_INODE
|
ZFS_AC_KERNEL_EVICT_INODE
|
||||||
ZFS_AC_KERNEL_DIRTY_INODE
|
ZFS_AC_KERNEL_DIRTY_INODE
|
||||||
ZFS_AC_KERNEL_SHRINKER
|
ZFS_AC_KERNEL_SHRINKER
|
||||||
ZFS_AC_KERNEL_MKDIR_UMODE_T
|
ZFS_AC_KERNEL_MKDIR
|
||||||
ZFS_AC_KERNEL_LOOKUP_FLAGS
|
ZFS_AC_KERNEL_LOOKUP_FLAGS
|
||||||
ZFS_AC_KERNEL_CREATE_FLAGS
|
ZFS_AC_KERNEL_CREATE
|
||||||
ZFS_AC_KERNEL_GET_LINK
|
ZFS_AC_KERNEL_GET_LINK
|
||||||
ZFS_AC_KERNEL_PUT_LINK
|
ZFS_AC_KERNEL_PUT_LINK
|
||||||
ZFS_AC_KERNEL_TMPFILE
|
ZFS_AC_KERNEL_TMPFILE
|
||||||
|
@ -212,7 +222,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
|
||||||
ZFS_AC_KERNEL_KUIDGID_T
|
ZFS_AC_KERNEL_KUIDGID_T
|
||||||
ZFS_AC_KERNEL_KUID_HELPERS
|
ZFS_AC_KERNEL_KUID_HELPERS
|
||||||
ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST
|
ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST
|
||||||
ZFS_AC_KERNEL_RENAME_WANTS_FLAGS
|
ZFS_AC_KERNEL_RENAME
|
||||||
ZFS_AC_KERNEL_CURRENT_TIME
|
ZFS_AC_KERNEL_CURRENT_TIME
|
||||||
ZFS_AC_KERNEL_USERNS_CAPABILITIES
|
ZFS_AC_KERNEL_USERNS_CAPABILITIES
|
||||||
ZFS_AC_KERNEL_IN_COMPAT_SYSCALL
|
ZFS_AC_KERNEL_IN_COMPAT_SYSCALL
|
||||||
|
@ -221,6 +231,16 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
|
||||||
ZFS_AC_KERNEL_TOTALHIGH_PAGES
|
ZFS_AC_KERNEL_TOTALHIGH_PAGES
|
||||||
ZFS_AC_KERNEL_KSTRTOUL
|
ZFS_AC_KERNEL_KSTRTOUL
|
||||||
ZFS_AC_KERNEL_PERCPU
|
ZFS_AC_KERNEL_PERCPU
|
||||||
|
ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS
|
||||||
|
ZFS_AC_KERNEL_MKNOD
|
||||||
|
ZFS_AC_KERNEL_SYMLINK
|
||||||
|
ZFS_AC_KERNEL_BIO_MAX_SEGS
|
||||||
|
ZFS_AC_KERNEL_SIGNAL_STOP
|
||||||
|
ZFS_AC_KERNEL_SIGINFO
|
||||||
|
ZFS_AC_KERNEL_SET_SPECIAL_STATE
|
||||||
|
ZFS_AC_KERNEL_VFS_SET_PAGE_DIRTY_NOBUFFERS
|
||||||
|
ZFS_AC_KERNEL_STANDALONE_LINUX_STDARG
|
||||||
|
ZFS_AC_KERNEL_PAGEMAP_FOLIO_WAIT_BIT
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
|
|
|
@ -153,8 +153,12 @@ AC_DEFUN([ZFS_AC_DEBUG_KMEM_TRACKING], [
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
|
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_UNUSED_BUT_SET_VARIABLE
|
||||||
ZFS_AC_CONFIG_ALWAYS_CC_NO_BOOL_COMPARE
|
ZFS_AC_CONFIG_ALWAYS_CC_NO_BOOL_COMPARE
|
||||||
|
ZFS_AC_CONFIG_ALWAYS_CC_IMPLICIT_FALLTHROUGH
|
||||||
ZFS_AC_CONFIG_ALWAYS_CC_FRAME_LARGER_THAN
|
ZFS_AC_CONFIG_ALWAYS_CC_FRAME_LARGER_THAN
|
||||||
ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_TRUNCATION
|
ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_TRUNCATION
|
||||||
ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_ZERO_LENGTH
|
ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_ZERO_LENGTH
|
||||||
|
@ -167,6 +171,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
|
||||||
ZFS_AC_CONFIG_ALWAYS_PYTHON
|
ZFS_AC_CONFIG_ALWAYS_PYTHON
|
||||||
ZFS_AC_CONFIG_ALWAYS_PYZFS
|
ZFS_AC_CONFIG_ALWAYS_PYZFS
|
||||||
ZFS_AC_CONFIG_ALWAYS_SED
|
ZFS_AC_CONFIG_ALWAYS_SED
|
||||||
|
ZFS_AC_CONFIG_ALWAYS_CPPCHECK
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_CONFIG], [
|
AC_DEFUN([ZFS_AC_CONFIG], [
|
||||||
|
@ -191,12 +196,10 @@ AC_DEFUN([ZFS_AC_CONFIG], [
|
||||||
|
|
||||||
ZFS_AC_CONFIG_ALWAYS
|
ZFS_AC_CONFIG_ALWAYS
|
||||||
|
|
||||||
|
|
||||||
AM_COND_IF([BUILD_LINUX], [
|
AM_COND_IF([BUILD_LINUX], [
|
||||||
AC_ARG_VAR([TEST_JOBS],
|
AC_ARG_VAR([TEST_JOBS], [simultaneous jobs during configure])
|
||||||
[simultaneous jobs during configure (defaults to $(nproc))])
|
|
||||||
if test "x$ac_cv_env_TEST_JOBS_set" != "xset"; then
|
if test "x$ac_cv_env_TEST_JOBS_set" != "xset"; then
|
||||||
TEST_JOBS=$(nproc)
|
TEST_JOBS=$CPU_COUNT
|
||||||
fi
|
fi
|
||||||
AC_SUBST(TEST_JOBS)
|
AC_SUBST(TEST_JOBS)
|
||||||
])
|
])
|
||||||
|
|
|
@ -221,6 +221,7 @@ AC_CONFIG_FILES([
|
||||||
tests/zfs-tests/cmd/mktree/Makefile
|
tests/zfs-tests/cmd/mktree/Makefile
|
||||||
tests/zfs-tests/cmd/mmap_exec/Makefile
|
tests/zfs-tests/cmd/mmap_exec/Makefile
|
||||||
tests/zfs-tests/cmd/mmap_libaio/Makefile
|
tests/zfs-tests/cmd/mmap_libaio/Makefile
|
||||||
|
tests/zfs-tests/cmd/mmap_seek/Makefile
|
||||||
tests/zfs-tests/cmd/mmapwrite/Makefile
|
tests/zfs-tests/cmd/mmapwrite/Makefile
|
||||||
tests/zfs-tests/cmd/nvlist_to_lua/Makefile
|
tests/zfs-tests/cmd/nvlist_to_lua/Makefile
|
||||||
tests/zfs-tests/cmd/randfree_file/Makefile
|
tests/zfs-tests/cmd/randfree_file/Makefile
|
||||||
|
@ -228,6 +229,7 @@ AC_CONFIG_FILES([
|
||||||
tests/zfs-tests/cmd/readmmap/Makefile
|
tests/zfs-tests/cmd/readmmap/Makefile
|
||||||
tests/zfs-tests/cmd/rename_dir/Makefile
|
tests/zfs-tests/cmd/rename_dir/Makefile
|
||||||
tests/zfs-tests/cmd/rm_lnkcnt_zero_file/Makefile
|
tests/zfs-tests/cmd/rm_lnkcnt_zero_file/Makefile
|
||||||
|
tests/zfs-tests/cmd/send_doall/Makefile
|
||||||
tests/zfs-tests/cmd/stride_dd/Makefile
|
tests/zfs-tests/cmd/stride_dd/Makefile
|
||||||
tests/zfs-tests/cmd/threadsappend/Makefile
|
tests/zfs-tests/cmd/threadsappend/Makefile
|
||||||
tests/zfs-tests/cmd/user_ns_exec/Makefile
|
tests/zfs-tests/cmd/user_ns_exec/Makefile
|
||||||
|
@ -236,6 +238,7 @@ AC_CONFIG_FILES([
|
||||||
tests/zfs-tests/tests/Makefile
|
tests/zfs-tests/tests/Makefile
|
||||||
tests/zfs-tests/tests/functional/Makefile
|
tests/zfs-tests/tests/functional/Makefile
|
||||||
tests/zfs-tests/tests/functional/acl/Makefile
|
tests/zfs-tests/tests/functional/acl/Makefile
|
||||||
|
tests/zfs-tests/tests/functional/acl/off/Makefile
|
||||||
tests/zfs-tests/tests/functional/acl/posix/Makefile
|
tests/zfs-tests/tests/functional/acl/posix/Makefile
|
||||||
tests/zfs-tests/tests/functional/acl/posix-sa/Makefile
|
tests/zfs-tests/tests/functional/acl/posix-sa/Makefile
|
||||||
tests/zfs-tests/tests/functional/alloc_class/Makefile
|
tests/zfs-tests/tests/functional/alloc_class/Makefile
|
||||||
|
|
|
@ -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
|
[ -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
|
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
|
echo "zfs-generator: finished" >> /dev/kmsg
|
||||||
|
|
|
@ -82,7 +82,11 @@ alloc_pw_size(size_t len)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
pw->len = len;
|
pw->len = len;
|
||||||
pw->value = malloc(len);
|
/*
|
||||||
|
* The use of malloc() triggers a spurious gcc 11 -Wmaybe-uninitialized
|
||||||
|
* warning in the mlock() function call below, so use calloc().
|
||||||
|
*/
|
||||||
|
pw->value = calloc(len, 1);
|
||||||
if (!pw->value) {
|
if (!pw->value) {
|
||||||
free(pw);
|
free(pw);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
@ -99,7 +103,11 @@ alloc_pw_string(const char *source)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
pw->len = strlen(source) + 1;
|
pw->len = strlen(source) + 1;
|
||||||
pw->value = malloc(pw->len);
|
/*
|
||||||
|
* The use of malloc() triggers a spurious gcc 11 -Wmaybe-uninitialized
|
||||||
|
* warning in the mlock() function call below, so use calloc().
|
||||||
|
*/
|
||||||
|
pw->value = calloc(pw->len, 1);
|
||||||
if (!pw->value) {
|
if (!pw->value) {
|
||||||
free(pw);
|
free(pw);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
|
@ -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
|
|
|
@ -8,7 +8,7 @@ After=cryptsetup.target
|
||||||
After=multipathd.target
|
After=multipathd.target
|
||||||
After=systemd-remount-fs.service
|
After=systemd-remount-fs.service
|
||||||
Before=zfs-import.target
|
Before=zfs-import.target
|
||||||
ConditionPathExists=@sysconfdir@/zfs/zpool.cache
|
ConditionFileNotEmpty=@sysconfdir@/zfs/zpool.cache
|
||||||
ConditionPathIsDirectory=/sys/module/zfs
|
ConditionPathIsDirectory=/sys/module/zfs
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
|
|
|
@ -7,7 +7,7 @@ After=systemd-udev-settle.service
|
||||||
After=cryptsetup.target
|
After=cryptsetup.target
|
||||||
After=multipathd.target
|
After=multipathd.target
|
||||||
Before=zfs-import.target
|
Before=zfs-import.target
|
||||||
ConditionPathExists=!@sysconfdir@/zfs/zpool.cache
|
ConditionFileNotEmpty=!@sysconfdir@/zfs/zpool.cache
|
||||||
ConditionPathIsDirectory=/sys/module/zfs
|
ConditionPathIsDirectory=/sys/module/zfs
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
|
|
|
@ -159,6 +159,16 @@ void color_start(char *color);
|
||||||
void color_end(void);
|
void color_end(void);
|
||||||
int printf_color(char *color, char *format, ...);
|
int printf_color(char *color, char *format, ...);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These functions are used by the ZFS libraries and cmd/zpool code, but are
|
||||||
|
* not exported in the ABI.
|
||||||
|
*/
|
||||||
|
typedef int (*pool_vdev_iter_f)(void *, nvlist_t *, void *);
|
||||||
|
int for_each_vdev_cb(void *zhp, nvlist_t *nv, pool_vdev_iter_f func,
|
||||||
|
void *data);
|
||||||
|
int for_each_vdev_in_nvlist(nvlist_t *nvroot, pool_vdev_iter_f func,
|
||||||
|
void *data);
|
||||||
|
void update_vdevs_config_dev_sysfs_path(nvlist_t *config);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -67,6 +67,7 @@
|
||||||
#define __always_inline inline
|
#define __always_inline inline
|
||||||
#define noinline __noinline
|
#define noinline __noinline
|
||||||
#define ____cacheline_aligned __aligned(CACHE_LINE_SIZE)
|
#define ____cacheline_aligned __aligned(CACHE_LINE_SIZE)
|
||||||
|
#define fallthrough __attribute__((__fallthrough__))
|
||||||
|
|
||||||
#if !defined(_KERNEL) && !defined(_STANDALONE)
|
#if !defined(_KERNEL) && !defined(_STANDALONE)
|
||||||
#define likely(x) __builtin_expect(!!(x), 1)
|
#define likely(x) __builtin_expect(!!(x), 1)
|
||||||
|
|
|
@ -4,6 +4,7 @@ KERNEL_H = \
|
||||||
atomic.h \
|
atomic.h \
|
||||||
byteorder.h \
|
byteorder.h \
|
||||||
callb.h \
|
callb.h \
|
||||||
|
ccompat.h \
|
||||||
ccompile.h \
|
ccompile.h \
|
||||||
cmn_err.h \
|
cmn_err.h \
|
||||||
condvar.h \
|
condvar.h \
|
||||||
|
@ -18,9 +19,11 @@ KERNEL_H = \
|
||||||
fcntl.h \
|
fcntl.h \
|
||||||
file.h \
|
file.h \
|
||||||
freebsd_rwlock.h \
|
freebsd_rwlock.h \
|
||||||
|
idmap.h \
|
||||||
inttypes.h \
|
inttypes.h \
|
||||||
isa_defs.h \
|
isa_defs.h \
|
||||||
kmem_cache.h \
|
kmem_cache.h \
|
||||||
|
kidmap.h \
|
||||||
kmem.h \
|
kmem.h \
|
||||||
kstat.h \
|
kstat.h \
|
||||||
list_impl.h \
|
list_impl.h \
|
||||||
|
|
|
@ -74,9 +74,9 @@ void spl_dumpstack(void);
|
||||||
"%s", "VERIFY(" #cond ") failed\n"))
|
"%s", "VERIFY(" #cond ") failed\n"))
|
||||||
|
|
||||||
#define VERIFY3B(LEFT, OP, RIGHT) do { \
|
#define VERIFY3B(LEFT, OP, RIGHT) do { \
|
||||||
boolean_t _verify3_left = (boolean_t)(LEFT); \
|
const boolean_t _verify3_left = (boolean_t)(LEFT); \
|
||||||
boolean_t _verify3_right = (boolean_t)(RIGHT); \
|
const boolean_t _verify3_right = (boolean_t)(RIGHT);\
|
||||||
if (!(_verify3_left OP _verify3_right)) \
|
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||||
"failed (%d " #OP " %d)\n", \
|
"failed (%d " #OP " %d)\n", \
|
||||||
|
@ -85,9 +85,9 @@ void spl_dumpstack(void);
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define VERIFY3S(LEFT, OP, RIGHT) do { \
|
#define VERIFY3S(LEFT, OP, RIGHT) do { \
|
||||||
int64_t _verify3_left = (int64_t)(LEFT); \
|
const int64_t _verify3_left = (int64_t)(LEFT); \
|
||||||
int64_t _verify3_right = (int64_t)(RIGHT); \
|
const int64_t _verify3_right = (int64_t)(RIGHT); \
|
||||||
if (!(_verify3_left OP _verify3_right)) \
|
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||||
"failed (%lld " #OP " %lld)\n", \
|
"failed (%lld " #OP " %lld)\n", \
|
||||||
|
@ -96,9 +96,9 @@ void spl_dumpstack(void);
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define VERIFY3U(LEFT, OP, RIGHT) do { \
|
#define VERIFY3U(LEFT, OP, RIGHT) do { \
|
||||||
uint64_t _verify3_left = (uint64_t)(LEFT); \
|
const uint64_t _verify3_left = (uint64_t)(LEFT); \
|
||||||
uint64_t _verify3_right = (uint64_t)(RIGHT); \
|
const uint64_t _verify3_right = (uint64_t)(RIGHT); \
|
||||||
if (!(_verify3_left OP _verify3_right)) \
|
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||||
"failed (%llu " #OP " %llu)\n", \
|
"failed (%llu " #OP " %llu)\n", \
|
||||||
|
@ -107,9 +107,9 @@ void spl_dumpstack(void);
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define VERIFY3P(LEFT, OP, RIGHT) do { \
|
#define VERIFY3P(LEFT, OP, RIGHT) do { \
|
||||||
uintptr_t _verify3_left = (uintptr_t)(LEFT); \
|
const uintptr_t _verify3_left = (uintptr_t)(LEFT); \
|
||||||
uintptr_t _verify3_right = (uintptr_t)(RIGHT); \
|
const uintptr_t _verify3_right = (uintptr_t)(RIGHT);\
|
||||||
if (!(_verify3_left OP _verify3_right)) \
|
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||||
"failed (%px " #OP " %px)\n", \
|
"failed (%px " #OP " %px)\n", \
|
||||||
|
@ -118,9 +118,9 @@ void spl_dumpstack(void);
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define VERIFY0(RIGHT) do { \
|
#define VERIFY0(RIGHT) do { \
|
||||||
int64_t _verify3_left = (int64_t)(0); \
|
const int64_t _verify3_left = (int64_t)(0); \
|
||||||
int64_t _verify3_right = (int64_t)(RIGHT); \
|
const int64_t _verify3_right = (int64_t)(RIGHT); \
|
||||||
if (!(_verify3_left == _verify3_right)) \
|
if (unlikely(!(_verify3_left == _verify3_right))) \
|
||||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
"VERIFY3(0 == " #RIGHT ") " \
|
"VERIFY3(0 == " #RIGHT ") " \
|
||||||
"failed (0 == %lld)\n", \
|
"failed (0 == %lld)\n", \
|
||||||
|
@ -154,11 +154,11 @@ void spl_dumpstack(void);
|
||||||
#define ASSERT0 VERIFY0
|
#define ASSERT0 VERIFY0
|
||||||
#define ASSERT VERIFY
|
#define ASSERT VERIFY
|
||||||
#define IMPLY(A, B) \
|
#define IMPLY(A, B) \
|
||||||
((void)(((!(A)) || (B)) || \
|
((void)(likely((!(A)) || (B)) || \
|
||||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
"(" #A ") implies (" #B ")")))
|
"(" #A ") implies (" #B ")")))
|
||||||
#define EQUIV(A, B) \
|
#define EQUIV(A, B) \
|
||||||
((void)((!!(A) == !!(B)) || \
|
((void)(likely(!!(A) == !!(B)) || \
|
||||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
"(" #A ") is equivalent to (" #B ")")))
|
"(" #A ") is equivalent to (" #B ")")))
|
||||||
/* END CSTYLED */
|
/* END CSTYLED */
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#define _OPENSOLARIS_SYS_MISC_H_
|
#define _OPENSOLARIS_SYS_MISC_H_
|
||||||
|
|
||||||
#include <sys/limits.h>
|
#include <sys/limits.h>
|
||||||
|
#include <sys/filio.h>
|
||||||
|
|
||||||
#define MAXUID UID_MAX
|
#define MAXUID UID_MAX
|
||||||
|
|
||||||
|
@ -40,8 +41,8 @@
|
||||||
#define _FIOGDIO (INT_MIN+1)
|
#define _FIOGDIO (INT_MIN+1)
|
||||||
#define _FIOSDIO (INT_MIN+2)
|
#define _FIOSDIO (INT_MIN+2)
|
||||||
|
|
||||||
#define _FIO_SEEK_DATA FIOSEEKDATA
|
#define F_SEEK_DATA FIOSEEKDATA
|
||||||
#define _FIO_SEEK_HOLE FIOSEEKHOLE
|
#define F_SEEK_HOLE FIOSEEKHOLE
|
||||||
|
|
||||||
struct opensolaris_utsname {
|
struct opensolaris_utsname {
|
||||||
char *sysname;
|
char *sysname;
|
||||||
|
|
|
@ -35,81 +35,47 @@
|
||||||
#include <sys/_uio.h>
|
#include <sys/_uio.h>
|
||||||
#include <sys/debug.h>
|
#include <sys/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define uio_loffset uio_offset
|
|
||||||
|
|
||||||
typedef struct uio uio_t;
|
|
||||||
typedef struct iovec iovec_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 enum xuio_type {
|
typedef struct zfs_uio {
|
||||||
UIOTYPE_ASYNCIO,
|
struct uio *uio;
|
||||||
UIOTYPE_ZEROCOPY
|
} zfs_uio_t;
|
||||||
} xuio_type_t;
|
|
||||||
|
|
||||||
typedef struct xuio {
|
#define GET_UIO_STRUCT(u) (u)->uio
|
||||||
uio_t xu_uio;
|
#define zfs_uio_segflg(u) GET_UIO_STRUCT(u)->uio_segflg
|
||||||
|
#define zfs_uio_offset(u) GET_UIO_STRUCT(u)->uio_offset
|
||||||
/* Extended uio fields */
|
#define zfs_uio_resid(u) GET_UIO_STRUCT(u)->uio_resid
|
||||||
enum xuio_type xu_type; /* What kind of uio structure? */
|
#define zfs_uio_iovcnt(u) GET_UIO_STRUCT(u)->uio_iovcnt
|
||||||
union {
|
#define zfs_uio_iovlen(u, idx) GET_UIO_STRUCT(u)->uio_iov[(idx)].iov_len
|
||||||
struct {
|
#define zfs_uio_iovbase(u, idx) GET_UIO_STRUCT(u)->uio_iov[(idx)].iov_base
|
||||||
int xu_zc_rw;
|
#define zfs_uio_td(u) GET_UIO_STRUCT(u)->uio_td
|
||||||
void *xu_zc_priv;
|
#define zfs_uio_rw(u) GET_UIO_STRUCT(u)->uio_rw
|
||||||
} xu_zc;
|
#define zfs_uio_fault_disable(u, set)
|
||||||
} xu_ext;
|
#define zfs_uio_prefaultpages(size, u) (0)
|
||||||
} xuio_t;
|
|
||||||
|
|
||||||
#define XUIO_XUZC_PRIV(xuio) xuio->xu_ext.xu_zc.xu_zc_priv
|
|
||||||
#define XUIO_XUZC_RW(xuio) xuio->xu_ext.xu_zc.xu_zc_rw
|
|
||||||
|
|
||||||
static __inline int
|
|
||||||
zfs_uiomove(void *cp, size_t n, enum uio_rw dir, uio_t *uio)
|
|
||||||
{
|
|
||||||
|
|
||||||
ASSERT(uio->uio_rw == dir);
|
|
||||||
return (uiomove(cp, (int)n, 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)
|
|
||||||
|
|
||||||
static inline void
|
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);
|
zfs_uio_offset(uio) = off;
|
||||||
*len = uio_iovlen(uio, idx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
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;
|
zfs_uio_resid(uio) -= size;
|
||||||
uio->uio_loffset += size;
|
zfs_uio_offset(uio) += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline offset_t
|
static __inline void
|
||||||
uio_index_at_offset(uio_t *uio, offset_t off, uint_t *vec_idx)
|
zfs_uio_init(zfs_uio_t *uio, struct uio *uio_s)
|
||||||
{
|
{
|
||||||
*vec_idx = 0;
|
GET_UIO_STRUCT(uio) = uio_s;
|
||||||
while (*vec_idx < uio_iovcnt(uio) && off >= uio_iovlen(uio, *vec_idx)) {
|
|
||||||
off -= uio_iovlen(uio, *vec_idx);
|
|
||||||
(*vec_idx)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (off);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int zfs_uio_fault_move(void *p, size_t n, zfs_uio_rw_t dir, zfs_uio_t *uio);
|
||||||
|
|
||||||
#endif /* !_STANDALONE */
|
#endif /* !_STANDALONE */
|
||||||
|
|
||||||
#endif /* !_OPENSOLARIS_SYS_UIO_H_ */
|
#endif /* !_OPENSOLARIS_SYS_UIO_H_ */
|
||||||
|
|
|
@ -59,6 +59,8 @@ enum symfollow { NO_FOLLOW = NOFOLLOW };
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <sys/filedesc.h>
|
#include <sys/filedesc.h>
|
||||||
#include <sys/syscallsubr.h>
|
#include <sys/syscallsubr.h>
|
||||||
|
#include <sys/vm.h>
|
||||||
|
#include <vm/vm_object.h>
|
||||||
|
|
||||||
typedef struct vop_vector vnodeops_t;
|
typedef struct vop_vector vnodeops_t;
|
||||||
#define VOP_FID VOP_VPTOFH
|
#define VOP_FID VOP_VPTOFH
|
||||||
|
@ -88,6 +90,22 @@ vn_is_readonly(vnode_t *vp)
|
||||||
#define vn_has_cached_data(vp) \
|
#define vn_has_cached_data(vp) \
|
||||||
((vp)->v_object != NULL && \
|
((vp)->v_object != NULL && \
|
||||||
(vp)->v_object->resident_page_count > 0)
|
(vp)->v_object->resident_page_count > 0)
|
||||||
|
|
||||||
|
static __inline void
|
||||||
|
vn_flush_cached_data(vnode_t *vp, boolean_t sync)
|
||||||
|
{
|
||||||
|
#if __FreeBSD_version > 1300054
|
||||||
|
if (vm_object_mightbedirty(vp->v_object)) {
|
||||||
|
#else
|
||||||
|
if (vp->v_object->flags & OBJ_MIGHTBEDIRTY) {
|
||||||
|
#endif
|
||||||
|
int flags = sync ? OBJPC_SYNC : 0;
|
||||||
|
zfs_vmobject_wlock(vp->v_object);
|
||||||
|
vm_object_page_clean(vp->v_object, 0, 0, flags);
|
||||||
|
zfs_vmobject_wunlock(vp->v_object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define vn_exists(vp) do { } while (0)
|
#define vn_exists(vp) do { } while (0)
|
||||||
#define vn_invalid(vp) do { } while (0)
|
#define vn_invalid(vp) do { } while (0)
|
||||||
#define vn_renamepath(tdvp, svp, tnm, lentnm) do { } while (0)
|
#define vn_renamepath(tdvp, svp, tnm, lentnm) do { } while (0)
|
||||||
|
|
|
@ -92,7 +92,7 @@ int freebsd_crypt_newsession(freebsd_crypt_session_t *sessp,
|
||||||
void freebsd_crypt_freesession(freebsd_crypt_session_t *sessp);
|
void freebsd_crypt_freesession(freebsd_crypt_session_t *sessp);
|
||||||
|
|
||||||
int freebsd_crypt_uio(boolean_t, freebsd_crypt_session_t *,
|
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);
|
size_t, size_t);
|
||||||
|
|
||||||
#endif /* _ZFS_FREEBSD_CRYPTO_H */
|
#endif /* _ZFS_FREEBSD_CRYPTO_H */
|
||||||
|
|
|
@ -42,7 +42,6 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
#define cond_resched() kern_yield(PRI_USER)
|
#define cond_resched() kern_yield(PRI_USER)
|
||||||
#define uio_prefaultpages(size, uio) (0)
|
|
||||||
|
|
||||||
#define taskq_create_sysdc(a, b, d, e, p, dc, f) \
|
#define taskq_create_sysdc(a, b, d, e, p, dc, f) \
|
||||||
(taskq_create(a, b, maxclsyspri, d, e, f))
|
(taskq_create(a, b, maxclsyspri, d, e, f))
|
||||||
|
|
|
@ -27,6 +27,10 @@
|
||||||
#ifndef _SYS_FS_ZFS_VFSOPS_H
|
#ifndef _SYS_FS_ZFS_VFSOPS_H
|
||||||
#define _SYS_FS_ZFS_VFSOPS_H
|
#define _SYS_FS_ZFS_VFSOPS_H
|
||||||
|
|
||||||
|
#if __FreeBSD_version >= 1300125
|
||||||
|
#define TEARDOWN_RMS
|
||||||
|
#endif
|
||||||
|
|
||||||
#if __FreeBSD_version >= 1300109
|
#if __FreeBSD_version >= 1300109
|
||||||
#define TEARDOWN_INACTIVE_RMS
|
#define TEARDOWN_INACTIVE_RMS
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,10 +50,16 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TEARDOWN_INACTIVE_RMS
|
#ifdef TEARDOWN_RMS
|
||||||
typedef struct rmslock zfs_teardown_lock_t;
|
typedef struct rmslock zfs_teardown_lock_t;
|
||||||
#else
|
#else
|
||||||
#define zfs_teardown_lock_t krwlock_t
|
#define zfs_teardown_lock_t rrmlock_t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEARDOWN_INACTIVE_RMS
|
||||||
|
typedef struct rmslock zfs_teardown_inactive_lock_t;
|
||||||
|
#else
|
||||||
|
#define zfs_teardown_inactive_lock_t krwlock_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct zfsvfs zfsvfs_t;
|
typedef struct zfsvfs zfsvfs_t;
|
||||||
|
@ -80,8 +90,8 @@ struct zfsvfs {
|
||||||
int z_norm; /* normalization flags */
|
int z_norm; /* normalization flags */
|
||||||
boolean_t z_atime; /* enable atimes mount option */
|
boolean_t z_atime; /* enable atimes mount option */
|
||||||
boolean_t z_unmounted; /* unmounted */
|
boolean_t z_unmounted; /* unmounted */
|
||||||
rrmlock_t z_teardown_lock;
|
zfs_teardown_lock_t z_teardown_lock;
|
||||||
zfs_teardown_lock_t z_teardown_inactive_lock;
|
zfs_teardown_inactive_lock_t z_teardown_inactive_lock;
|
||||||
list_t z_all_znodes; /* all vnodes in the fs */
|
list_t z_all_znodes; /* all vnodes in the fs */
|
||||||
uint64_t z_nr_znodes; /* number of znodes in the fs */
|
uint64_t z_nr_znodes; /* number of znodes in the fs */
|
||||||
kmutex_t z_znodes_lock; /* lock for z_all_znodes */
|
kmutex_t z_znodes_lock; /* lock for z_all_znodes */
|
||||||
|
@ -112,53 +122,121 @@ struct zfsvfs {
|
||||||
struct task z_unlinked_drain_task;
|
struct task z_unlinked_drain_task;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef TEARDOWN_RMS
|
||||||
|
#define ZFS_TEARDOWN_INIT(zfsvfs) \
|
||||||
|
rms_init(&(zfsvfs)->z_teardown_lock, "zfs teardown")
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_DESTROY(zfsvfs) \
|
||||||
|
rms_destroy(&(zfsvfs)->z_teardown_lock)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_TRY_ENTER_READ(zfsvfs) \
|
||||||
|
rms_try_rlock(&(zfsvfs)->z_teardown_lock)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_ENTER_READ(zfsvfs, tag) \
|
||||||
|
rms_rlock(&(zfsvfs)->z_teardown_lock);
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_EXIT_READ(zfsvfs, tag) \
|
||||||
|
rms_runlock(&(zfsvfs)->z_teardown_lock)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_ENTER_WRITE(zfsvfs, tag) \
|
||||||
|
rms_wlock(&(zfsvfs)->z_teardown_lock)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_EXIT_WRITE(zfsvfs) \
|
||||||
|
rms_wunlock(&(zfsvfs)->z_teardown_lock)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_EXIT(zfsvfs, tag) \
|
||||||
|
rms_unlock(&(zfsvfs)->z_teardown_lock)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_READ_HELD(zfsvfs) \
|
||||||
|
rms_rowned(&(zfsvfs)->z_teardown_lock)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_WRITE_HELD(zfsvfs) \
|
||||||
|
rms_wowned(&(zfsvfs)->z_teardown_lock)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_HELD(zfsvfs) \
|
||||||
|
rms_owned_any(&(zfsvfs)->z_teardown_lock)
|
||||||
|
#else
|
||||||
|
#define ZFS_TEARDOWN_INIT(zfsvfs) \
|
||||||
|
rrm_init(&(zfsvfs)->z_teardown_lock, B_FALSE)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_DESTROY(zfsvfs) \
|
||||||
|
rrm_destroy(&(zfsvfs)->z_teardown_lock)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_TRY_ENTER_READ(zfsvfs) \
|
||||||
|
rw_tryenter(&(zfsvfs)->z_teardown_lock, RW_READER)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_ENTER_READ(zfsvfs, tag) \
|
||||||
|
rrm_enter_read(&(zfsvfs)->z_teardown_lock, tag);
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_EXIT_READ(zfsvfs, tag) \
|
||||||
|
rrm_exit(&(zfsvfs)->z_teardown_lock, tag)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_ENTER_WRITE(zfsvfs, tag) \
|
||||||
|
rrm_enter(&(zfsvfs)->z_teardown_lock, RW_WRITER, tag)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_EXIT_WRITE(zfsvfs) \
|
||||||
|
rrm_exit(&(zfsvfs)->z_teardown_lock, tag)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_EXIT(zfsvfs, tag) \
|
||||||
|
rrm_exit(&(zfsvfs)->z_teardown_lock, tag)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_READ_HELD(zfsvfs) \
|
||||||
|
RRM_READ_HELD(&(zfsvfs)->z_teardown_lock)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_WRITE_HELD(zfsvfs) \
|
||||||
|
RRM_WRITE_HELD(&(zfsvfs)->z_teardown_lock)
|
||||||
|
|
||||||
|
#define ZFS_TEARDOWN_HELD(zfsvfs) \
|
||||||
|
RRM_LOCK_HELD(&(zfsvfs)->z_teardown_lock)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef TEARDOWN_INACTIVE_RMS
|
#ifdef TEARDOWN_INACTIVE_RMS
|
||||||
#define ZFS_INIT_TEARDOWN_INACTIVE(zfsvfs) \
|
#define ZFS_TEARDOWN_INACTIVE_INIT(zfsvfs) \
|
||||||
rms_init(&(zfsvfs)->z_teardown_inactive_lock, "zfs teardown inactive")
|
rms_init(&(zfsvfs)->z_teardown_inactive_lock, "zfs teardown inactive")
|
||||||
|
|
||||||
#define ZFS_DESTROY_TEARDOWN_INACTIVE(zfsvfs) \
|
#define ZFS_TEARDOWN_INACTIVE_DESTROY(zfsvfs) \
|
||||||
rms_destroy(&(zfsvfs)->z_teardown_inactive_lock)
|
rms_destroy(&(zfsvfs)->z_teardown_inactive_lock)
|
||||||
|
|
||||||
#define ZFS_TRYRLOCK_TEARDOWN_INACTIVE(zfsvfs) \
|
#define ZFS_TEARDOWN_INACTIVE_TRY_ENTER_READ(zfsvfs) \
|
||||||
rms_try_rlock(&(zfsvfs)->z_teardown_inactive_lock)
|
rms_try_rlock(&(zfsvfs)->z_teardown_inactive_lock)
|
||||||
|
|
||||||
#define ZFS_RLOCK_TEARDOWN_INACTIVE(zfsvfs) \
|
#define ZFS_TEARDOWN_INACTIVE_ENTER_READ(zfsvfs) \
|
||||||
rms_rlock(&(zfsvfs)->z_teardown_inactive_lock)
|
rms_rlock(&(zfsvfs)->z_teardown_inactive_lock)
|
||||||
|
|
||||||
#define ZFS_RUNLOCK_TEARDOWN_INACTIVE(zfsvfs) \
|
#define ZFS_TEARDOWN_INACTIVE_EXIT_READ(zfsvfs) \
|
||||||
rms_runlock(&(zfsvfs)->z_teardown_inactive_lock)
|
rms_runlock(&(zfsvfs)->z_teardown_inactive_lock)
|
||||||
|
|
||||||
#define ZFS_WLOCK_TEARDOWN_INACTIVE(zfsvfs) \
|
#define ZFS_TEARDOWN_INACTIVE_ENTER_WRITE(zfsvfs) \
|
||||||
rms_wlock(&(zfsvfs)->z_teardown_inactive_lock)
|
rms_wlock(&(zfsvfs)->z_teardown_inactive_lock)
|
||||||
|
|
||||||
#define ZFS_WUNLOCK_TEARDOWN_INACTIVE(zfsvfs) \
|
#define ZFS_TEARDOWN_INACTIVE_EXIT_WRITE(zfsvfs) \
|
||||||
rms_wunlock(&(zfsvfs)->z_teardown_inactive_lock)
|
rms_wunlock(&(zfsvfs)->z_teardown_inactive_lock)
|
||||||
|
|
||||||
#define ZFS_TEARDOWN_INACTIVE_WLOCKED(zfsvfs) \
|
#define ZFS_TEARDOWN_INACTIVE_WRITE_HELD(zfsvfs) \
|
||||||
rms_wowned(&(zfsvfs)->z_teardown_inactive_lock)
|
rms_wowned(&(zfsvfs)->z_teardown_inactive_lock)
|
||||||
#else
|
#else
|
||||||
#define ZFS_INIT_TEARDOWN_INACTIVE(zfsvfs) \
|
#define ZFS_TEARDOWN_INACTIVE_INIT(zfsvfs) \
|
||||||
rw_init(&(zfsvfs)->z_teardown_inactive_lock, NULL, RW_DEFAULT, NULL)
|
rw_init(&(zfsvfs)->z_teardown_inactive_lock, NULL, RW_DEFAULT, NULL)
|
||||||
|
|
||||||
#define ZFS_DESTROY_TEARDOWN_INACTIVE(zfsvfs) \
|
#define ZFS_TEARDOWN_INACTIVE_DESTROY(zfsvfs) \
|
||||||
rw_destroy(&(zfsvfs)->z_teardown_inactive_lock)
|
rw_destroy(&(zfsvfs)->z_teardown_inactive_lock)
|
||||||
|
|
||||||
#define ZFS_TRYRLOCK_TEARDOWN_INACTIVE(zfsvfs) \
|
#define ZFS_TEARDOWN_INACTIVE_TRY_ENTER_READ(zfsvfs) \
|
||||||
rw_tryenter(&(zfsvfs)->z_teardown_inactive_lock, RW_READER)
|
rw_tryenter(&(zfsvfs)->z_teardown_inactive_lock, RW_READER)
|
||||||
|
|
||||||
#define ZFS_RLOCK_TEARDOWN_INACTIVE(zfsvfs) \
|
#define ZFS_TEARDOWN_INACTIVE_ENTER_READ(zfsvfs) \
|
||||||
rw_enter(&(zfsvfs)->z_teardown_inactive_lock, RW_READER)
|
rw_enter(&(zfsvfs)->z_teardown_inactive_lock, RW_READER)
|
||||||
|
|
||||||
#define ZFS_RUNLOCK_TEARDOWN_INACTIVE(zfsvfs) \
|
#define ZFS_TEARDOWN_INACTIVE_EXIT_READ(zfsvfs) \
|
||||||
rw_exit(&(zfsvfs)->z_teardown_inactive_lock)
|
rw_exit(&(zfsvfs)->z_teardown_inactive_lock)
|
||||||
|
|
||||||
#define ZFS_WLOCK_TEARDOWN_INACTIVE(zfsvfs) \
|
#define ZFS_TEARDOWN_INACTIVE_ENTER_WRITE(zfsvfs) \
|
||||||
rw_enter(&(zfsvfs)->z_teardown_inactive_lock, RW_WRITER)
|
rw_enter(&(zfsvfs)->z_teardown_inactive_lock, RW_WRITER)
|
||||||
|
|
||||||
#define ZFS_WUNLOCK_TEARDOWN_INACTIVE(zfsvfs) \
|
#define ZFS_TEARDOWN_INACTIVE_EXIT_WRITE(zfsvfs) \
|
||||||
rw_exit(&(zfsvfs)->z_teardown_inactive_lock)
|
rw_exit(&(zfsvfs)->z_teardown_inactive_lock)
|
||||||
|
|
||||||
#define ZFS_TEARDOWN_INACTIVE_WLOCKED(zfsvfs) \
|
#define ZFS_TEARDOWN_INACTIVE_WRITE_HELD(zfsvfs) \
|
||||||
RW_WRITE_HELD(&(zfsvfs)->z_teardown_inactive_lock)
|
RW_WRITE_HELD(&(zfsvfs)->z_teardown_inactive_lock)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <sys/zil.h>
|
#include <sys/zil.h>
|
||||||
#include <sys/zfs_project.h>
|
#include <sys/zfs_project.h>
|
||||||
#include <vm/vm_object.h>
|
#include <vm/vm_object.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -117,24 +118,26 @@ extern minor_t zfsdev_minor_alloc(void);
|
||||||
#define Z_ISDIR(type) ((type) == VDIR)
|
#define Z_ISDIR(type) ((type) == VDIR)
|
||||||
|
|
||||||
#define zn_has_cached_data(zp) vn_has_cached_data(ZTOV(zp))
|
#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_flush_cached_data(zp, sync) vn_flush_cached_data(ZTOV(zp), sync)
|
||||||
|
#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 */
|
/* Called on entry to each ZFS vnode and vfs operation */
|
||||||
#define ZFS_ENTER(zfsvfs) \
|
#define ZFS_ENTER(zfsvfs) \
|
||||||
{ \
|
{ \
|
||||||
rrm_enter_read(&(zfsvfs)->z_teardown_lock, FTAG); \
|
ZFS_TEARDOWN_ENTER_READ((zfsvfs), FTAG); \
|
||||||
if ((zfsvfs)->z_unmounted) { \
|
if (__predict_false((zfsvfs)->z_unmounted)) { \
|
||||||
ZFS_EXIT(zfsvfs); \
|
ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG); \
|
||||||
return (EIO); \
|
return (EIO); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Must be called before exiting the vop */
|
/* Must be called before exiting the vop */
|
||||||
#define ZFS_EXIT(zfsvfs) rrm_exit(&(zfsvfs)->z_teardown_lock, FTAG)
|
#define ZFS_EXIT(zfsvfs) ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG)
|
||||||
|
|
||||||
/* Verifies the znode is valid */
|
/* Verifies the znode is valid */
|
||||||
#define ZFS_VERIFY_ZP(zp) \
|
#define ZFS_VERIFY_ZP(zp) \
|
||||||
if ((zp)->z_sa_hdl == NULL) { \
|
if (__predict_false((zp)->z_sa_hdl == NULL)) { \
|
||||||
ZFS_EXIT((zp)->z_zfsvfs); \
|
ZFS_EXIT((zp)->z_zfsvfs); \
|
||||||
return (EIO); \
|
return (EIO); \
|
||||||
} \
|
} \
|
||||||
|
@ -173,7 +176,6 @@ extern void zfs_tstamp_update_setup_ext(struct znode *,
|
||||||
uint_t, uint64_t [2], uint64_t [2], boolean_t have_tx);
|
uint_t, uint64_t [2], uint64_t [2], boolean_t have_tx);
|
||||||
extern void zfs_znode_free(struct znode *);
|
extern void zfs_znode_free(struct znode *);
|
||||||
|
|
||||||
extern zil_get_data_t zfs_get_data;
|
|
||||||
extern zil_replay_func_t *zfs_replay_vector[TX_MAX_TYPE];
|
extern zil_replay_func_t *zfs_replay_vector[TX_MAX_TYPE];
|
||||||
extern int zfsfstype;
|
extern int zfsfstype;
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,9 @@
|
||||||
#define _ZFS_BLKDEV_H
|
#define _ZFS_BLKDEV_H
|
||||||
|
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
#include <linux/elevator.h>
|
|
||||||
#include <linux/backing-dev.h>
|
#include <linux/backing-dev.h>
|
||||||
#include <linux/hdreg.h>
|
#include <linux/hdreg.h>
|
||||||
|
#include <linux/major.h>
|
||||||
#include <linux/msdos_fs.h> /* for SECTOR_* */
|
#include <linux/msdos_fs.h> /* for SECTOR_* */
|
||||||
|
|
||||||
#ifndef HAVE_BLK_QUEUE_FLAG_SET
|
#ifndef HAVE_BLK_QUEUE_FLAG_SET
|
||||||
|
@ -92,11 +92,14 @@ blk_queue_set_write_cache(struct request_queue *q, bool wc, bool fua)
|
||||||
static inline void
|
static inline void
|
||||||
blk_queue_set_read_ahead(struct request_queue *q, unsigned long ra_pages)
|
blk_queue_set_read_ahead(struct request_queue *q, unsigned long ra_pages)
|
||||||
{
|
{
|
||||||
|
#if !defined(HAVE_BLK_QUEUE_UPDATE_READAHEAD) && \
|
||||||
|
!defined(HAVE_DISK_UPDATE_READAHEAD)
|
||||||
#ifdef HAVE_BLK_QUEUE_BDI_DYNAMIC
|
#ifdef HAVE_BLK_QUEUE_BDI_DYNAMIC
|
||||||
q->backing_dev_info->ra_pages = ra_pages;
|
q->backing_dev_info->ra_pages = ra_pages;
|
||||||
#else
|
#else
|
||||||
q->backing_dev_info.ra_pages = ra_pages;
|
q->backing_dev_info.ra_pages = ra_pages;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_BIO_BVEC_ITER
|
#ifdef HAVE_BIO_BVEC_ITER
|
||||||
|
@ -277,18 +280,22 @@ bio_set_bi_error(struct bio *bio, int error)
|
||||||
static inline int
|
static inline int
|
||||||
zfs_check_media_change(struct block_device *bdev)
|
zfs_check_media_change(struct block_device *bdev)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK
|
||||||
struct gendisk *gd = bdev->bd_disk;
|
struct gendisk *gd = bdev->bd_disk;
|
||||||
const struct block_device_operations *bdo = gd->fops;
|
const struct block_device_operations *bdo = gd->fops;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!bdev_check_media_change(bdev))
|
if (!bdev_check_media_change(bdev))
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
#ifdef HAVE_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK
|
||||||
/*
|
/*
|
||||||
* Force revalidation, to mimic the old behavior of
|
* Force revalidation, to mimic the old behavior of
|
||||||
* check_disk_change()
|
* check_disk_change()
|
||||||
*/
|
*/
|
||||||
if (bdo->revalidate_disk)
|
if (bdo->revalidate_disk)
|
||||||
bdo->revalidate_disk(gd);
|
bdo->revalidate_disk(gd);
|
||||||
|
#endif
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -520,7 +527,9 @@ blk_generic_start_io_acct(struct request_queue *q __attribute__((unused)),
|
||||||
struct gendisk *disk __attribute__((unused)),
|
struct gendisk *disk __attribute__((unused)),
|
||||||
int rw __attribute__((unused)), struct bio *bio)
|
int rw __attribute__((unused)), struct bio *bio)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_BIO_IO_ACCT)
|
#if defined(HAVE_DISK_IO_ACCT)
|
||||||
|
return (disk_start_io_acct(disk, bio_sectors(bio), bio_op(bio)));
|
||||||
|
#elif defined(HAVE_BIO_IO_ACCT)
|
||||||
return (bio_start_io_acct(bio));
|
return (bio_start_io_acct(bio));
|
||||||
#elif defined(HAVE_GENERIC_IO_ACCT_3ARG)
|
#elif defined(HAVE_GENERIC_IO_ACCT_3ARG)
|
||||||
unsigned long start_time = jiffies;
|
unsigned long start_time = jiffies;
|
||||||
|
@ -541,7 +550,9 @@ blk_generic_end_io_acct(struct request_queue *q __attribute__((unused)),
|
||||||
struct gendisk *disk __attribute__((unused)),
|
struct gendisk *disk __attribute__((unused)),
|
||||||
int rw __attribute__((unused)), struct bio *bio, unsigned long start_time)
|
int rw __attribute__((unused)), struct bio *bio, unsigned long start_time)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_BIO_IO_ACCT)
|
#if defined(HAVE_DISK_IO_ACCT)
|
||||||
|
disk_end_io_acct(disk, bio_op(bio), start_time);
|
||||||
|
#elif defined(HAVE_BIO_IO_ACCT)
|
||||||
bio_end_io_acct(bio, start_time);
|
bio_end_io_acct(bio, start_time);
|
||||||
#elif defined(HAVE_GENERIC_IO_ACCT_3ARG)
|
#elif defined(HAVE_GENERIC_IO_ACCT_3ARG)
|
||||||
generic_end_io_acct(rw, &disk->part0, start_time);
|
generic_end_io_acct(rw, &disk->part0, start_time);
|
||||||
|
|
|
@ -28,6 +28,14 @@
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
|
#if !defined(fallthrough)
|
||||||
|
#if defined(HAVE_IMPLICIT_FALLTHROUGH)
|
||||||
|
#define fallthrough __attribute__((__fallthrough__))
|
||||||
|
#else
|
||||||
|
#define fallthrough ((void)0)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(READ_ONCE)
|
#if !defined(READ_ONCE)
|
||||||
#define READ_ONCE(x) ACCESS_ONCE(x)
|
#define READ_ONCE(x) ACCESS_ONCE(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -88,6 +88,9 @@
|
||||||
#if defined(HAVE_KERNEL_FPU_API_HEADER)
|
#if defined(HAVE_KERNEL_FPU_API_HEADER)
|
||||||
#include <asm/fpu/api.h>
|
#include <asm/fpu/api.h>
|
||||||
#include <asm/fpu/internal.h>
|
#include <asm/fpu/internal.h>
|
||||||
|
#if defined(HAVE_KERNEL_FPU_XCR_HEADER)
|
||||||
|
#include <asm/fpu/xcr.h>
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#include <asm/i387.h>
|
#include <asm/i387.h>
|
||||||
#include <asm/xcr.h>
|
#include <asm/xcr.h>
|
||||||
|
|
|
@ -343,7 +343,8 @@ static inline void zfs_gid_write(struct inode *ip, gid_t gid)
|
||||||
/*
|
/*
|
||||||
* 4.9 API change
|
* 4.9 API change
|
||||||
*/
|
*/
|
||||||
#ifndef HAVE_SETATTR_PREPARE
|
#if !(defined(HAVE_SETATTR_PREPARE_NO_USERNS) || \
|
||||||
|
defined(HAVE_SETATTR_PREPARE_USERNS))
|
||||||
static inline int
|
static inline int
|
||||||
setattr_prepare(struct dentry *dentry, struct iattr *ia)
|
setattr_prepare(struct dentry *dentry, struct iattr *ia)
|
||||||
{
|
{
|
||||||
|
@ -389,6 +390,15 @@ func(const struct path *path, struct kstat *stat, u32 request_mask, \
|
||||||
{ \
|
{ \
|
||||||
return (func##_impl(path, stat, request_mask, query_flags)); \
|
return (func##_impl(path, stat, request_mask, query_flags)); \
|
||||||
}
|
}
|
||||||
|
#elif defined(HAVE_USERNS_IOPS_GETATTR)
|
||||||
|
#define ZPL_GETATTR_WRAPPER(func) \
|
||||||
|
static int \
|
||||||
|
func(struct user_namespace *user_ns, const struct path *path, \
|
||||||
|
struct kstat *stat, u32 request_mask, unsigned int query_flags) \
|
||||||
|
{ \
|
||||||
|
return (func##_impl(user_ns, path, stat, request_mask, \
|
||||||
|
query_flags)); \
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#error
|
#error
|
||||||
#endif
|
#endif
|
||||||
|
@ -436,4 +446,16 @@ zpl_is_32bit_api(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 5.12 API change
|
||||||
|
* To support id-mapped mounts, generic_fillattr() was modified to
|
||||||
|
* accept a new struct user_namespace* as its first arg.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_GENERIC_FILLATTR_USERNS
|
||||||
|
#define zpl_generic_fillattr(user_ns, ip, sp) \
|
||||||
|
generic_fillattr(user_ns, ip, sp)
|
||||||
|
#else
|
||||||
|
#define zpl_generic_fillattr(user_ns, ip, sp) generic_fillattr(ip, sp)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _ZFS_VFS_H */
|
#endif /* _ZFS_VFS_H */
|
||||||
|
|
|
@ -119,12 +119,27 @@ fn(struct dentry *dentry, const char *name, void *buffer, size_t size, \
|
||||||
#error "Unsupported kernel"
|
#error "Unsupported kernel"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 5.12 API change,
|
||||||
|
* The xattr_handler->set() callback was changed to take the
|
||||||
|
* struct user_namespace* as the first arg, to support idmapped
|
||||||
|
* mounts.
|
||||||
|
*/
|
||||||
|
#if defined(HAVE_XATTR_SET_USERNS)
|
||||||
|
#define ZPL_XATTR_SET_WRAPPER(fn) \
|
||||||
|
static int \
|
||||||
|
fn(const struct xattr_handler *handler, struct user_namespace *user_ns, \
|
||||||
|
struct dentry *dentry, struct inode *inode, const char *name, \
|
||||||
|
const void *buffer, size_t size, int flags) \
|
||||||
|
{ \
|
||||||
|
return (__ ## fn(inode, name, buffer, size, flags)); \
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* 4.7 API change,
|
* 4.7 API change,
|
||||||
* The xattr_handler->set() callback was changed to take a both dentry and
|
* The xattr_handler->set() callback was changed to take a both dentry and
|
||||||
* inode, because the dentry might not be attached to an inode yet.
|
* inode, because the dentry might not be attached to an inode yet.
|
||||||
*/
|
*/
|
||||||
#if defined(HAVE_XATTR_SET_DENTRY_INODE)
|
#elif defined(HAVE_XATTR_SET_DENTRY_INODE)
|
||||||
#define ZPL_XATTR_SET_WRAPPER(fn) \
|
#define ZPL_XATTR_SET_WRAPPER(fn) \
|
||||||
static int \
|
static int \
|
||||||
fn(const struct xattr_handler *handler, struct dentry *dentry, \
|
fn(const struct xattr_handler *handler, struct dentry *dentry, \
|
||||||
|
|
|
@ -24,7 +24,11 @@
|
||||||
#ifndef _SPL_CMN_ERR_H
|
#ifndef _SPL_CMN_ERR_H
|
||||||
#define _SPL_CMN_ERR_H
|
#define _SPL_CMN_ERR_H
|
||||||
|
|
||||||
|
#if defined(_KERNEL) && defined(HAVE_STANDALONE_LINUX_STDARG)
|
||||||
|
#include <linux/stdarg.h>
|
||||||
|
#else
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CE_CONT 0 /* continuation */
|
#define CE_CONT 0 /* continuation */
|
||||||
#define CE_NOTE 1 /* notice */
|
#define CE_NOTE 1 /* notice */
|
||||||
|
|
|
@ -68,9 +68,9 @@ void spl_dumpstack(void);
|
||||||
"%s", "VERIFY(" #cond ") failed\n"))
|
"%s", "VERIFY(" #cond ") failed\n"))
|
||||||
|
|
||||||
#define VERIFY3B(LEFT, OP, RIGHT) do { \
|
#define VERIFY3B(LEFT, OP, RIGHT) do { \
|
||||||
boolean_t _verify3_left = (boolean_t)(LEFT); \
|
const boolean_t _verify3_left = (boolean_t)(LEFT); \
|
||||||
boolean_t _verify3_right = (boolean_t)(RIGHT); \
|
const boolean_t _verify3_right = (boolean_t)(RIGHT);\
|
||||||
if (!(_verify3_left OP _verify3_right)) \
|
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||||
"failed (%d " #OP " %d)\n", \
|
"failed (%d " #OP " %d)\n", \
|
||||||
|
@ -79,9 +79,9 @@ void spl_dumpstack(void);
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define VERIFY3S(LEFT, OP, RIGHT) do { \
|
#define VERIFY3S(LEFT, OP, RIGHT) do { \
|
||||||
int64_t _verify3_left = (int64_t)(LEFT); \
|
const int64_t _verify3_left = (int64_t)(LEFT); \
|
||||||
int64_t _verify3_right = (int64_t)(RIGHT); \
|
const int64_t _verify3_right = (int64_t)(RIGHT); \
|
||||||
if (!(_verify3_left OP _verify3_right)) \
|
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||||
"failed (%lld " #OP " %lld)\n", \
|
"failed (%lld " #OP " %lld)\n", \
|
||||||
|
@ -90,9 +90,9 @@ void spl_dumpstack(void);
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define VERIFY3U(LEFT, OP, RIGHT) do { \
|
#define VERIFY3U(LEFT, OP, RIGHT) do { \
|
||||||
uint64_t _verify3_left = (uint64_t)(LEFT); \
|
const uint64_t _verify3_left = (uint64_t)(LEFT); \
|
||||||
uint64_t _verify3_right = (uint64_t)(RIGHT); \
|
const uint64_t _verify3_right = (uint64_t)(RIGHT); \
|
||||||
if (!(_verify3_left OP _verify3_right)) \
|
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||||
"failed (%llu " #OP " %llu)\n", \
|
"failed (%llu " #OP " %llu)\n", \
|
||||||
|
@ -101,9 +101,9 @@ void spl_dumpstack(void);
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define VERIFY3P(LEFT, OP, RIGHT) do { \
|
#define VERIFY3P(LEFT, OP, RIGHT) do { \
|
||||||
uintptr_t _verify3_left = (uintptr_t)(LEFT); \
|
const uintptr_t _verify3_left = (uintptr_t)(LEFT); \
|
||||||
uintptr_t _verify3_right = (uintptr_t)(RIGHT); \
|
const uintptr_t _verify3_right = (uintptr_t)(RIGHT);\
|
||||||
if (!(_verify3_left OP _verify3_right)) \
|
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||||
"failed (%px " #OP " %px)\n", \
|
"failed (%px " #OP " %px)\n", \
|
||||||
|
@ -112,9 +112,9 @@ void spl_dumpstack(void);
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define VERIFY0(RIGHT) do { \
|
#define VERIFY0(RIGHT) do { \
|
||||||
int64_t _verify3_left = (int64_t)(0); \
|
const int64_t _verify3_left = (int64_t)(0); \
|
||||||
int64_t _verify3_right = (int64_t)(RIGHT); \
|
const int64_t _verify3_right = (int64_t)(RIGHT); \
|
||||||
if (!(_verify3_left == _verify3_right)) \
|
if (unlikely(!(_verify3_left == _verify3_right))) \
|
||||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
"VERIFY3(0 == " #RIGHT ") " \
|
"VERIFY3(0 == " #RIGHT ") " \
|
||||||
"failed (0 == %lld)\n", \
|
"failed (0 == %lld)\n", \
|
||||||
|
@ -154,11 +154,11 @@ void spl_dumpstack(void);
|
||||||
#define ASSERT0 VERIFY0
|
#define ASSERT0 VERIFY0
|
||||||
#define ASSERT VERIFY
|
#define ASSERT VERIFY
|
||||||
#define IMPLY(A, B) \
|
#define IMPLY(A, B) \
|
||||||
((void)(((!(A)) || (B)) || \
|
((void)(likely((!(A)) || (B)) || \
|
||||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
"(" #A ") implies (" #B ")")))
|
"(" #A ") implies (" #B ")")))
|
||||||
#define EQUIV(A, B) \
|
#define EQUIV(A, B) \
|
||||||
((void)((!!(A) == !!(B)) || \
|
((void)(likely(!!(A) == !!(B)) || \
|
||||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
"(" #A ") is equivalent to (" #B ")")))
|
"(" #A ") is equivalent to (" #B ")")))
|
||||||
/* END CSTYLED */
|
/* END CSTYLED */
|
||||||
|
|
|
@ -33,22 +33,6 @@
|
||||||
#define FORREAL 0 /* Usual side-effects */
|
#define FORREAL 0 /* Usual side-effects */
|
||||||
#define JUSTLOOKING 1 /* Don't stop the process */
|
#define JUSTLOOKING 1 /* Don't stop the process */
|
||||||
|
|
||||||
/*
|
extern int issig(int why);
|
||||||
* The "why" argument indicates the allowable side-effects of the call:
|
|
||||||
*
|
|
||||||
* FORREAL: Extract the next pending signal from p_sig into p_cursig;
|
|
||||||
* stop the process if a stop has been requested or if a traced signal
|
|
||||||
* is pending.
|
|
||||||
*
|
|
||||||
* JUSTLOOKING: Don't stop the process, just indicate whether or not
|
|
||||||
* a signal might be pending (FORREAL is needed to tell for sure).
|
|
||||||
*/
|
|
||||||
static __inline__ int
|
|
||||||
issig(int why)
|
|
||||||
{
|
|
||||||
ASSERT(why == FORREAL || why == JUSTLOOKING);
|
|
||||||
|
|
||||||
return (signal_pending(current));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SPL_SIGNAL_H */
|
#endif /* SPL_SIGNAL_H */
|
||||||
|
|
|
@ -70,4 +70,17 @@ extern struct task_struct *spl_kthread_create(int (*func)(void *),
|
||||||
|
|
||||||
extern proc_t p0;
|
extern proc_t p0;
|
||||||
|
|
||||||
|
#ifdef HAVE_SIGINFO
|
||||||
|
typedef kernel_siginfo_t spl_kernel_siginfo_t;
|
||||||
|
#else
|
||||||
|
typedef siginfo_t spl_kernel_siginfo_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SET_SPECIAL_STATE
|
||||||
|
#define spl_set_special_state(x) set_special_state((x))
|
||||||
|
#else
|
||||||
|
#define spl_set_special_state(x) __set_current_state((x))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* _SPL_THREAD_H */
|
#endif /* _SPL_THREAD_H */
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue