Notable upstream pull request merges:
  #12321 Fix inflated quiesce time caused by lwb_tx during zil_commit()
  #13244 zstd early abort
  #13360 Verify BPs as part of spa_load_verify_cb()
  #13452 More speculative prefetcher improvements
  #13466 Expose zpool guids through kstats
  #13476 Refactor Log Size Limit
  #13484 FreeBSD: libspl: Add locking around statfs globals
  #13498 Cancel in-progress rebuilds when we finish removal
  #13499 zed: Take no action on scrub/resilver checksum errors
  #13513 Remove wrong assertion in log spacemap

Obtained from:	OpenZFS
OpenZFS commit:	b9d98453f9
This commit is contained in:
Martin Matuska 2022-06-03 17:58:39 +02:00
commit e3aa18ad71
121 changed files with 2621 additions and 2601 deletions

View file

@ -24,7 +24,7 @@ CFLAGS+= -include ${SRCTOP}/sys/contrib/openzfs/include/os/freebsd/spl/sys/ccomp
CFLAGS+= -I${SRCTOP}/cddl/usr.sbin
# use issetugid(2)
CFLAGS+= -D_MACHINE_FLOAT_H_ -DHAVE_ISSETUGID
CFLAGS+= -DHAVE_ISSETUGID
LIBADD+= devdctl zfs util geom bsdxml sbuf nvpair avl uutil zutil

View file

@ -84,7 +84,7 @@ CFLAGS.zstd_decompress.c= -U__BMI__
CFLAGS.zstd_decompress.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL}
CFLAGS.zstd_decompress_block.c= -U__BMI__
CFLAGS.zstd_decompress_block.c+= ${NO_WBITWISE_INSTEAD_OF_LOGICAL}
CFLAGS.zstd_shim.c+= -DIN_BASE -I${OZFS}/include
CFLAGS.zstd_shim.c+= -DIN_BASE -DIN_LIBSA -I${OZFS}/include
# Do not unroll skein loops, reduce code size
CFLAGS.skein_block.c+= -DSKEIN_LOOP=111

View file

@ -28,7 +28,7 @@ jobs:
./autogen.sh
- name: Configure
run: |
./configure --enable-debug --enable-debuginfo --enable-asan --enable-ubsan
./configure --enable-debug --enable-debuginfo --enable-asan --enable-ubsan --with-config=dist
- name: Make
run: |
make -j$(nproc) --no-print-directory --silent pkg-utils pkg-kmod

View file

@ -24,7 +24,7 @@ jobs:
./autogen.sh
- name: Configure
run: |
./configure --enable-debug --enable-debuginfo --enable-asan --enable-ubsan
./configure --enable-debug --enable-debuginfo --enable-asan --enable-ubsan --with-config=dist
- name: Make
run: |
make -j$(nproc) --no-print-directory --silent pkg-utils pkg-kmod

View file

@ -23,7 +23,7 @@ jobs:
./autogen.sh
- name: Configure
run: |
./configure --enable-debug --enable-debuginfo --enable-asan --enable-ubsan
./configure --enable-debug --enable-debuginfo --enable-asan --enable-ubsan --with-config=dist
- name: Make
run: |
make -j$(nproc) --no-print-directory --silent pkg-utils pkg-kmod

View file

@ -6,5 +6,5 @@ Release: 1
Release-Tags: relext
License: CDDL
Author: OpenZFS
Linux-Maximum: 5.17
Linux-Maximum: 5.18
Linux-Minimum: 3.10

View file

@ -1,5 +1,5 @@
CLEANFILES =
EXTRA_DIST =
dist_noinst_DATA =
INSTALL_DATA_HOOKS =
ALL_LOCAL =
CLEAN_LOCAL =
@ -37,26 +37,26 @@ extradir = $(prefix)/src/zfs-$(VERSION)
extra_HEADERS = zfs.release.in zfs_config.h.in
endif
EXTRA_DIST += autogen.sh copy-builtin
EXTRA_DIST += AUTHORS CODE_OF_CONDUCT.md COPYRIGHT LICENSE META NEWS NOTICE
EXTRA_DIST += README.md RELEASES.md
EXTRA_DIST += module/lua/README.zfs module/os/linux/spl/README.md
dist_noinst_DATA += autogen.sh copy-builtin
dist_noinst_DATA += AUTHORS CODE_OF_CONDUCT.md COPYRIGHT LICENSE META NEWS NOTICE
dist_noinst_DATA += README.md RELEASES.md
dist_noinst_DATA += module/lua/README.zfs module/os/linux/spl/README.md
# Include all the extra licensing information for modules
EXTRA_DIST += module/icp/algs/skein/THIRDPARTYLICENSE
EXTRA_DIST += module/icp/algs/skein/THIRDPARTYLICENSE.descrip
EXTRA_DIST += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.gladman
EXTRA_DIST += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.gladman.descrip
EXTRA_DIST += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.openssl
EXTRA_DIST += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.openssl.descrip
EXTRA_DIST += module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.cryptogams
EXTRA_DIST += module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.cryptogams.descrip
EXTRA_DIST += module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.openssl
EXTRA_DIST += module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.openssl.descrip
EXTRA_DIST += module/os/linux/spl/THIRDPARTYLICENSE.gplv2
EXTRA_DIST += module/os/linux/spl/THIRDPARTYLICENSE.gplv2.descrip
EXTRA_DIST += module/zfs/THIRDPARTYLICENSE.cityhash
EXTRA_DIST += module/zfs/THIRDPARTYLICENSE.cityhash.descrip
dist_noinst_DATA += module/icp/algs/skein/THIRDPARTYLICENSE
dist_noinst_DATA += module/icp/algs/skein/THIRDPARTYLICENSE.descrip
dist_noinst_DATA += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.gladman
dist_noinst_DATA += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.gladman.descrip
dist_noinst_DATA += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.openssl
dist_noinst_DATA += module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.openssl.descrip
dist_noinst_DATA += module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.cryptogams
dist_noinst_DATA += module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.cryptogams.descrip
dist_noinst_DATA += module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.openssl
dist_noinst_DATA += module/icp/asm-x86_64/modes/THIRDPARTYLICENSE.openssl.descrip
dist_noinst_DATA += module/os/linux/spl/THIRDPARTYLICENSE.gplv2
dist_noinst_DATA += module/os/linux/spl/THIRDPARTYLICENSE.gplv2.descrip
dist_noinst_DATA += module/zfs/THIRDPARTYLICENSE.cityhash
dist_noinst_DATA += module/zfs/THIRDPARTYLICENSE.cityhash.descrip
@CODE_COVERAGE_RULES@
@ -170,6 +170,10 @@ flake8:
echo "skipping flake8 because flake8 is not installed"; \
fi
PHONY += regen-tests
regen-tests:
@$(MAKE) -C tests/zfs-tests/tests regen
PHONY += ctags
ctags:
$(RM) tags

View file

@ -10,7 +10,7 @@ mounthelper_PROGRAMS =
sbin_SCRIPTS += fsck.zfs
SHELLCHECKSCRIPTS += fsck.zfs
CLEANFILES += fsck.zfs
EXTRA_DIST += %D%/fsck.zfs.in
dist_noinst_DATA += %D%/fsck.zfs.in
$(call SUBST,fsck.zfs,%D%/)
@ -100,9 +100,9 @@ endif
if USING_PYTHON
bin_SCRIPTS += arc_summary arcstat dbufstat
CLEANFILES += arc_summary arcstat dbufstat
EXTRA_DIST += %D%/arc_summary %D%/arcstat.in %D%/dbufstat.in
bin_SCRIPTS += arc_summary arcstat dbufstat
CLEANFILES += arc_summary arcstat dbufstat
dist_noinst_DATA += %D%/arc_summary %D%/arcstat.in %D%/dbufstat.in
$(call SUBST,arcstat,%D%/)
$(call SUBST,dbufstat,%D%/)

View file

@ -3194,13 +3194,18 @@ dump_znode_symlink(sa_handle_t *hdl)
{
int sa_symlink_size = 0;
char linktarget[MAXPATHLEN];
linktarget[0] = '\0';
int error;
error = sa_size(hdl, sa_attr_table[ZPL_SYMLINK], &sa_symlink_size);
if (error || sa_symlink_size == 0) {
return;
}
if (sa_symlink_size >= sizeof (linktarget)) {
(void) printf("symlink size %d is too large\n",
sa_symlink_size);
return;
}
linktarget[sa_symlink_size] = '\0';
if (sa_lookup(hdl, sa_attr_table[ZPL_SYMLINK],
&linktarget, sa_symlink_size) == 0)
(void) printf("\ttarget %s\n", linktarget);

View file

@ -43,4 +43,4 @@ zed_LDADD = \
zed_LDADD += -lrt $(LIBATOMIC_LIBS) $(LIBUDEV_LIBS) $(LIBUUID_LIBS)
zed_LDFLAGS = -pthread
EXTRA_DIST += $(addprefix %D%/,agents/README.md)
dist_noinst_DATA += %D%/agents/README.md

View file

@ -34,6 +34,7 @@
#include <sys/fs/zfs.h>
#include <sys/fm/protocol.h>
#include <sys/fm/fs/zfs.h>
#include <sys/zio.h>
#include "zfs_agents.h"
#include "fmd_api.h"
@ -770,6 +771,8 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_PROBE_FAILURE))) {
char *failmode = NULL;
boolean_t checkremove = B_FALSE;
uint32_t pri = 0;
int32_t flags = 0;
/*
* If this is a checksum or I/O error, then toss it into the
@ -792,6 +795,23 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
checkremove = B_TRUE;
} else if (fmd_nvl_class_match(hdl, nvl,
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_CHECKSUM))) {
/*
* We ignore ereports for checksum errors generated by
* scrub/resilver I/O to avoid potentially further
* degrading the pool while it's being repaired.
*/
if (((nvlist_lookup_uint32(nvl,
FM_EREPORT_PAYLOAD_ZFS_ZIO_PRIORITY, &pri) == 0) &&
(pri == ZIO_PRIORITY_SCRUB ||
pri == ZIO_PRIORITY_REBUILD)) ||
((nvlist_lookup_int32(nvl,
FM_EREPORT_PAYLOAD_ZFS_ZIO_FLAGS, &flags) == 0) &&
(flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)))) {
fmd_hdl_debug(hdl, "ignoring '%s' for "
"scrub/resilver I/O", class);
return;
}
if (zcp->zc_data.zc_serd_checksum[0] == '\0') {
zfs_serd_name(zcp->zc_data.zc_serd_checksum,
pool_guid, vdev_guid, "checksum");

View file

@ -1073,7 +1073,7 @@ zfs_enum_pools(void *arg)
* For now, each agent has its own libzfs instance
*/
int
zfs_slm_init()
zfs_slm_init(void)
{
if ((g_zfshdl = libzfs_init()) == NULL)
return (-1);
@ -1099,7 +1099,7 @@ zfs_slm_init()
}
void
zfs_slm_fini()
zfs_slm_fini(void)
{
unavailpool_t *pool;
pendingdev_t *device;

View file

@ -38,7 +38,7 @@ zedconfdefaults = \
vdev_attach-led.sh \
vdev_clear-led.sh
EXTRA_DIST += $(addprefix %D%/,README)
dist_noinst_DATA += %D%/README
INSTALL_DATA_HOOKS += zed-install-data-hook
zed-install-data-hook:

View file

@ -223,6 +223,8 @@ zed_notify()
# ZED_EMAIL_OPTS. This undergoes the following keyword substitutions:
# - @ADDRESS@ is replaced with the space-delimited recipient email address(es)
# - @SUBJECT@ is replaced with the notification subject
# If @SUBJECT@ was omited here, a "Subject: ..." header will be added to notification
#
#
# Arguments
# subject: notification subject
@ -240,7 +242,7 @@ zed_notify()
#
zed_notify_email()
{
local subject="$1"
local subject="${1:-"ZED notification"}"
local pathname="${2:-"/dev/null"}"
: "${ZED_EMAIL_PROG:="mail"}"
@ -261,12 +263,23 @@ zed_notify_email()
return 1
fi
ZED_EMAIL_OPTS="$(echo "${ZED_EMAIL_OPTS}" \
# construct cmdline options
ZED_EMAIL_OPTS_PARSED="$(echo "${ZED_EMAIL_OPTS}" \
| sed -e "s/@ADDRESS@/${ZED_EMAIL_ADDR}/g" \
-e "s/@SUBJECT@/${subject}/g")"
# pipe message to email prog
# shellcheck disable=SC2086,SC2248
eval ${ZED_EMAIL_PROG} ${ZED_EMAIL_OPTS} < "${pathname}" >/dev/null 2>&1
{
# no subject passed as option?
if [ "${ZED_EMAIL_OPTS%@SUBJECT@*}" = "${ZED_EMAIL_OPTS}" ] ; then
# inject subject header
printf "Subject: %s\n" "${subject}"
fi
# output message
cat "${pathname}"
} |
eval ${ZED_EMAIL_PROG} ${ZED_EMAIL_OPTS_PARSED} >/dev/null 2>&1
rv=$?
if [ "${rv}" -ne 0 ]; then
zed_log_err "${ZED_EMAIL_PROG##*/} exit=${rv}"

View file

@ -29,6 +29,7 @@ ZED_EMAIL_ADDR="root"
# The string @SUBJECT@ will be replaced with the notification subject;
# this should be protected with quotes to prevent word-splitting.
# Email will only be sent if ZED_EMAIL_ADDR is defined.
# If @SUBJECT@ was omited here, a "Subject: ..." header will be added to notification
#
#ZED_EMAIL_OPTS="-s '@SUBJECT@' @ADDRESS@"

View file

@ -362,7 +362,7 @@ zed_udev_monitor(void *arg)
}
int
zed_disk_event_init()
zed_disk_event_init(void)
{
int fd, fflags;
@ -398,7 +398,7 @@ zed_disk_event_init()
}
void
zed_disk_event_fini()
zed_disk_event_fini(void)
{
/* cancel monitor thread at recvmsg() */
(void) pthread_cancel(g_mon_tid);
@ -416,13 +416,13 @@ zed_disk_event_fini()
#include "zed_disk_event.h"
int
zed_disk_event_init()
zed_disk_event_init(void)
{
return (0);
}
void
zed_disk_event_fini()
zed_disk_event_fini(void)
{
}

View file

@ -8577,11 +8577,7 @@ static int
zfs_do_version(int argc, char **argv)
{
(void) argc, (void) argv;
if (zfs_version_print() == -1)
return (1);
return (0);
return (zfs_version_print() != 0);
}
int

View file

@ -38,7 +38,7 @@ zpool_LDADD += -lgeom
endif
zpool_LDADD += -lm $(LIBBLKID_LIBS) $(LIBUUID_LIBS)
EXTRA_DIST += $(addprefix %D%/,zpool.d/README compatibility.d)
dist_noinst_DATA += %D%/zpool.d/README
SHELLCHECKSCRIPTS += $(dist_zpoolexec_SCRIPTS)
zpoolexecdir = $(zfsexecdir)/zpool.d

View file

@ -10818,11 +10818,7 @@ static int
zpool_do_version(int argc, char **argv)
{
(void) argc, (void) argv;
if (zfs_version_print() == -1)
return (1);
return (0);
return (zfs_version_print() != 0);
}
/*

View file

@ -41,6 +41,6 @@ endef
SUBSTFILES =
CLEANFILES += $(SUBSTFILES)
EXTRA_DIST += $(SUBSTFILES:=.in)
dist_noinst_DATA += $(SUBSTFILES:=.in)
$(call SUBST,%,)

View file

@ -464,7 +464,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_CGROUP_HEADER], [
])
AC_DEFUN([ZFS_AC_KERNEL_BLK_CGROUP_HEADER], [
AC_MSG_CHECKING([for existence of linux/blk-cgroup.h])
AC_MSG_CHECKING([whether linux/blk-cgroup.h exists])
ZFS_LINUX_TEST_RESULT([blk_cgroup_header],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_LINUX_BLK_CGROUP_HEADER, 1,
@ -500,7 +500,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_ALLOC_4ARG], [
])
AC_DEFUN([ZFS_AC_KERNEL_BIO_ALLOC_4ARG], [
AC_MSG_CHECKING([for 4-argument bio_alloc()])
AC_MSG_CHECKING([whether bio_alloc() wants 4 args])
ZFS_LINUX_TEST_RESULT([bio_alloc_4arg],[
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_BIO_ALLOC_4ARG], 1, [bio_alloc() takes 4 arguments])

View file

@ -74,6 +74,8 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_UPDATE_READAHEAD], [
AC_DEFINE(HAVE_BLK_QUEUE_UPDATE_READAHEAD, 1,
[blk_queue_update_readahead() exists])
],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether disk_update_readahead() exists])
ZFS_LINUX_TEST_RESULT([disk_update_readahead], [
AC_MSG_RESULT(yes)
@ -86,10 +88,19 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_UPDATE_READAHEAD], [
])
dnl #
dnl # 2.6.32 API,
dnl # blk_queue_discard()
dnl # 5.19: bdev_max_discard_sectors() available
dnl # 2.6.32: blk_queue_discard() available
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD], [
ZFS_LINUX_TEST_SRC([bdev_max_discard_sectors], [
#include <linux/blkdev.h>
],[
struct block_device *bdev __attribute__ ((unused)) = NULL;
unsigned int error __attribute__ ((unused));
error = bdev_max_discard_sectors(bdev);
])
ZFS_LINUX_TEST_SRC([blk_queue_discard], [
#include <linux/blkdev.h>
],[
@ -102,22 +113,40 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD], [
])
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_DISCARD], [
AC_MSG_CHECKING([whether blk_queue_discard() is available])
ZFS_LINUX_TEST_RESULT([blk_queue_discard], [
AC_MSG_CHECKING([whether bdev_max_discard_sectors() is available])
ZFS_LINUX_TEST_RESULT([bdev_max_discard_sectors], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BDEV_MAX_DISCARD_SECTORS, 1,
[bdev_max_discard_sectors() is available])
],[
ZFS_LINUX_TEST_ERROR([blk_queue_discard])
AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether blk_queue_discard() is available])
ZFS_LINUX_TEST_RESULT([blk_queue_discard], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLK_QUEUE_DISCARD, 1,
[blk_queue_discard() is available])
],[
ZFS_LINUX_TEST_ERROR([blk_queue_discard])
])
])
])
dnl #
dnl # 4.8 API,
dnl # blk_queue_secure_erase()
dnl #
dnl # 2.6.36 - 4.7 API,
dnl # blk_queue_secdiscard()
dnl # 5.19: bdev_max_secure_erase_sectors() available
dnl # 4.8: blk_queue_secure_erase() available
dnl # 2.6.36: blk_queue_secdiscard() available
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE], [
ZFS_LINUX_TEST_SRC([bdev_max_secure_erase_sectors], [
#include <linux/blkdev.h>
],[
struct block_device *bdev __attribute__ ((unused)) = NULL;
unsigned int error __attribute__ ((unused));
error = bdev_max_secure_erase_sectors(bdev);
])
ZFS_LINUX_TEST_SRC([blk_queue_secure_erase], [
#include <linux/blkdev.h>
],[
@ -140,21 +169,30 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE], [
])
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE], [
AC_MSG_CHECKING([whether blk_queue_secure_erase() is available])
ZFS_LINUX_TEST_RESULT([blk_queue_secure_erase], [
AC_MSG_CHECKING([whether bdev_max_secure_erase_sectors() is available])
ZFS_LINUX_TEST_RESULT([bdev_max_secure_erase_sectors], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLK_QUEUE_SECURE_ERASE, 1,
[blk_queue_secure_erase() is available])
AC_DEFINE(HAVE_BDEV_MAX_SECURE_ERASE_SECTORS, 1,
[bdev_max_secure_erase_sectors() is available])
],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether blk_queue_secdiscard() is available])
ZFS_LINUX_TEST_RESULT([blk_queue_secdiscard], [
AC_MSG_CHECKING([whether blk_queue_secure_erase() is available])
ZFS_LINUX_TEST_RESULT([blk_queue_secure_erase], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLK_QUEUE_SECDISCARD, 1,
[blk_queue_secdiscard() is available])
AC_DEFINE(HAVE_BLK_QUEUE_SECURE_ERASE, 1,
[blk_queue_secure_erase() is available])
],[
ZFS_LINUX_TEST_ERROR([blk_queue_secure_erase])
AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether blk_queue_secdiscard() is available])
ZFS_LINUX_TEST_RESULT([blk_queue_secdiscard], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLK_QUEUE_SECDISCARD, 1,
[blk_queue_secdiscard() is available])
],[
ZFS_LINUX_TEST_ERROR([blk_queue_secure_erase])
])
])
])
])

View file

@ -294,6 +294,57 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BDEV_WHOLE], [
])
])
dnl #
dnl # 5.19 API: blkdev_issue_secure_erase()
dnl # 3.10 API: blkdev_issue_discard(..., BLKDEV_DISCARD_SECURE)
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_ISSUE_SECURE_ERASE], [
ZFS_LINUX_TEST_SRC([blkdev_issue_secure_erase], [
#include <linux/blkdev.h>
],[
struct block_device *bdev = NULL;
sector_t sector = 0;
sector_t nr_sects = 0;
int error __attribute__ ((unused));
error = blkdev_issue_secure_erase(bdev,
sector, nr_sects, GFP_KERNEL);
])
ZFS_LINUX_TEST_SRC([blkdev_issue_discard_flags], [
#include <linux/blkdev.h>
],[
struct block_device *bdev = NULL;
sector_t sector = 0;
sector_t nr_sects = 0;
unsigned long flags = 0;
int error __attribute__ ((unused));
error = blkdev_issue_discard(bdev,
sector, nr_sects, GFP_KERNEL, flags);
])
])
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_ISSUE_SECURE_ERASE], [
AC_MSG_CHECKING([whether blkdev_issue_secure_erase() is available])
ZFS_LINUX_TEST_RESULT([blkdev_issue_secure_erase], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLKDEV_ISSUE_SECURE_ERASE, 1,
[blkdev_issue_secure_erase() is available])
],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether blkdev_issue_discard() is available])
ZFS_LINUX_TEST_RESULT([blkdev_issue_discard_flags], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLKDEV_ISSUE_DISCARD, 1,
[blkdev_issue_discard() is available])
],[
ZFS_LINUX_TEST_ERROR([blkdev_issue_discard()])
])
])
])
dnl #
dnl # 5.13 API change
dnl # blkdev_get_by_path() no longer handles ERESTARTSYS
@ -326,6 +377,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
ZFS_AC_KERNEL_SRC_BLKDEV_CHECK_DISK_CHANGE
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_CHECK_MEDIA_CHANGE
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_WHOLE
ZFS_AC_KERNEL_SRC_BLKDEV_ISSUE_SECURE_ERASE
])
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [
@ -340,4 +392,5 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [
ZFS_AC_KERNEL_BLKDEV_BDEV_CHECK_MEDIA_CHANGE
ZFS_AC_KERNEL_BLKDEV_BDEV_WHOLE
ZFS_AC_KERNEL_BLKDEV_GET_ERESTARTSYS
ZFS_AC_KERNEL_BLKDEV_ISSUE_SECURE_ERASE
])

View file

@ -2,6 +2,9 @@ dnl #
dnl # Handle differences in kernel FPU code.
dnl #
dnl # Kernel
dnl # 5.19: The asm/fpu/internal.h header was removed, it has been
dnl # effectively empty since the 5.16 kernel.
dnl #
dnl # 5.11: kernel_fpu_begin() is an inlined function now, so don't check
dnl # for it inside the kernel symbols.
dnl #
@ -27,10 +30,22 @@ AC_DEFUN([ZFS_AC_KERNEL_FPU_HEADER], [
],[
AC_DEFINE(HAVE_KERNEL_FPU_API_HEADER, 1,
[kernel has asm/fpu/api.h])
AC_MSG_RESULT(asm/fpu/api.h)
ZFS_LINUX_TRY_COMPILE([
#include <linux/module.h>
#include <asm/fpu/internal.h>
],[
],[
AC_DEFINE(HAVE_KERNEL_FPU_INTERNAL_HEADER, 1,
[kernel has asm/fpu/internal.h])
AC_MSG_RESULT([asm/fpu/api.h asm/fpu/internal.h])
],[
AC_MSG_RESULT([asm/fpu/api.h])
])
],[
AC_MSG_RESULT(i387.h)
AC_MSG_RESULT([i387.h])
])
])
AC_DEFUN([ZFS_AC_KERNEL_SRC_FPU], [
@ -38,7 +53,9 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_FPU], [
#include <linux/types.h>
#ifdef HAVE_KERNEL_FPU_API_HEADER
#include <asm/fpu/api.h>
#ifdef HAVE_KERNEL_FPU_INTERNAL_HEADER
#include <asm/fpu/internal.h>
#endif
#else
#include <asm/i387.h>
#endif
@ -51,7 +68,9 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_FPU], [
#include <linux/types.h>
#ifdef HAVE_KERNEL_FPU_API_HEADER
#include <asm/fpu/api.h>
#ifdef HAVE_KERNEL_FPU_INTERNAL_HEADER
#include <asm/fpu/internal.h>
#endif
#else
#include <asm/i387.h>
#endif

View file

@ -2,6 +2,19 @@ dnl #
dnl # Check for generic io accounting interface.
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT], [
ZFS_LINUX_TEST_SRC([bdev_io_acct], [
#include <linux/blkdev.h>
], [
struct block_device *bdev = NULL;
struct bio *bio = NULL;
unsigned long passed_time = 0;
unsigned long start_time;
start_time = bdev_start_io_acct(bdev, bio_sectors(bio),
bio_op(bio), passed_time);
bdev_end_io_acct(bdev, bio_op(bio), start_time);
])
ZFS_LINUX_TEST_SRC([disk_io_acct], [
#include <linux/blkdev.h>
], [
@ -50,61 +63,75 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT], [
AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT], [
dnl #
dnl # 5.12 API,
dnl # 5.19 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 # disk_start_io_acct() and disk_end_io_acct() have been replaced by
dnl # bdev_start_io_acct() and bdev_end_io_acct().
dnl #
AC_MSG_CHECKING([whether generic disk_*_io_acct() are available])
ZFS_LINUX_TEST_RESULT([disk_io_acct], [
AC_MSG_CHECKING([whether generic bdev_*_io_acct() are available])
ZFS_LINUX_TEST_RESULT([bdev_io_acct], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_DISK_IO_ACCT, 1, [disk_*_io_acct() available])
AC_DEFINE(HAVE_BDEV_IO_ACCT, 1, [bdev_*_io_acct() available])
], [
AC_MSG_RESULT(no)
dnl #
dnl # 5.7 API,
dnl # 5.12 API,
dnl #
dnl # Added bio_start_io_acct() and bio_end_io_acct() helpers.
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 bio_*_io_acct() are available])
ZFS_LINUX_TEST_RESULT([bio_io_acct], [
AC_MSG_CHECKING([whether generic disk_*_io_acct() are available])
ZFS_LINUX_TEST_RESULT([disk_io_acct], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BIO_IO_ACCT, 1, [bio_*_io_acct() available])
AC_DEFINE(HAVE_DISK_IO_ACCT, 1, [disk_*_io_acct() available])
], [
AC_MSG_RESULT(no)
dnl #
dnl # 4.14 API,
dnl # 5.7 API,
dnl #
dnl # generic_start_io_acct/generic_end_io_acct now require
dnl # request_queue to be provided. No functional changes,
dnl # but preparation for inflight accounting.
dnl # Added bio_start_io_acct() and bio_end_io_acct() helpers.
dnl #
AC_MSG_CHECKING([whether generic_*_io_acct wants 4 args])
ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_4args],
[generic_start_io_acct], [block/bio.c], [
AC_MSG_CHECKING([whether generic bio_*_io_acct() are available])
ZFS_LINUX_TEST_RESULT([bio_io_acct], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GENERIC_IO_ACCT_4ARG, 1,
[generic_*_io_acct() 4 arg available])
AC_DEFINE(HAVE_BIO_IO_ACCT, 1, [bio_*_io_acct() available])
], [
AC_MSG_RESULT(no)
dnl #
dnl # 3.19 API addition
dnl # 4.14 API,
dnl #
dnl # torvalds/linux@394ffa50 allows us to increment
dnl # iostat counters without generic_make_request().
dnl # generic_start_io_acct/generic_end_io_acct now require
dnl # request_queue to be provided. No functional changes,
dnl # but preparation for inflight accounting.
dnl #
AC_MSG_CHECKING(
[whether generic_*_io_acct wants 3 args])
ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_3args],
AC_MSG_CHECKING([whether generic_*_io_acct wants 4 args])
ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_4args],
[generic_start_io_acct], [block/bio.c], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GENERIC_IO_ACCT_3ARG, 1,
[generic_*_io_acct() 3 arg available])
AC_DEFINE(HAVE_GENERIC_IO_ACCT_4ARG, 1,
[generic_*_io_acct() 4 arg available])
], [
AC_MSG_RESULT(no)
dnl #
dnl # 3.19 API addition
dnl #
dnl # torvalds/linux@394ffa50 allows us to increment
dnl # iostat counters without generic_make_request().
dnl #
AC_MSG_CHECKING(
[whether generic_*_io_acct wants 3 args])
ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_3args],
[generic_start_io_acct], [block/bio.c], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GENERIC_IO_ACCT_3ARG, 1,
[generic_*_io_acct() 3 arg available])
], [
AC_MSG_RESULT(no)
])
])
])
])

View file

@ -15,7 +15,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_PAGEMAP_FOLIO_WAIT_BIT], [
])
AC_DEFUN([ZFS_AC_KERNEL_PAGEMAP_FOLIO_WAIT_BIT], [
AC_MSG_CHECKING([folio_wait_bit() exists])
AC_MSG_CHECKING([whether 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,

View file

@ -14,7 +14,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_READPAGES], [
])
AC_DEFUN([ZFS_AC_KERNEL_VFS_READPAGES], [
AC_MSG_CHECKING([address_space_operations->readpages exists])
AC_MSG_CHECKING([whether aops->readpages exists])
ZFS_LINUX_TEST_RESULT([vfs_has_readpages], [
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_VFS_READPAGES, 1,

View file

@ -84,7 +84,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK], [
AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
dnl #
dnl # 3.0 - 3.11 API change
dnl # ->shrink(struct shrinker *, struct shrink_control *sc)
dnl # cs->shrink(struct shrinker *, struct shrink_control *sc)
dnl #
AC_MSG_CHECKING([whether new 2-argument shrinker exists])
ZFS_LINUX_TEST_RESULT([shrinker_cb_shrink_control], [
@ -96,14 +96,14 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
dnl #
dnl # 3.12 API change,
dnl # ->shrink() is logically split in to
dnl # ->count_objects() and ->scan_objects()
dnl # cs->shrink() is logically split in to
dnl # cs->count_objects() and cs->scan_objects()
dnl #
AC_MSG_CHECKING([whether ->count_objects callback exists])
AC_MSG_CHECKING([whether cs->count_objects callback exists])
ZFS_LINUX_TEST_RESULT([shrinker_cb_shrink_control_split], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SPLIT_SHRINKER_CALLBACK, 1,
[->count_objects exists])
[cs->count_objects exists])
],[
ZFS_LINUX_TEST_ERROR([shrinker])
])

View file

@ -19,7 +19,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_SYSFS_DEFAULT_GROUPS], [
])
AC_DEFUN([ZFS_AC_KERNEL_SYSFS_DEFAULT_GROUPS], [
AC_MSG_CHECKING([for struct kobj_type.default_groups])
AC_MSG_CHECKING([whether struct kobj_type.default_groups exists])
ZFS_LINUX_TEST_RESULT([sysfs_default_groups],[
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_SYSFS_DEFAULT_GROUPS], 1, [struct kobj_type has default_groups])

View file

@ -19,7 +19,7 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_FILEMAP_DIRTY_FOLIO], [
dnl # Linux 5.18 uses filemap_dirty_folio in lieu of
dnl # ___set_page_dirty_nobuffers
dnl #
AC_MSG_CHECKING([filemap_dirty_folio exists])
AC_MSG_CHECKING([whether filemap_dirty_folio exists])
ZFS_LINUX_TEST_RESULT([vfs_has_filemap_dirty_folio], [
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_VFS_FILEMAP_DIRTY_FOLIO, 1,

View file

@ -134,6 +134,8 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_IOV_ITER], [
AC_DEFINE(HAVE_IOV_ITER_FAULT_IN_READABLE, 1,
[iov_iter_fault_in_readable() is available])
],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether fault_in_iov_iter_readable() is available])
ZFS_LINUX_TEST_RESULT([fault_in_iov_iter_readable], [
AC_MSG_RESULT(yes)

View file

@ -0,0 +1,32 @@
dnl #
dnl # Linux 5.19 uses read_folio in lieu of readpage
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_READ_FOLIO], [
ZFS_LINUX_TEST_SRC([vfs_has_read_folio], [
#include <linux/fs.h>
static int
test_read_folio(struct file *file, struct folio *folio) {
(void) file; (void) folio;
return (0);
}
static const struct address_space_operations
aops __attribute__ ((unused)) = {
.read_folio = test_read_folio,
};
],[])
])
AC_DEFUN([ZFS_AC_KERNEL_VFS_READ_FOLIO], [
dnl #
dnl # Linux 5.19 uses read_folio in lieu of readpage
dnl #
AC_MSG_CHECKING([whether read_folio exists])
ZFS_LINUX_TEST_RESULT([vfs_has_read_folio], [
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_VFS_READ_FOLIO, 1, [read_folio exists])
],[
AC_MSG_RESULT([no])
])
])

View file

@ -23,7 +23,7 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_SET_PAGE_DIRTY_NOBUFFERS], [
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])
AC_MSG_CHECKING([whether __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,

View file

@ -102,10 +102,13 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
ZFS_AC_KERNEL_SRC_SGET
ZFS_AC_KERNEL_SRC_LSEEK_EXECUTE
ZFS_AC_KERNEL_SRC_VFS_FILEMAP_DIRTY_FOLIO
ZFS_AC_KERNEL_SRC_VFS_READ_FOLIO
ZFS_AC_KERNEL_SRC_VFS_GETATTR
ZFS_AC_KERNEL_SRC_VFS_FSYNC_2ARGS
ZFS_AC_KERNEL_SRC_VFS_ITERATE
ZFS_AC_KERNEL_SRC_VFS_DIRECT_IO
ZFS_AC_KERNEL_SRC_VFS_READPAGES
ZFS_AC_KERNEL_SRC_VFS_SET_PAGE_DIRTY_NOBUFFERS
ZFS_AC_KERNEL_SRC_VFS_RW_ITERATE
ZFS_AC_KERNEL_SRC_VFS_GENERIC_WRITE_CHECKS
ZFS_AC_KERNEL_SRC_VFS_IOV_ITER
@ -136,8 +139,6 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
ZFS_AC_KERNEL_SRC_SIGINFO
ZFS_AC_KERNEL_SRC_SYSFS
ZFS_AC_KERNEL_SRC_SET_SPECIAL_STATE
ZFS_AC_KERNEL_SRC_VFS_READPAGES
ZFS_AC_KERNEL_SRC_VFS_SET_PAGE_DIRTY_NOBUFFERS
ZFS_AC_KERNEL_SRC_STANDALONE_LINUX_STDARG
ZFS_AC_KERNEL_SRC_PAGEMAP_FOLIO_WAIT_BIT
ZFS_AC_KERNEL_SRC_ADD_DISK
@ -219,10 +220,13 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
ZFS_AC_KERNEL_SGET
ZFS_AC_KERNEL_LSEEK_EXECUTE
ZFS_AC_KERNEL_VFS_FILEMAP_DIRTY_FOLIO
ZFS_AC_KERNEL_VFS_READ_FOLIO
ZFS_AC_KERNEL_VFS_GETATTR
ZFS_AC_KERNEL_VFS_FSYNC_2ARGS
ZFS_AC_KERNEL_VFS_ITERATE
ZFS_AC_KERNEL_VFS_DIRECT_IO
ZFS_AC_KERNEL_VFS_READPAGES
ZFS_AC_KERNEL_VFS_SET_PAGE_DIRTY_NOBUFFERS
ZFS_AC_KERNEL_VFS_RW_ITERATE
ZFS_AC_KERNEL_VFS_GENERIC_WRITE_CHECKS
ZFS_AC_KERNEL_VFS_IOV_ITER
@ -253,8 +257,6 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
ZFS_AC_KERNEL_SIGINFO
ZFS_AC_KERNEL_SYSFS
ZFS_AC_KERNEL_SET_SPECIAL_STATE
ZFS_AC_KERNEL_VFS_READPAGES
ZFS_AC_KERNEL_VFS_SET_PAGE_DIRTY_NOBUFFERS
ZFS_AC_KERNEL_STANDALONE_LINUX_STDARG
ZFS_AC_KERNEL_PAGEMAP_FOLIO_WAIT_BIT
ZFS_AC_KERNEL_ADD_DISK

View file

@ -268,6 +268,7 @@ AC_DEFUN([ZFS_AC_CONFIG], [
user) ZFS_AC_CONFIG_USER ;;
all) ZFS_AC_CONFIG_USER
ZFS_AC_CONFIG_KERNEL ;;
dist) ;;
srpm) ;;
*)
AC_MSG_RESULT([Error!])
@ -333,6 +334,10 @@ AC_DEFUN([ZFS_AC_RPM], [
RPM_DEFINE_COMMON=${RPM_DEFINE_COMMON}' --define "$(ASAN_ZFS) 1"'
RPM_DEFINE_COMMON=${RPM_DEFINE_COMMON}' --define "$(UBSAN_ZFS) 1"'
AS_IF([test "x$enable_debuginfo" = xyes], [
RPM_DEFINE_COMMON=${RPM_DEFINE_COMMON}' --define "__strip /bin/true"'
])
RPM_DEFINE_UTIL=' --define "_initconfdir $(initconfdir)"'
dnl # Make the next three RPM_DEFINE_UTIL additions conditional, since

View file

@ -43,7 +43,7 @@ AM_INIT_AUTOMAKE([subdir-objects foreign])
# Remove default macros from config.h:
# PACKAGE, PACKAGE_{BUGREPORT,NAME,STRING,TARNAME,VERSION}, STDC_HEADERS, VERSION
AC_CONFIG_HEADERS([zfs_config.h], [
sed -nEi~ -e '/^$/be' -e 'N;N;/#define (PACKAGE|VERSION|STDC_HEADERS)/d' -e ':e' -e 'p' zfs_config.h && rm zfs_config.h~ || exit])
sed -nri~ -e '/^$/be' -e 'N;N;/#define (PACKAGE|VERSION|STDC_HEADERS)/d' -e ':e' -e 'p' zfs_config.h && rm zfs_config.h~ || exit])
LT_INIT
AC_PROG_INSTALL

View file

@ -1,5 +1,3 @@
EXTRA_DIST += $(addprefix %D%/, \
taskqlatency.bt \
zfs-trace.sh)
dist_noinst_DATA += %D%/taskqlatency.bt %D%/zfs-trace.sh
SHELLCHECKSCRIPTS += %D%/zfs-trace.sh

View file

@ -24,4 +24,4 @@ SHELLCHECKSCRIPTS += $(pkgdracut_02_SCRIPTS) $(pkgdracut_90_SCRIPTS)
# Provided by /bin/sleep, and, again, every implementation of that supports this
$(call SHELLCHECK_OPTS,$(pkgdracut_90_SCRIPTS)): CHECKBASHISMS_IGNORE = -e 'sleep only takes one integer' -e 'sleep 0.'
EXTRA_DIST += $(addprefix %D%/,README.md)
dist_noinst_DATA += %D%/README.md

View file

@ -36,4 +36,4 @@ SHELLCHECKSCRIPTS += $(i_t_check_scripts)
$(call SHELLCHECK_OPTS,$(i_t_check_scripts)): SHELLCHECK_SHELL = sh
EXTRA_DIST += $(addprefix %D%/,README.md)
dist_noinst_DATA += %D%/README.md

View file

@ -1,4 +1,4 @@
EXTRA_DIST += $(addprefix %D%/,libzfs_core README LICENSE docs)
dist_noinst_DATA += %D%/libzfs_core %D%/README %D%/LICENSE %D%/docs
SUBSTFILES += %D%/setup.py
if PYZFS_ENABLED

View file

@ -1 +1 @@
EXTRA_DIST += $(addprefix %D%/,autosnap.lua)
dist_noinst_DATA += %D%/autosnap.lua

View file

@ -2,7 +2,7 @@ sudoersddir = $(sysconfdir)/sudoers.d
sudoersd_DATA = \
%D%/sudoers.d/zfs
EXTRA_DIST += $(sudoersd_DATA)
dist_noinst_DATA += $(sudoersd_DATA)
sysconf_zfsdir = $(sysconfdir)/zfs
@ -14,25 +14,25 @@ dist_sysconf_zfs_DATA = \
%D%/zfs/vdev_id.conf.sas_switch.example \
%D%/zfs/vdev_id.conf.scsi.example
sysconf_zfs_SCRIPTS = \
sysconf_zfs_DATA = \
%D%/zfs/zfs-functions
SUBSTFILES += $(sysconf_zfs_SCRIPTS)
SHELLCHECKSCRIPTS += $(sysconf_zfs_SCRIPTS)
$(call SHELLCHECK_OPTS,$(sysconf_zfs_SCRIPTS)): SHELLCHECK_SHELL = sh
SUBSTFILES += $(sysconf_zfs_DATA)
SHELLCHECKSCRIPTS += $(sysconf_zfs_DATA)
$(call SHELLCHECK_OPTS,$(sysconf_zfs_DATA)): SHELLCHECK_SHELL = sh
if BUILD_LINUX
initconf_SCRIPTS = \
initconf_DATA = \
%D%/default/zfs
SUBSTFILES += $(initconf_SCRIPTS)
SHELLCHECKSCRIPTS += $(initconf_SCRIPTS)
$(call SHELLCHECK_OPTS,$(initconf_SCRIPTS)): SHELLCHECK_SHELL = sh
SUBSTFILES += $(initconf_DATA)
SHELLCHECKSCRIPTS += $(initconf_DATA)
$(call SHELLCHECK_OPTS,$(initconf_DATA)): SHELLCHECK_SHELL = sh
if INIT_SYSV
EXTRA_DIST += $(addprefix %D%/,init.d/README.md)
dist_noinst_DATA += %D%/init.d/README.md
init_SCRIPTS = \
%D%/init.d/zfs-import \

View file

@ -40,10 +40,8 @@
#include <sys/mnttab.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/varargs.h>
#include <sys/fs/zfs.h>
#include <sys/avl.h>
#include <ucred.h>
#include <libzfs_core.h>
#ifdef __cplusplus
@ -916,8 +914,8 @@ _LIBZFS_H int libzfs_envvar_is_set(char *);
/*
* Utility functions for zfs version
*/
_LIBZFS_H void zfs_version_userland(char *, int);
_LIBZFS_H int zfs_version_kernel(char *, int);
_LIBZFS_H const char *zfs_version_userland(void);
_LIBZFS_H char *zfs_version_kernel(void);
_LIBZFS_H int zfs_version_print(void);
/*

View file

@ -495,21 +495,45 @@ blk_queue_discard_granularity(struct request_queue *q, unsigned int dg)
}
/*
* 5.19 API,
* bdev_max_discard_sectors()
*
* 2.6.32 API,
* blk_queue_discard()
*/
static inline boolean_t
bdev_discard_supported(struct block_device *bdev)
{
#if defined(HAVE_BDEV_MAX_DISCARD_SECTORS)
return (!!bdev_max_discard_sectors(bdev));
#elif defined(HAVE_BLK_QUEUE_DISCARD)
return (!!blk_queue_discard(bdev_get_queue(bdev)));
#else
#error "Unsupported kernel"
#endif
}
/*
* 5.19 API,
* bdev_max_secure_erase_sectors()
*
* 4.8 API,
* blk_queue_secure_erase()
*
* 2.6.36 - 4.7 API,
* blk_queue_secdiscard()
*/
static inline int
blk_queue_discard_secure(struct request_queue *q)
static inline boolean_t
bdev_secure_discard_supported(struct block_device *bdev)
{
#if defined(HAVE_BLK_QUEUE_SECURE_ERASE)
return (blk_queue_secure_erase(q));
#if defined(HAVE_BDEV_MAX_SECURE_ERASE_SECTORS)
return (!!bdev_max_secure_erase_sectors(bdev));
#elif defined(HAVE_BLK_QUEUE_SECURE_ERASE)
return (!!blk_queue_secure_erase(bdev_get_queue(bdev)));
#elif defined(HAVE_BLK_QUEUE_SECDISCARD)
return (blk_queue_secdiscard(q));
return (!!blk_queue_secdiscard(bdev_get_queue(bdev)));
#else
return (0);
#error "Unsupported kernel"
#endif
}
@ -527,7 +551,10 @@ blk_generic_start_io_acct(struct request_queue *q __attribute__((unused)),
struct gendisk *disk __attribute__((unused)),
int rw __attribute__((unused)), struct bio *bio)
{
#if defined(HAVE_DISK_IO_ACCT)
#if defined(HAVE_BDEV_IO_ACCT)
return (bdev_start_io_acct(bio->bi_bdev, bio_sectors(bio),
bio_op(bio), jiffies));
#elif 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));
@ -550,7 +577,9 @@ blk_generic_end_io_acct(struct request_queue *q __attribute__((unused)),
struct gendisk *disk __attribute__((unused)),
int rw __attribute__((unused)), struct bio *bio, unsigned long start_time)
{
#if defined(HAVE_DISK_IO_ACCT)
#if defined(HAVE_BDEV_IO_ACCT)
bdev_end_io_acct(bio->bi_bdev, bio_op(bio), start_time);
#elif 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);

View file

@ -93,7 +93,9 @@
#if defined(HAVE_KERNEL_FPU_API_HEADER)
#include <asm/fpu/api.h>
#if defined(HAVE_KERNEL_FPU_INTERNAL_HEADER)
#include <asm/fpu/internal.h>
#endif
#else
#include <asm/i387.h>
#endif

View file

@ -329,7 +329,7 @@ typedef struct dbuf_hash_table {
krwlock_t hash_rwlocks[DBUF_RWLOCKS] ____cacheline_aligned;
} dbuf_hash_table_t;
typedef void (*dbuf_prefetch_fn)(void *, boolean_t);
typedef void (*dbuf_prefetch_fn)(void *, uint64_t, uint64_t, boolean_t);
uint64_t dbuf_whichblock(const struct dnode *di, const int64_t level,
const uint64_t offset);

View file

@ -124,8 +124,8 @@ typedef struct dmu_tx_stats {
kstat_named_t dmu_tx_dirty_throttle;
kstat_named_t dmu_tx_dirty_delay;
kstat_named_t dmu_tx_dirty_over_max;
kstat_named_t dmu_tx_wrlog_over_max;
kstat_named_t dmu_tx_dirty_frees_delay;
kstat_named_t dmu_tx_wrlog_delay;
kstat_named_t dmu_tx_quota;
} dmu_tx_stats_t;

View file

@ -49,20 +49,18 @@ typedef struct zfetch {
typedef struct zstream {
uint64_t zs_blkid; /* expect next access at this blkid */
uint64_t zs_pf_blkid1; /* first block to prefetch */
uint64_t zs_pf_blkid; /* block to prefetch up to */
/*
* We will next prefetch the L1 indirect block of this level-0
* block id.
*/
uint64_t zs_ipf_blkid1; /* first block to prefetch */
uint64_t zs_ipf_blkid; /* block to prefetch up to */
unsigned int zs_pf_dist; /* data prefetch distance in bytes */
unsigned int zs_ipf_dist; /* L1 prefetch distance in bytes */
uint64_t zs_pf_start; /* first data block to prefetch */
uint64_t zs_pf_end; /* data block to prefetch up to */
uint64_t zs_ipf_start; /* first data block to prefetch L1 */
uint64_t zs_ipf_end; /* data block to prefetch L1 up to */
list_node_t zs_node; /* link for zf_stream */
hrtime_t zs_atime; /* time last prefetch issued */
zfetch_t *zs_fetch; /* parent fetch */
boolean_t zs_missed; /* stream saw cache misses */
boolean_t zs_more; /* need more distant prefetch */
zfs_refcount_t zs_callers; /* number of pending callers */
/*
* Number of stream references: dnode, callers and pending blocks.

View file

@ -616,7 +616,7 @@ extern dnode_stats_t dnode_stats;
#else
#define dprintf_dnode(db, fmt, ...)
#define DNODE_VERIFY(dn)
#define DNODE_VERIFY(dn) ((void) sizeof ((uintptr_t)(dn)))
#define FREE_VERIFY(db, start, end, tx)
#endif

View file

@ -164,7 +164,7 @@ uint64_t dsl_pool_unreserved_space(dsl_pool_t *dp,
zfs_space_check_t slop_policy);
uint64_t dsl_pool_deferred_space(dsl_pool_t *dp);
void dsl_pool_wrlog_count(dsl_pool_t *dp, int64_t size, uint64_t txg);
boolean_t dsl_pool_wrlog_over_max(dsl_pool_t *dp);
boolean_t dsl_pool_need_wrlog_delay(dsl_pool_t *dp);
void dsl_pool_dirty_space(dsl_pool_t *dp, int64_t space, dmu_tx_t *tx);
void dsl_pool_undirty_space(dsl_pool_t *dp, int64_t space, uint64_t txg);
void dsl_free(dsl_pool_t *dp, uint64_t txg, const blkptr_t *bpp);

View file

@ -1292,6 +1292,7 @@ typedef struct ddt_histogram {
#define ZVOL_DRIVER "zvol"
#define ZFS_DRIVER "zfs"
#define ZFS_DEV "/dev/zfs"
#define ZFS_DEVDIR "/dev"
#define ZFS_SUPER_MAGIC 0x2fc12fc1

View file

@ -898,6 +898,7 @@ typedef struct spa_stats {
spa_history_kstat_t tx_assign_histogram;
spa_history_list_t mmp_history;
spa_history_kstat_t state; /* pool state */
spa_history_kstat_t guid; /* pool guid */
spa_history_kstat_t iostats;
} spa_stats_t;

View file

@ -110,7 +110,12 @@ typedef enum zap_flags {
* already randomly distributed.
*/
ZAP_FLAG_PRE_HASHED_KEY = 1 << 2,
#if defined(__linux__) && defined(_KERNEL)
} zfs_zap_flags_t;
#define zap_flags_t zfs_zap_flags_t
#else
} zap_flags_t;
#endif
/*
* Create a new zapobj with no attributes and return its object number.

View file

@ -99,7 +99,7 @@ typedef struct lwb {
char *lwb_buf; /* log write buffer */
zio_t *lwb_write_zio; /* zio for the lwb buffer */
zio_t *lwb_root_zio; /* root zio for lwb write and flushes */
dmu_tx_t *lwb_tx; /* tx for log block allocation */
uint64_t lwb_issued_txg; /* the txg when the write is issued */
uint64_t lwb_max_txg; /* highest txg in this lwb */
list_node_t lwb_node; /* zilog->zl_lwb_list linkage */
list_t lwb_itxs; /* list of itx's */
@ -209,6 +209,12 @@ struct zilog {
uint_t zl_prev_rotor; /* rotor for zl_prev[] */
txg_node_t zl_dirty_link; /* protected by dp_dirty_zilogs list */
uint64_t zl_dirty_max_txg; /* highest txg used to dirty zilog */
kmutex_t zl_lwb_io_lock; /* protect following members */
uint64_t zl_lwb_inflight[TXG_SIZE]; /* io issued, but not done */
kcondvar_t zl_lwb_io_cv; /* signal when the flush is done */
uint64_t zl_lwb_max_issued_txg; /* max txg when lwb io issued */
/*
* Max block size for this ZIL. Note that this can not be changed
* while the ZIL is in use because consumers (ZPL/zvol) need to take

View file

@ -78,6 +78,8 @@ typedef struct zfs_zstd_meta {
* kstat helper macros
*/
#define ZSTDSTAT(stat) (zstd_stats.stat.value.ui64)
#define ZSTDSTAT_ZERO(stat) \
atomic_store_64(&zstd_stats.stat.value.ui64, 0)
#define ZSTDSTAT_ADD(stat, val) \
atomic_add_64(&zstd_stats.stat.value.ui64, (val))
#define ZSTDSTAT_SUB(stat, val) \
@ -90,6 +92,8 @@ void zstd_fini(void);
size_t zfs_zstd_compress(void *s_start, void *d_start, size_t s_len,
size_t d_len, int level);
size_t zfs_zstd_compress_wrap(void *s_start, void *d_start, size_t s_len,
size_t d_len, int level);
int zfs_zstd_get_level(void *s_start, size_t s_len, uint8_t *level);
int zfs_zstd_decompress_level(void *s_start, void *d_start, size_t s_len,
size_t d_len, uint8_t *level);

View file

@ -28,7 +28,6 @@
#define _THREAD_POOL_H_ extern __attribute__((visibility("default")))
#include <sys/types.h>
#include <thread.h>
#include <pthread.h>
#ifdef __cplusplus

View file

@ -32,4 +32,4 @@ endif
libnvpair_la_LDFLAGS += -version-info 3:0:0
EXTRA_DIST += $(addprefix %D%/,libnvpair.abi libnvpair.suppr)
dist_noinst_DATA += %D%/libnvpair.abi %D%/libnvpair.suppr

View file

@ -248,7 +248,7 @@ smb_enable_share_one(const char *sharename, const char *sharepath)
NULL,
};
if (libzfs_run_process(argv[0], argv, 0) < 0)
if (libzfs_run_process(argv[0], argv, 0) != 0)
return (SA_SYSTEM_ERR);
/* Reload the share file */
@ -297,7 +297,7 @@ smb_disable_share_one(const char *sharename)
NULL,
};
if (libzfs_run_process(argv[0], argv, 0) < 0)
if (libzfs_run_process(argv[0], argv, 0) != 0)
return (SA_SYSTEM_ERR);
else
return (SA_OK);

View file

@ -2,18 +2,11 @@ libspldir = $(includedir)/libspl
libspl_HEADERS = \
%D%/assert.h \
%D%/atomic.h \
%D%/libdevinfo.h \
%D%/libgen.h \
%D%/libshare.h \
%D%/limits.h \
%D%/locale.h \
%D%/statcommon.h \
%D%/stdlib.h \
%D%/string.h \
%D%/stropts.h \
%D%/thread.h \
%D%/tzfile.h \
%D%/ucred.h \
%D%/umem.h \
%D%/unistd.h \
%D%/zone.h
@ -40,8 +33,6 @@ libspl_sys_HEADERS = \
%D%/sys/dkio.h \
%D%/sys/dklabel.h \
%D%/sys/feature_tests.h \
%D%/sys/int_limits.h \
%D%/sys/int_types.h \
%D%/sys/inttypes.h \
%D%/sys/isa_defs.h \
%D%/sys/kmem.h \
@ -59,7 +50,6 @@ libspl_sys_HEADERS = \
%D%/sys/stack.h \
%D%/sys/stdtypes.h \
%D%/sys/string.h \
%D%/sys/stropts.h \
%D%/sys/sunddi.h \
%D%/sys/systeminfo.h \
%D%/sys/time.h \
@ -67,10 +57,7 @@ libspl_sys_HEADERS = \
%D%/sys/trace_zfs.h \
%D%/sys/types.h \
%D%/sys/types32.h \
%D%/sys/tzfile.h \
%D%/sys/uio.h \
%D%/sys/va_list.h \
%D%/sys/varargs.h \
%D%/sys/vnode.h \
%D%/sys/wmsum.h \
%D%/sys/zone.h

View file

@ -1,30 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBSPL_LIBDEVINFO_H
#define _LIBSPL_LIBDEVINFO_H
#endif /* _LIBSPL_LIBDEVINFO_H */

View file

@ -1,45 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include_next <limits.h>
#include <float.h>
#ifndef _LIBSPL_LIMITS_H
#define _LIBSPL_LIMITS_H
#ifndef DBL_DIG
#define DBL_DIG 15
#define DBL_MAX 1.7976931348623157081452E+308
#define DBL_MIN 2.2250738585072013830903E-308
#endif
#ifndef FLT_DIG
#define FLT_DIG 6
#define FLT_MAX 3.4028234663852885981170E+38F
#define FLT_MIN 1.1754943508222875079688E-38F
#endif
#endif /* _LIBSPL_LIMITS_H */

View file

@ -1,35 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include_next <locale.h>
#ifndef _LIBSPL_LOCALE_H
#define _LIBSPL_LOCALE_H
#include <time.h>
#include <sys/time.h>
#endif

View file

@ -43,7 +43,7 @@
#include <sys/endian.h>
#include <netinet/in.h>
#include <sys/isa_defs.h>
#include <sys/int_types.h>
#include <inttypes.h>
#if defined(__GNUC__) && defined(_ASM_INLINES) && \
(defined(__i386) || defined(__amd64))

View file

@ -79,7 +79,7 @@ extern int _sol_getmntent(FILE *fp, struct mnttab *mp);
extern int getextmntent(const char *path, struct extmnttab *entry,
struct stat64 *statbuf);
extern void statfs2mnttab(struct statfs *sfs, struct mnttab *mp);
char *hasmntopt(struct mnttab *mnt, char *opt);
int getmntent(FILE *fp, struct mnttab *mp);
extern char *hasmntopt(struct mnttab *mnt, char *opt);
extern int getmntent(FILE *fp, struct mnttab *mp);
#endif

View file

@ -30,6 +30,5 @@
#define ZFS_CONTEXT_OS_H_
#define HAVE_LARGE_STACKS 1
#define ZFS_EXPORTS_PATH "/etc/zfs/exports"
#endif

View file

@ -46,7 +46,7 @@
#endif
#include <sys/isa_defs.h>
#include <sys/int_types.h>
#include <inttypes.h>
#ifdef __cplusplus
extern "C" {

View file

@ -1,25 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
#ifndef _LIBSPL_STROPTS_H
#define _LIBSPL_STROPTS_H
#endif /* _LIBSPL_STROPTS_H */

View file

@ -1,30 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBSPL_SYS_INT_LIMITS_H
#define _LIBSPL_SYS_INT_LIMITS_H
#endif

View file

@ -1,32 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SOL_SYS_INT_TYPES_H
#define _SOL_SYS_INT_TYPES_H
#include <inttypes.h>
#endif

View file

@ -92,39 +92,6 @@ typedef struct kstat {
void *ks_lock; /* protects this kstat's data */
} kstat_t;
#ifdef _SYSCALL32
typedef int32_t kid32_t;
typedef struct kstat32 {
/*
* Fields relevant to both kernel and user
*/
hrtime_t ks_crtime;
caddr32_t ks_next; /* struct kstat pointer */
kid32_t ks_kid;
char ks_module[KSTAT_STRLEN];
uint8_t ks_resv;
int32_t ks_instance;
char ks_name[KSTAT_STRLEN];
uint8_t ks_type;
char ks_class[KSTAT_STRLEN];
uint8_t ks_flags;
caddr32_t ks_data; /* type-specific data */
uint32_t ks_ndata;
size32_t ks_data_size;
hrtime_t ks_snaptime;
/*
* Fields relevant to kernel only (only needed here for padding)
*/
int32_t _ks_update;
caddr32_t _ks_private;
int32_t _ks_snapshot;
caddr32_t _ks_lock;
} kstat32_t;
#endif /* _SYSCALL32 */
/*
* kstat structure and locking strategy
*
@ -467,7 +434,7 @@ typedef struct kstat_named {
* 64-bit compilation environments or 32-bit non-maximally conformant
* C89 or C90 ANSI C compilation environments (cc -Xt and cc -Xa). In the
* C99 ANSI C compilation environment, the long long type is supported.
* The _INT64_TYPE is defined by the implementation (see sys/int_types.h).
* The _INT64_TYPE is defined by the implementation (see sys/inttypes.h).
*/
#if defined(_INT64_TYPE)
int64_t i64;

View file

@ -1,29 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBSPL_SYS_STROPTS_H
#define _LIBSPL_SYS_STROPTS_H
#endif /* _LIBSPL_SYS_STROPTS_H */

View file

@ -37,7 +37,7 @@
#include <sys/feature_tests.h>
#include_next <sys/types.h>
#include <sys/types32.h>
#include <sys/va_list.h>
#include <stdarg.h>
#include <sys/stdtypes.h>
#ifndef HAVE_INTTYPES

View file

@ -1,164 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* from Arthur Olson's 6.1
*/
#ifndef _LIBSPL_SYS_TZFILE_H
#define _LIBSPL_SYS_TZFILE_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Information about time zone files.
*/
#define TZDIR "/usr/share/lib/zoneinfo" /* Time zone object file directory */
#define TZDEFAULT (getenv("TZ"))
#define TZDEFRULES "posixrules"
/*
* Each file begins with. . .
*/
struct tzhead {
char tzh_reserved[24]; /* reserved for future use */
char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
char tzh_leapcnt[4]; /* coded number of leap seconds */
char tzh_timecnt[4]; /* coded number of transition times */
char tzh_typecnt[4]; /* coded number of local time types */
char tzh_charcnt[4]; /* coded number of abbr. chars */
};
/*
* . . .followed by. . .
*
* tzh_timecnt (char [4])s coded transition times a la time(2)
* tzh_timecnt (unsigned char)s types of local time starting at above
* tzh_typecnt repetitions of
* one (char [4]) coded GMT offset in seconds
* one (unsigned char) used to set tm_isdst
* one (unsigned char) that's an abbreviation list index
* tzh_charcnt (char)s '\0'-terminated zone abbreviations
* tzh_leapcnt repetitions of
* one (char [4]) coded leap second transition times
* one (char [4]) total correction after above
* tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition
* time is standard time, if FALSE,
* transition time is wall clock time
* if absent, transition times are
* assumed to be wall clock time
*/
/*
* In the current implementation, "tzset()" refuses to deal with files that
* exceed any of the limits below.
*/
/*
* The TZ_MAX_TIMES value below is enough to handle a bit more than a
* year's worth of solar time (corrected daily to the nearest second) or
* 138 years of Pacific Presidential Election time
* (where there are three time zone transitions every fourth year).
*/
#define TZ_MAX_TIMES 370
#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
#define SECSPERMIN 60
#define MINSPERHOUR 60
#define HOURSPERDAY 24
#define DAYSPERWEEK 7
#define DAYSPERNYEAR 365
#define DAYSPERLYEAR 366
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
#define SECSPERDAY ((long)SECSPERHOUR * HOURSPERDAY)
#define MONSPERYEAR 12
#define TM_SUNDAY 0
#define TM_MONDAY 1
#define TM_TUESDAY 2
#define TM_WEDNESDAY 3
#define TM_THURSDAY 4
#define TM_FRIDAY 5
#define TM_SATURDAY 6
#define TM_JANUARY 0
#define TM_FEBRUARY 1
#define TM_MARCH 2
#define TM_APRIL 3
#define TM_MAY 4
#define TM_JUNE 5
#define TM_JULY 6
#define TM_AUGUST 7
#define TM_SEPTEMBER 8
#define TM_OCTOBER 9
#define TM_NOVEMBER 10
#define TM_DECEMBER 11
#define TM_YEAR_BASE 1900
#define EPOCH_YEAR 1970
#define EPOCH_WDAY TM_THURSDAY
/*
* Accurate only for the past couple of centuries;
* that will probably do.
*/
#define isleap(y) (((y) % 4) == 0 && ((y) % 100) != 0 || ((y) % 400) == 0)
/*
* Use of the underscored variants may cause problems if you move your code to
* certain System-V-based systems; for maximum portability, use the
* underscore-free variants. The underscored variants are provided for
* backward compatibility only; they may disappear from future versions of
* this file.
*/
#define SECS_PER_MIN SECSPERMIN
#define MINS_PER_HOUR MINSPERHOUR
#define HOURS_PER_DAY HOURSPERDAY
#define DAYS_PER_WEEK DAYSPERWEEK
#define DAYS_PER_NYEAR DAYSPERNYEAR
#define DAYS_PER_LYEAR DAYSPERLYEAR
#define SECS_PER_HOUR SECSPERHOUR
#define SECS_PER_DAY SECSPERDAY
#define MONS_PER_YEAR MONSPERYEAR
#ifdef __cplusplus
}
#endif
#endif /* _LIBSPL_SYS_TZFILE_H */

View file

@ -1,32 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_VA_LIST_H
#define _SYS_VA_LIST_H
#include <stdarg.h>
#endif

View file

@ -1,30 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBSPL_SYS_VARARGS_H
#define _LIBSPL_SYS_VARARGS_H
#endif

View file

@ -1,30 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBSPL_THREAD_H
#define _LIBSPL_THREAD_H
#endif /* _LIBSPL_THREAD_H */

View file

@ -1,32 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBSPL_TZFILE_H
#define _LIBSPL_TZFILE_H
#include <sys/tzfile.h>
#endif /* _LIBSPL_TZFILE_H */

View file

@ -1,32 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBSPL_UCRED_H
#define _LIBSPL_UCRED_H
typedef int ucred_t;
#endif

View file

@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <ctype.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -136,6 +137,7 @@ statfs2mnttab(struct statfs *sfs, struct mnttab *mp)
mp->mnt_mntopts = gmntopts;
}
static pthread_rwlock_t gsfs_lock = PTHREAD_RWLOCK_INITIALIZER;
static struct statfs *gsfs = NULL;
static int allfs = 0;
@ -145,6 +147,8 @@ statfs_init(void)
struct statfs *sfs;
int error;
(void) pthread_rwlock_wrlock(&gsfs_lock);
if (gsfs != NULL) {
free(gsfs);
gsfs = NULL;
@ -162,6 +166,7 @@ statfs_init(void)
sfs = realloc(gsfs, allfs * sizeof (gsfs[0]));
if (sfs != NULL)
gsfs = sfs;
(void) pthread_rwlock_unlock(&gsfs_lock);
return (0);
fail:
error = errno;
@ -169,6 +174,7 @@ statfs_init(void)
free(gsfs);
gsfs = NULL;
allfs = 0;
(void) pthread_rwlock_unlock(&gsfs_lock);
return (error);
}
@ -181,6 +187,8 @@ getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
if (error != 0)
return (error);
(void) pthread_rwlock_rdlock(&gsfs_lock);
for (i = 0; i < allfs; i++) {
if (mrefp->mnt_special != NULL &&
strcmp(mrefp->mnt_special, gsfs[i].f_mntfromname) != 0) {
@ -195,8 +203,10 @@ getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
continue;
}
statfs2mnttab(&gsfs[i], mgetp);
(void) pthread_rwlock_unlock(&gsfs_lock);
return (0);
}
(void) pthread_rwlock_unlock(&gsfs_lock);
return (-1);
}
@ -214,9 +224,13 @@ getmntent(FILE *fp, struct mnttab *mp)
if (error != 0)
return (error);
}
if (nfs >= allfs)
(void) pthread_rwlock_rdlock(&gsfs_lock);
if (nfs >= allfs) {
(void) pthread_rwlock_unlock(&gsfs_lock);
return (-1);
}
statfs2mnttab(&gsfs[nfs], mp);
(void) pthread_rwlock_unlock(&gsfs_lock);
if (lseek(fileno(fp), 1, SEEK_CUR) == -1)
return (errno);
return (0);

View file

@ -26,4 +26,4 @@ endif
libuutil_la_LDFLAGS += -version-info 3:0:0
EXTRA_DIST += $(addprefix %D%/,libuutil.abi libuutil.suppr)
dist_noinst_DATA += %D%/libuutil.abi %D%/libuutil.suppr

View file

@ -76,5 +76,5 @@ libzfs_la_LDFLAGS += -version-info 5:0:1
pkgconfig_DATA += %D%/libzfs.pc
EXTRA_DIST += $(addprefix %D%/,libzfs.abi libzfs.suppr)
EXTRA_DIST += $(addprefix %D%/,THIRDPARTYLICENSE.openssl THIRDPARTYLICENSE.openssl.descrip)
dist_noinst_DATA += %D%/libzfs.abi %D%/libzfs.suppr
dist_noinst_DATA += %D%/THIRDPARTYLICENSE.openssl %D%/THIRDPARTYLICENSE.openssl.descrip

File diff suppressed because it is too large Load diff

View file

@ -49,7 +49,6 @@
#include <sys/mount.h>
#include <pwd.h>
#include <grp.h>
#include <ucred.h>
#ifdef HAVE_IDMAP
#include <idmap.h>
#include <aclutils.h>

View file

@ -41,7 +41,6 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stropts.h>
#include <pthread.h>
#include <sys/zfs_ioctl.h>
#include <libzfs.h>

View file

@ -1910,37 +1910,30 @@ zprop_iter(zprop_func func, void *cb, boolean_t show_all, boolean_t ordered,
return (zprop_iter_common(func, cb, show_all, ordered, type));
}
/*
* Fill given version buffer with zfs userland version
*/
void
zfs_version_userland(char *version, int len)
const char *
zfs_version_userland(void)
{
(void) strlcpy(version, ZFS_META_ALIAS, len);
return (ZFS_META_ALIAS);
}
/*
* Prints both zfs userland and kernel versions
* Returns 0 on success, and -1 on error (with errno set)
* Returns 0 on success, and -1 on error
*/
int
zfs_version_print(void)
{
char zver_userland[128];
char zver_kernel[128];
(void) puts(ZFS_META_ALIAS);
zfs_version_userland(zver_userland, sizeof (zver_userland));
(void) printf("%s\n", zver_userland);
if (zfs_version_kernel(zver_kernel, sizeof (zver_kernel)) == -1) {
char *kver = zfs_version_kernel();
if (kver == NULL) {
fprintf(stderr, "zfs_version_kernel() failed: %s\n",
strerror(errno));
return (-1);
}
(void) printf("zfs-kmod-%s\n", zver_kernel);
(void) printf("zfs-kmod-%s\n", kver);
free(kver);
return (0);
}

View file

@ -351,14 +351,22 @@ zpool_nextboot(libzfs_handle_t *hdl, uint64_t pool_guid, uint64_t dev_guid,
}
/*
* Fill given version buffer with zfs kernel version.
* Returns 0 on success, and -1 on error (with errno set)
* Return allocated loaded module version, or NULL on error (with errno set)
*/
int
zfs_version_kernel(char *version, int len)
char *
zfs_version_kernel(void)
{
size_t l = len;
return (sysctlbyname("vfs.zfs.version.module",
version, &l, NULL, 0));
size_t l;
if (sysctlbyname("vfs.zfs.version.module",
NULL, &l, NULL, 0) == -1)
return (NULL);
char *version = malloc(l);
if (version == NULL)
return (NULL);
if (sysctlbyname("vfs.zfs.version.module",
version, &l, NULL, 0) == -1) {
free(version);
return (NULL);
}
return (version);
}

View file

@ -20,20 +20,24 @@
*/
#include <alloca.h>
#include <errno.h>
#include <fcntl.h>
#include <libintl.h>
#include <math.h>
#include <poll.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <math.h>
#include <sys/stat.h>
#include <sys/mnttab.h>
#include <sys/inotify.h>
#include <sys/mntent.h>
#include <sys/mnttab.h>
#include <sys/stat.h>
#include <sys/timerfd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <libzfs.h>
#include <libzfs_core.h>
@ -57,7 +61,7 @@ libzfs_error_init(int error)
switch (error) {
case ENXIO:
return (dgettext(TEXT_DOMAIN, "The ZFS modules are not "
"loaded.\nTry running '/sbin/modprobe zfs' as root "
"loaded.\nTry running 'modprobe zfs' as root "
"to load them."));
case ENOENT:
return (dgettext(TEXT_DOMAIN, "/dev/zfs and /proc/self/mounts "
@ -65,7 +69,7 @@ libzfs_error_init(int error)
"-t proc proc /proc' as root."));
case ENOEXEC:
return (dgettext(TEXT_DOMAIN, "The ZFS modules cannot be "
"auto-loaded.\nTry running '/sbin/modprobe zfs' as "
"auto-loaded.\nTry running 'modprobe zfs' as "
"root to manually load them."));
case EACCES:
return (dgettext(TEXT_DOMAIN, "Permission denied the "
@ -76,93 +80,80 @@ libzfs_error_init(int error)
}
}
static int
libzfs_module_loaded(const char *module)
{
const char path_prefix[] = "/sys/module/";
char path[256];
memcpy(path, path_prefix, sizeof (path_prefix) - 1);
strcpy(path + sizeof (path_prefix) - 1, module);
return (access(path, F_OK) == 0);
}
/*
* Verify the required ZFS_DEV device is available and optionally attempt
* to load the ZFS modules. Under normal circumstances the modules
* should already have been loaded by some external mechanism.
* zfs(4) is loaded by udev if there's a fstype=zfs device present,
* but if there isn't, load them automatically;
* always wait for ZFS_DEV to appear via udev.
*
* Environment variables:
* - ZFS_MODULE_LOADING="YES|yes|ON|on" - Attempt to load modules.
* - ZFS_MODULE_TIMEOUT="<seconds>" - Seconds to wait for ZFS_DEV
* - ZFS_MODULE_TIMEOUT="<seconds>" - Seconds to wait for ZFS_DEV,
* defaults to 10, max. 10 min.
*/
static int
libzfs_load_module_impl(const char *module)
{
char *argv[4] = {"/sbin/modprobe", "-q", (char *)module, (char *)0};
char *load_str, *timeout_str;
long timeout = 10; /* seconds */
long busy_timeout = 10; /* milliseconds */
int load = 0, fd;
hrtime_t start;
/* Optionally request module loading */
if (!libzfs_module_loaded(module)) {
load_str = getenv("ZFS_MODULE_LOADING");
if (load_str) {
if (!strncasecmp(load_str, "YES", strlen("YES")) ||
!strncasecmp(load_str, "ON", strlen("ON")))
load = 1;
else
load = 0;
}
if (load) {
if (libzfs_run_process("/sbin/modprobe", argv, 0))
return (ENOEXEC);
}
if (!libzfs_module_loaded(module))
return (ENXIO);
}
/*
* Device creation by udev is asynchronous and waiting may be
* required. Busy wait for 10ms and then fall back to polling every
* 10ms for the allowed timeout (default 10s, max 10m). This is
* done to optimize for the common case where the device is
* immediately available and to avoid penalizing the possible
* case where udev is slow or unable to create the device.
*/
timeout_str = getenv("ZFS_MODULE_TIMEOUT");
if (timeout_str) {
timeout = strtol(timeout_str, NULL, 0);
timeout = MAX(MIN(timeout, (10 * 60)), 0); /* 0 <= N <= 600 */
}
start = gethrtime();
do {
fd = open(ZFS_DEV, O_RDWR | O_CLOEXEC);
if (fd >= 0) {
(void) close(fd);
return (0);
} else if (errno != ENOENT) {
return (errno);
} else if (NSEC2MSEC(gethrtime() - start) < busy_timeout) {
sched_yield();
} else {
usleep(10 * MILLISEC);
}
} while (NSEC2MSEC(gethrtime() - start) < (timeout * MILLISEC));
return (ENOENT);
}
int
libzfs_load_module(void)
{
return (libzfs_load_module_impl(ZFS_DRIVER));
if (access(ZFS_DEV, F_OK) == 0)
return (0);
if (access(ZFS_SYSFS_DIR, F_OK) != 0) {
char *argv[] = {"modprobe", "zfs", NULL};
if (libzfs_run_process("modprobe", argv, 0))
return (ENOEXEC);
if (access(ZFS_SYSFS_DIR, F_OK) != 0)
return (ENXIO);
}
const char *timeout_str = getenv("ZFS_MODULE_TIMEOUT");
int seconds = 10;
if (timeout_str)
seconds = MIN(strtol(timeout_str, NULL, 0), 600);
struct itimerspec timeout = {.it_value.tv_sec = MAX(seconds, 0)};
int ino = inotify_init1(IN_CLOEXEC);
if (ino == -1)
return (ENOENT);
inotify_add_watch(ino, ZFS_DEVDIR, IN_CREATE);
if (access(ZFS_DEV, F_OK) == 0) {
close(ino);
return (0);
} else if (seconds == 0) {
close(ino);
return (ENOENT);
}
size_t evsz = sizeof (struct inotify_event) + NAME_MAX + 1;
struct inotify_event *ev = alloca(evsz);
int tout = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
if (tout == -1) {
close(ino);
return (ENOENT);
}
timerfd_settime(tout, 0, &timeout, NULL);
int ret = ENOENT;
struct pollfd pfds[] = {
{.fd = ino, .events = POLLIN},
{.fd = tout, .events = POLLIN},
};
while (poll(pfds, ARRAY_SIZE(pfds), -1) != -1) {
if (pfds[0].revents & POLLIN) {
verify(read(ino, ev, evsz) >
sizeof (struct inotify_event));
if (strcmp(ev->name, &ZFS_DEV[sizeof (ZFS_DEVDIR)])
== 0) {
ret = 0;
break;
}
}
if (pfds[1].revents & POLLIN)
break;
}
close(tout);
close(ino);
return (ret);
}
int
@ -192,31 +183,27 @@ zfs_destroy_snaps_nvl_os(libzfs_handle_t *hdl, nvlist_t *snaps)
}
/*
* Fill given version buffer with zfs kernel version read from ZFS_SYSFS_DIR
* Returns 0 on success, and -1 on error (with errno set)
* Return allocated loaded module version, or NULL on error (with errno set)
*/
int
zfs_version_kernel(char *version, int len)
char *
zfs_version_kernel(void)
{
int _errno;
int fd;
int rlen;
FILE *f = fopen(ZFS_SYSFS_DIR "/version", "re");
if (f == NULL)
return (NULL);
if ((fd = open(ZFS_SYSFS_DIR "/version", O_RDONLY | O_CLOEXEC)) == -1)
return (-1);
if ((rlen = read(fd, version, len)) == -1) {
version[0] = '\0';
_errno = errno;
(void) close(fd);
errno = _errno;
return (-1);
char *ret = NULL;
size_t l;
ssize_t read;
if ((read = getline(&ret, &l, f)) == -1) {
int err = errno;
fclose(f);
errno = err;
return (NULL);
}
version[rlen-1] = '\0'; /* discard '\n' */
if (close(fd) == -1)
return (-1);
return (0);
fclose(f);
if (ret[read - 1] == '\n')
ret[read - 1] = '\0';
return (ret);
}

View file

@ -43,4 +43,4 @@ libzfs_core_la_LDFLAGS += -version-info 3:0:0
pkgconfig_DATA += %D%/libzfs_core.pc
EXTRA_DIST += $(addprefix %D%/,libzfs_core.abi libzfs_core.suppr)
dist_noinst_DATA += %D%/libzfs_core.abi %D%/libzfs_core.suppr

View file

@ -26,4 +26,4 @@ libzfsbootenv_la_LDFLAGS += -version-info 1:0:0
pkgconfig_DATA += %D%/libzfsbootenv.pc
EXTRA_DIST += $(addprefix %D%/,libzfsbootenv.abi libzfsbootenv.suppr)
dist_noinst_DATA += %D%/libzfsbootenv.abi %D%/libzfsbootenv.suppr

View file

@ -1,4 +1,4 @@
EXTRA_DIST += \
dist_noinst_man_MANS = \
%D%/man1/cstyle.1
dist_man_MANS = \
@ -105,8 +105,9 @@ nodist_man_MANS = \
%D%/man8/zed.8 \
%D%/man8/zfs-mount-generator.8
SUBSTFILES += $(nodist_man_MANS)
dist_noinst_DATA += $(dist_noinst_man_MANS) $(dist_man_MANS)
SUBSTFILES += $(nodist_man_MANS)
CHECKS += mancheck
mancheck:

View file

@ -487,7 +487,15 @@ However, this is limited by
.It Sy zfetch_array_rd_sz Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq ulong
If prefetching is enabled, disable prefetching for reads larger than this size.
.
.It Sy zfetch_max_distance Ns = Ns Sy 8388608 Ns B Po 8 MiB Pc Pq uint
.It Sy zfetch_min_distance Ns = Ns Sy 4194304 Ns B Po 4 MiB Pc Pq uint
Min bytes to prefetch per stream.
Prefetch distance starts from the demand access size and quickly grows to
this value, doubling on each hit.
After that it may grow further by 1/8 per hit, but only if some prefetch
since last time haven't completed in time to satisfy demand request, i.e.
prefetch depth didn't cover the read latency or the pool got saturated.
.
.It Sy zfetch_max_distance Ns = Ns Sy 67108864 Ns B Po 64 MiB Pc Pq uint
Max bytes to prefetch per stream.
.
.It Sy zfetch_max_idistance Ns = Ns Sy 67108864 Ns B Po 64 MiB Pc Pq uint
@ -496,8 +504,11 @@ Max bytes to prefetch indirects for per stream.
.It Sy zfetch_max_streams Ns = Ns Sy 8 Pq uint
Max number of streams per zfetch (prefetch streams per file).
.
.It Sy zfetch_min_sec_reap Ns = Ns Sy 2 Pq uint
Min time before an active prefetch stream can be reclaimed
.It Sy zfetch_min_sec_reap Ns = Ns Sy 1 Pq uint
Min time before inactive prefetch stream can be reclaimed
.
.It Sy zfetch_max_sec_reap Ns = Ns Sy 2 Pq uint
Max time before inactive prefetch stream can be deleted
.
.It Sy zfs_abd_scatter_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int
Enables ARC from using scatter/gather lists and forces all allocations to be
@ -1098,10 +1109,9 @@ This should be less than
.
.It Sy zfs_wrlog_data_max Ns = Pq int
The upper limit of write-transaction zil log data size in bytes.
Once it is reached, write operation is blocked, until log data is cleared out
after transaction group sync.
Because of some overhead, it should be set
at least 2 times the size of
Write operations are throttled when approaching the limit until log data is
cleared out after transaction group sync.
Because of some overhead, it should be set at least 2 times the size of
.Sy zfs_dirty_data_max
.No to prevent harming normal write throughput.
It also should be smaller than the size of the slog device if slog is present.
@ -2129,6 +2139,14 @@ However, if there are fewer than
metaslabs in the vdev, this functionality is disabled.
This ensures that we don't set aside an unreasonable amount of space for the ZIL.
.
.It Sy zstd_earlyabort_pass Ns = Ns Sy 1 Pq int
Whether heuristic for detection of incompressible data with zstd levels >= 3
using LZ4 and zstd-1 passes is enabled.
.
.It Sy zstd_abort_size Ns = Ns Sy 131072 Pq int
Minimal uncompressed size (inclusive) of a record before the early abort
heuristic will be attempted.
.
.It Sy zio_deadman_log_all Ns = Ns Sy 0 Ns | Ns 1 Pq int
If non-zero, the zio deadman will produce debugging messages
.Pq see Sy zfs_dbgmsg_enable

View file

@ -736,7 +736,7 @@ Do note that any changes done with the
command will be undone if the share is ever unshared (like via a reboot).
.
.Sh ENVIRONMENT VARIABLES
.Bl -tag -width "ZFS_MOUNT_HELPER"
.Bl -tag -width "ZFS_MODULE_TIMEOUT"
.It Sy ZFS_MOUNT_HELPER
Cause
.Nm zfs Cm mount
@ -744,14 +744,28 @@ to use
.Xr mount 8
to mount ZFS datasets.
This option is provided for backwards compatibility with older ZFS versions.
.El
.Bl -tag -width "ZFS_SET_PIPE_MAX"
.
.It Sy ZFS_SET_PIPE_MAX
Tells
.Nm zfs
to set the maximum pipe size for sends/recieves.
Disabled by default on Linux
due to an unfixed deadlock in Linux's pipe size handling code.
.
.\" Shared with zpool.8
.It Sy ZFS_MODULE_TIMEOUT
Time, in seconds, to wait for
.Pa /dev/zfs
to appear.
Defaults to
.Sy 10 ,
max
.Sy 600 Pq 10 minutes .
If
.Pf < Sy 0 ,
wait forever; if
.Sy 0 ,
don't wait.
.El
.
.Sh INTERFACE STABILITY

View file

@ -524,6 +524,20 @@ If
.Sy ZPOOL_SCRIPTS_ENABLED
is not set, it is assumed that the user is allowed to run
.Nm zpool Cm status Ns / Ns Cm iostat Fl c .
.\" Shared with zfs.8
.It Sy ZFS_MODULE_TIMEOUT
Time, in seconds, to wait for
.Pa /dev/zfs
to appear.
Defaults to
.Sy 10 ,
max
.Sy 600 Pq 10 minutes .
If
.Pf < Sy 0 ,
wait forever; if
.Sy 0 ,
don't wait.
.El
.
.Sh INTERFACE STABILITY

View file

@ -304,8 +304,6 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
rw_exit(&vd->vd_lock);
}
struct request_queue *q = bdev_get_queue(vd->vd_bdev);
/* Determine the physical block size */
int physical_block_size = bdev_physical_block_size(vd->vd_bdev);
@ -316,13 +314,13 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
v->vdev_nowritecache = B_FALSE;
/* Set when device reports it supports TRIM. */
v->vdev_has_trim = !!blk_queue_discard(q);
v->vdev_has_trim = bdev_discard_supported(vd->vd_bdev);
/* Set when device reports it supports secure TRIM. */
v->vdev_has_securetrim = !!blk_queue_discard_secure(q);
v->vdev_has_securetrim = bdev_secure_discard_supported(vd->vd_bdev);
/* Inform the ZIO pipeline that we are non-rotational */
v->vdev_nonrot = blk_queue_nonrot(q);
v->vdev_nonrot = blk_queue_nonrot(bdev_get_queue(vd->vd_bdev));
/* Physical volume size in bytes for the partition */
*psize = bdev_capacity(vd->vd_bdev);
@ -460,6 +458,13 @@ vdev_submit_bio_impl(struct bio *bio)
#define preempt_schedule_notrace(x) preempt_schedule(x)
#endif
/*
* As for the Linux 5.18 kernel bio_alloc() expects a block_device struct
* as an argument removing the need to set it with bio_set_dev(). This
* removes the need for all of the following compatibility code.
*/
#if !defined(HAVE_BIO_ALLOC_4ARG)
#ifdef HAVE_BIO_SET_DEV
#if defined(CONFIG_BLK_CGROUP) && defined(HAVE_BIO_SET_DEV_GPL_ONLY)
/*
@ -556,6 +561,7 @@ bio_set_dev(struct bio *bio, struct block_device *bdev)
bio->bi_bdev = bdev;
}
#endif /* HAVE_BIO_SET_DEV */
#endif /* !HAVE_BIO_ALLOC_4ARG */
static inline void
vdev_submit_bio(struct bio *bio)
@ -566,10 +572,36 @@ vdev_submit_bio(struct bio *bio)
current->bio_list = bio_list;
}
static inline struct bio *
vdev_bio_alloc(struct block_device *bdev, gfp_t gfp_mask,
unsigned short nr_vecs)
{
struct bio *bio;
#ifdef HAVE_BIO_ALLOC_4ARG
#define bio_alloc(gfp_mask, nr_iovecs) bio_alloc(NULL, nr_iovecs, 0, gfp_mask)
bio = bio_alloc(bdev, nr_vecs, 0, gfp_mask);
#else
bio = bio_alloc(gfp_mask, nr_vecs);
if (likely(bio != NULL))
bio_set_dev(bio, bdev);
#endif
return (bio);
}
static inline unsigned int
vdev_bio_max_segs(zio_t *zio, int bio_size, uint64_t abd_offset)
{
unsigned long nr_segs = abd_nr_pages_off(zio->io_abd,
bio_size, abd_offset);
#ifdef HAVE_BIO_MAX_SEGS
return (bio_max_segs(nr_segs));
#else
return (MIN(nr_segs, BIO_MAX_PAGES));
#endif
}
static int
__vdev_disk_physio(struct block_device *bdev, zio_t *zio,
size_t io_size, uint64_t io_offset, int rw, int flags)
@ -581,6 +613,7 @@ __vdev_disk_physio(struct block_device *bdev, zio_t *zio,
int bio_count = 16;
int error = 0;
struct blk_plug plug;
unsigned short nr_vecs;
/*
* Accessing outside the block device is never allowed.
@ -632,15 +665,8 @@ __vdev_disk_physio(struct block_device *bdev, zio_t *zio,
goto retry;
}
/* bio_alloc() with __GFP_WAIT never returns NULL */
#ifdef HAVE_BIO_MAX_SEGS
dr->dr_bio[i] = bio_alloc(GFP_NOIO, bio_max_segs(
abd_nr_pages_off(zio->io_abd, bio_size, abd_offset)));
#else
dr->dr_bio[i] = bio_alloc(GFP_NOIO,
MIN(abd_nr_pages_off(zio->io_abd, bio_size, abd_offset),
BIO_MAX_PAGES));
#endif
nr_vecs = vdev_bio_max_segs(zio, bio_size, abd_offset);
dr->dr_bio[i] = vdev_bio_alloc(bdev, GFP_NOIO, nr_vecs);
if (unlikely(dr->dr_bio[i] == NULL)) {
vdev_disk_dio_free(dr);
return (SET_ERROR(ENOMEM));
@ -649,7 +675,6 @@ __vdev_disk_physio(struct block_device *bdev, zio_t *zio,
/* Matching put called by vdev_disk_physio_completion */
vdev_disk_dio_get(dr);
bio_set_dev(dr->dr_bio[i], bdev);
BIO_BI_SECTOR(dr->dr_bio[i]) = bio_offset >> 9;
dr->dr_bio[i]->bi_end_io = vdev_disk_physio_completion;
dr->dr_bio[i]->bi_private = dr;
@ -713,14 +738,12 @@ vdev_disk_io_flush(struct block_device *bdev, zio_t *zio)
if (!q)
return (SET_ERROR(ENXIO));
bio = bio_alloc(GFP_NOIO, 0);
/* bio_alloc() with __GFP_WAIT never returns NULL */
bio = vdev_bio_alloc(bdev, GFP_NOIO, 0);
if (unlikely(bio == NULL))
return (SET_ERROR(ENOMEM));
bio->bi_end_io = vdev_disk_io_flush_completion;
bio->bi_private = zio;
bio_set_dev(bio, bdev);
bio_set_flush(bio);
vdev_submit_bio(bio);
invalidate_bdev(bdev);
@ -728,12 +751,38 @@ vdev_disk_io_flush(struct block_device *bdev, zio_t *zio)
return (0);
}
static int
vdev_disk_io_trim(zio_t *zio)
{
vdev_t *v = zio->io_vd;
vdev_disk_t *vd = v->vdev_tsd;
#if defined(HAVE_BLKDEV_ISSUE_SECURE_ERASE)
if (zio->io_trim_flags & ZIO_TRIM_SECURE) {
return (-blkdev_issue_secure_erase(vd->vd_bdev,
zio->io_offset >> 9, zio->io_size >> 9, GFP_NOFS));
} else {
return (-blkdev_issue_discard(vd->vd_bdev,
zio->io_offset >> 9, zio->io_size >> 9, GFP_NOFS));
}
#elif defined(HAVE_BLKDEV_ISSUE_DISCARD)
unsigned long trim_flags = 0;
#if defined(BLKDEV_DISCARD_SECURE)
if (zio->io_trim_flags & ZIO_TRIM_SECURE)
trim_flags |= BLKDEV_DISCARD_SECURE;
#endif
return (-blkdev_issue_discard(vd->vd_bdev,
zio->io_offset >> 9, zio->io_size >> 9, GFP_NOFS, trim_flags));
#else
#error "Unsupported kernel"
#endif
}
static void
vdev_disk_io_start(zio_t *zio)
{
vdev_t *v = zio->io_vd;
vdev_disk_t *vd = v->vdev_tsd;
unsigned long trim_flags = 0;
int rw, error;
/*
@ -806,14 +855,7 @@ vdev_disk_io_start(zio_t *zio)
break;
case ZIO_TYPE_TRIM:
#if defined(BLKDEV_DISCARD_SECURE)
if (zio->io_trim_flags & ZIO_TRIM_SECURE)
trim_flags |= BLKDEV_DISCARD_SECURE;
#endif
zio->io_error = -blkdev_issue_discard(vd->vd_bdev,
zio->io_offset >> 9, zio->io_size >> 9, GFP_NOFS,
trim_flags);
zio->io_error = vdev_disk_io_trim(zio);
rw_exit(&vd->vd_lock);
zio_interrupt(zio);
return;

View file

@ -674,11 +674,19 @@ zpl_readpage_common(struct page *pp)
return (error);
}
#ifdef HAVE_VFS_READ_FOLIO
static int
zpl_read_folio(struct file *filp, struct folio *folio)
{
return (zpl_readpage_common(&folio->page));
}
#else
static int
zpl_readpage(struct file *filp, struct page *pp)
{
return (zpl_readpage_common(pp));
}
#endif
static int
zpl_readpage_filler(void *data, struct page *pp)
@ -1208,7 +1216,11 @@ const struct address_space_operations zpl_address_space_operations = {
#else
.readahead = zpl_readahead,
#endif
#ifdef HAVE_VFS_READ_FOLIO
.read_folio = zpl_read_folio,
#else
.readpage = zpl_readpage,
#endif
.writepage = zpl_writepage,
.writepages = zpl_writepages,
.direct_IO = zpl_direct_IO,

View file

@ -1053,7 +1053,9 @@ zvol_os_create_minor(const char *name)
(zvol_max_discard_blocks * zv->zv_volblocksize) >> 9);
blk_queue_discard_granularity(zv->zv_zso->zvo_queue,
zv->zv_volblocksize);
#ifdef QUEUE_FLAG_DISCARD
blk_queue_flag_set(QUEUE_FLAG_DISCARD, zv->zv_zso->zvo_queue);
#endif
#ifdef QUEUE_FLAG_NONROT
blk_queue_flag_set(QUEUE_FLAG_NONROT, zv->zv_zso->zvo_queue);
#endif

View file

@ -3185,8 +3185,10 @@ typedef struct dbuf_prefetch_arg {
static void
dbuf_prefetch_fini(dbuf_prefetch_arg_t *dpa, boolean_t io_done)
{
if (dpa->dpa_cb != NULL)
dpa->dpa_cb(dpa->dpa_arg, io_done);
if (dpa->dpa_cb != NULL) {
dpa->dpa_cb(dpa->dpa_arg, dpa->dpa_zb.zb_level,
dpa->dpa_zb.zb_blkid, io_done);
}
kmem_free(dpa, sizeof (*dpa));
}
@ -3320,7 +3322,8 @@ dbuf_prefetch_indirect_done(zio_t *zio, const zbookmark_phys_t *zb,
dpa->dpa_zb.zb_object, dpa->dpa_curlevel, nextblkid);
(void) arc_read(dpa->dpa_zio, dpa->dpa_spa,
bp, dbuf_prefetch_indirect_done, dpa, dpa->dpa_prio,
bp, dbuf_prefetch_indirect_done, dpa,
ZIO_PRIORITY_SYNC_READ,
ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE,
&iter_aflags, &zb);
}
@ -3455,7 +3458,8 @@ dbuf_prefetch_impl(dnode_t *dn, int64_t level, uint64_t blkid,
SET_BOOKMARK(&zb, ds != NULL ? ds->ds_object : DMU_META_OBJSET,
dn->dn_object, curlevel, curblkid);
(void) arc_read(dpa->dpa_zio, dpa->dpa_spa,
&bp, dbuf_prefetch_indirect_done, dpa, prio,
&bp, dbuf_prefetch_indirect_done, dpa,
ZIO_PRIORITY_SYNC_READ,
ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE,
&iter_aflags, &zb);
}
@ -3467,7 +3471,7 @@ dbuf_prefetch_impl(dnode_t *dn, int64_t level, uint64_t blkid,
return (1);
no_issue:
if (cb != NULL)
cb(arg, B_FALSE);
cb(arg, level, blkid, B_FALSE);
return (0);
}

View file

@ -53,8 +53,8 @@ dmu_tx_stats_t dmu_tx_stats = {
{ "dmu_tx_dirty_throttle", KSTAT_DATA_UINT64 },
{ "dmu_tx_dirty_delay", KSTAT_DATA_UINT64 },
{ "dmu_tx_dirty_over_max", KSTAT_DATA_UINT64 },
{ "dmu_tx_wrlog_over_max", KSTAT_DATA_UINT64 },
{ "dmu_tx_dirty_frees_delay", KSTAT_DATA_UINT64 },
{ "dmu_tx_wrlog_delay", KSTAT_DATA_UINT64 },
{ "dmu_tx_quota", KSTAT_DATA_UINT64 },
};
@ -779,34 +779,49 @@ static void
dmu_tx_delay(dmu_tx_t *tx, uint64_t dirty)
{
dsl_pool_t *dp = tx->tx_pool;
uint64_t delay_min_bytes =
zfs_dirty_data_max * zfs_delay_min_dirty_percent / 100;
hrtime_t wakeup, min_tx_time, now;
uint64_t delay_min_bytes, wrlog;
hrtime_t wakeup, tx_time = 0, now;
if (dirty <= delay_min_bytes)
/* Calculate minimum transaction time for the dirty data amount. */
delay_min_bytes =
zfs_dirty_data_max * zfs_delay_min_dirty_percent / 100;
if (dirty > delay_min_bytes) {
/*
* The caller has already waited until we are under the max.
* We make them pass us the amount of dirty data so we don't
* have to handle the case of it being >= the max, which
* could cause a divide-by-zero if it's == the max.
*/
ASSERT3U(dirty, <, zfs_dirty_data_max);
tx_time = zfs_delay_scale * (dirty - delay_min_bytes) /
(zfs_dirty_data_max - dirty);
}
/* Calculate minimum transaction time for the TX_WRITE log size. */
wrlog = aggsum_upper_bound(&dp->dp_wrlog_total);
delay_min_bytes =
zfs_wrlog_data_max * zfs_delay_min_dirty_percent / 100;
if (wrlog >= zfs_wrlog_data_max) {
tx_time = zfs_delay_max_ns;
} else if (wrlog > delay_min_bytes) {
tx_time = MAX(zfs_delay_scale * (wrlog - delay_min_bytes) /
(zfs_wrlog_data_max - wrlog), tx_time);
}
if (tx_time == 0)
return;
/*
* The caller has already waited until we are under the max.
* We make them pass us the amount of dirty data so we don't
* have to handle the case of it being >= the max, which could
* cause a divide-by-zero if it's == the max.
*/
ASSERT3U(dirty, <, zfs_dirty_data_max);
tx_time = MIN(tx_time, zfs_delay_max_ns);
now = gethrtime();
min_tx_time = zfs_delay_scale *
(dirty - delay_min_bytes) / (zfs_dirty_data_max - dirty);
min_tx_time = MIN(min_tx_time, zfs_delay_max_ns);
if (now > tx->tx_start + min_tx_time)
if (now > tx->tx_start + tx_time)
return;
DTRACE_PROBE3(delay__mintime, dmu_tx_t *, tx, uint64_t, dirty,
uint64_t, min_tx_time);
uint64_t, tx_time);
mutex_enter(&dp->dp_lock);
wakeup = MAX(tx->tx_start + min_tx_time,
dp->dp_last_wakeup + min_tx_time);
wakeup = MAX(tx->tx_start + tx_time, dp->dp_last_wakeup + tx_time);
dp->dp_last_wakeup = wakeup;
mutex_exit(&dp->dp_lock);
@ -884,8 +899,9 @@ dmu_tx_try_assign(dmu_tx_t *tx, uint64_t txg_how)
}
if (!tx->tx_dirty_delayed &&
dsl_pool_wrlog_over_max(tx->tx_pool)) {
DMU_TX_STAT_BUMP(dmu_tx_wrlog_over_max);
dsl_pool_need_wrlog_delay(tx->tx_pool)) {
tx->tx_wait_dirty = B_TRUE;
DMU_TX_STAT_BUMP(dmu_tx_wrlog_delay);
return (SET_ERROR(ERESTART));
}

View file

@ -48,9 +48,13 @@ static int zfs_prefetch_disable = B_FALSE;
/* max # of streams per zfetch */
static unsigned int zfetch_max_streams = 8;
/* min time before stream reclaim */
static unsigned int zfetch_min_sec_reap = 2;
/* max bytes to prefetch per stream (default 8MB) */
unsigned int zfetch_max_distance = 8 * 1024 * 1024;
static unsigned int zfetch_min_sec_reap = 1;
/* max time before stream delete */
static unsigned int zfetch_max_sec_reap = 2;
/* min bytes to prefetch per stream (default 4MB) */
static unsigned int zfetch_min_distance = 4 * 1024 * 1024;
/* max bytes to prefetch per stream (default 64MB) */
unsigned int zfetch_max_distance = 64 * 1024 * 1024;
/* max bytes to prefetch indirects for per stream (default 64MB) */
unsigned int zfetch_max_idistance = 64 * 1024 * 1024;
/* max number of bytes in an array_read in which we allow prefetching (1MB) */
@ -195,74 +199,99 @@ dmu_zfetch_fini(zfetch_t *zf)
}
/*
* If there aren't too many streams already, create a new stream.
* If there aren't too many active streams already, create one more.
* In process delete/reuse all streams without hits for zfetch_max_sec_reap.
* If needed, reuse oldest stream without hits for zfetch_min_sec_reap or ever.
* The "blkid" argument is the next block that we expect this stream to access.
* While we're here, clean up old streams (which haven't been
* accessed for at least zfetch_min_sec_reap seconds).
*/
static void
dmu_zfetch_stream_create(zfetch_t *zf, uint64_t blkid)
{
zstream_t *zs_next;
hrtime_t now = gethrtime();
zstream_t *zs, *zs_next, *zs_old = NULL;
hrtime_t now = gethrtime(), t;
ASSERT(MUTEX_HELD(&zf->zf_lock));
/*
* Clean up old streams.
* Delete too old streams, reusing the first found one.
*/
for (zstream_t *zs = list_head(&zf->zf_stream);
zs != NULL; zs = zs_next) {
t = now - SEC2NSEC(zfetch_max_sec_reap);
for (zs = list_head(&zf->zf_stream); zs != NULL; zs = zs_next) {
zs_next = list_next(&zf->zf_stream, zs);
/*
* Skip if still active. 1 -- zf_stream reference.
*/
if (zfs_refcount_count(&zs->zs_refs) != 1)
continue;
if (((now - zs->zs_atime) / NANOSEC) >
zfetch_min_sec_reap)
if (zs->zs_atime > t)
continue;
if (zs_old)
dmu_zfetch_stream_remove(zf, zs);
else
zs_old = zs;
}
if (zs_old) {
zs = zs_old;
goto reuse;
}
/*
* The maximum number of streams is normally zfetch_max_streams,
* but for small files we lower it such that it's at least possible
* for all the streams to be non-overlapping.
*
* If we are already at the maximum number of streams for this file,
* even after removing old streams, then don't create this stream.
*/
uint32_t max_streams = MAX(1, MIN(zfetch_max_streams,
zf->zf_dnode->dn_maxblkid * zf->zf_dnode->dn_datablksz /
zfetch_max_distance));
if (zf->zf_numstreams >= max_streams) {
t = now - SEC2NSEC(zfetch_min_sec_reap);
for (zs = list_head(&zf->zf_stream); zs != NULL;
zs = list_next(&zf->zf_stream, zs)) {
if (zfs_refcount_count(&zs->zs_refs) != 1)
continue;
if (zs->zs_atime > t)
continue;
if (zs_old == NULL || zs->zs_atime < zs_old->zs_atime)
zs_old = zs;
}
if (zs_old) {
zs = zs_old;
goto reuse;
}
ZFETCHSTAT_BUMP(zfetchstat_max_streams);
return;
}
zstream_t *zs = kmem_zalloc(sizeof (*zs), KM_SLEEP);
zs->zs_blkid = blkid;
zs->zs_pf_blkid1 = blkid;
zs->zs_pf_blkid = blkid;
zs->zs_ipf_blkid1 = blkid;
zs->zs_ipf_blkid = blkid;
zs->zs_atime = now;
zs = kmem_zalloc(sizeof (*zs), KM_SLEEP);
zs->zs_fetch = zf;
zs->zs_missed = B_FALSE;
zfs_refcount_create(&zs->zs_callers);
zfs_refcount_create(&zs->zs_refs);
/* One reference for zf_stream. */
zfs_refcount_add(&zs->zs_refs, NULL);
zf->zf_numstreams++;
list_insert_head(&zf->zf_stream, zs);
reuse:
zs->zs_blkid = blkid;
zs->zs_pf_dist = 0;
zs->zs_pf_start = blkid;
zs->zs_pf_end = blkid;
zs->zs_ipf_dist = 0;
zs->zs_ipf_start = blkid;
zs->zs_ipf_end = blkid;
/* Allow immediate stream reuse until first hit. */
zs->zs_atime = now - SEC2NSEC(zfetch_min_sec_reap);
zs->zs_missed = B_FALSE;
zs->zs_more = B_FALSE;
}
static void
dmu_zfetch_stream_done(void *arg, boolean_t io_issued)
dmu_zfetch_done(void *arg, uint64_t level, uint64_t blkid, boolean_t io_issued)
{
(void) io_issued;
zstream_t *zs = arg;
if (io_issued && level == 0 && blkid < zs->zs_blkid)
zs->zs_more = B_TRUE;
if (zfs_refcount_remove(&zs->zs_refs, NULL) == 0)
dmu_zfetch_stream_fini(zs);
}
@ -284,11 +313,6 @@ dmu_zfetch_prepare(zfetch_t *zf, uint64_t blkid, uint64_t nblks,
boolean_t fetch_data, boolean_t have_lock)
{
zstream_t *zs;
int64_t pf_start, ipf_start;
int64_t pf_ahead_blks, max_blks;
int max_dist_blks, pf_nblks, ipf_nblks;
uint64_t end_of_access_blkid, maxblkid;
end_of_access_blkid = blkid + nblks;
spa_t *spa = zf->zf_dnode->dn_objset->os_spa;
if (zfs_prefetch_disable)
@ -317,7 +341,7 @@ dmu_zfetch_prepare(zfetch_t *zf, uint64_t blkid, uint64_t nblks,
* A fast path for small files for which no prefetch will
* happen.
*/
maxblkid = zf->zf_dnode->dn_maxblkid;
uint64_t maxblkid = zf->zf_dnode->dn_maxblkid;
if (maxblkid < 2) {
if (!have_lock)
rw_exit(&zf->zf_dnode->dn_struct_rwlock);
@ -345,6 +369,7 @@ dmu_zfetch_prepare(zfetch_t *zf, uint64_t blkid, uint64_t nblks,
* If the file is ending, remove the matching stream if found.
* If not found then it is too late to create a new one now.
*/
uint64_t end_of_access_blkid = blkid + nblks;
if (end_of_access_blkid >= maxblkid) {
if (zs != NULL)
dmu_zfetch_stream_remove(zf, zs);
@ -377,60 +402,48 @@ dmu_zfetch_prepare(zfetch_t *zf, uint64_t blkid, uint64_t nblks,
/*
* This access was to a block that we issued a prefetch for on
* behalf of this stream. Issue further prefetches for this stream.
* behalf of this stream. Calculate further prefetch distances.
*
* Normally, we start prefetching where we stopped
* prefetching last (zs_pf_blkid). But when we get our first
* hit on this stream, zs_pf_blkid == zs_blkid, we don't
* want to prefetch the block we just accessed. In this case,
* start just after the block we just accessed.
*/
pf_start = MAX(zs->zs_pf_blkid, end_of_access_blkid);
if (zs->zs_pf_blkid1 < end_of_access_blkid)
zs->zs_pf_blkid1 = end_of_access_blkid;
if (zs->zs_ipf_blkid1 < end_of_access_blkid)
zs->zs_ipf_blkid1 = end_of_access_blkid;
/*
* Double our amount of prefetched data, but don't let the
* prefetch get further ahead than zfetch_max_distance.
* Start prefetch from the demand access size (nblks). Double the
* distance every access up to zfetch_min_distance. After that only
* if needed increase the distance by 1/8 up to zfetch_max_distance.
*/
unsigned int nbytes = nblks << zf->zf_dnode->dn_datablkshift;
unsigned int pf_nblks;
if (fetch_data) {
max_dist_blks =
zfetch_max_distance >> zf->zf_dnode->dn_datablkshift;
/*
* Previously, we were (zs_pf_blkid - blkid) ahead. We
* want to now be double that, so read that amount again,
* plus the amount we are catching up by (i.e. the amount
* read just now).
*/
pf_ahead_blks = zs->zs_pf_blkid - blkid + nblks;
max_blks = max_dist_blks - (pf_start - end_of_access_blkid);
pf_nblks = MIN(pf_ahead_blks, max_blks);
if (unlikely(zs->zs_pf_dist < nbytes))
zs->zs_pf_dist = nbytes;
else if (zs->zs_pf_dist < zfetch_min_distance)
zs->zs_pf_dist *= 2;
else if (zs->zs_more)
zs->zs_pf_dist += zs->zs_pf_dist / 8;
zs->zs_more = B_FALSE;
if (zs->zs_pf_dist > zfetch_max_distance)
zs->zs_pf_dist = zfetch_max_distance;
pf_nblks = zs->zs_pf_dist >> zf->zf_dnode->dn_datablkshift;
} else {
pf_nblks = 0;
}
zs->zs_pf_blkid = pf_start + pf_nblks;
if (zs->zs_pf_start < end_of_access_blkid)
zs->zs_pf_start = end_of_access_blkid;
if (zs->zs_pf_end < end_of_access_blkid + pf_nblks)
zs->zs_pf_end = end_of_access_blkid + pf_nblks;
/*
* Do the same for indirects, starting from where we stopped last,
* or where we will stop reading data blocks (and the indirects
* that point to them).
* Do the same for indirects, starting where we will stop reading
* data blocks (and the indirects that point to them).
*/
ipf_start = MAX(zs->zs_ipf_blkid, zs->zs_pf_blkid);
max_dist_blks = zfetch_max_idistance >> zf->zf_dnode->dn_datablkshift;
/*
* We want to double our distance ahead of the data prefetch
* (or reader, if we are not prefetching data). Previously, we
* were (zs_ipf_blkid - blkid) ahead. To double that, we read
* that amount again, plus the amount we are catching up by
* (i.e. the amount read now + the amount of data prefetched now).
*/
pf_ahead_blks = zs->zs_ipf_blkid - blkid + nblks + pf_nblks;
max_blks = max_dist_blks - (ipf_start - zs->zs_pf_blkid);
ipf_nblks = MIN(pf_ahead_blks, max_blks);
zs->zs_ipf_blkid = ipf_start + ipf_nblks;
if (unlikely(zs->zs_ipf_dist < nbytes))
zs->zs_ipf_dist = nbytes;
else
zs->zs_ipf_dist *= 2;
if (zs->zs_ipf_dist > zfetch_max_idistance)
zs->zs_ipf_dist = zfetch_max_idistance;
pf_nblks = zs->zs_ipf_dist >> zf->zf_dnode->dn_datablkshift;
if (zs->zs_ipf_start < zs->zs_pf_end)
zs->zs_ipf_start = zs->zs_pf_end;
if (zs->zs_ipf_end < zs->zs_pf_end + pf_nblks)
zs->zs_ipf_end = zs->zs_pf_end + pf_nblks;
zs->zs_blkid = end_of_access_blkid;
/* Protect the stream from reclamation. */
@ -471,13 +484,13 @@ dmu_zfetch_run(zstream_t *zs, boolean_t missed, boolean_t have_lock)
mutex_enter(&zf->zf_lock);
if (zs->zs_missed) {
pf_start = zs->zs_pf_blkid1;
pf_end = zs->zs_pf_blkid1 = zs->zs_pf_blkid;
pf_start = zs->zs_pf_start;
pf_end = zs->zs_pf_start = zs->zs_pf_end;
} else {
pf_start = pf_end = 0;
}
ipf_start = MAX(zs->zs_pf_blkid1, zs->zs_ipf_blkid1);
ipf_end = zs->zs_ipf_blkid1 = zs->zs_ipf_blkid;
ipf_start = zs->zs_ipf_start;
ipf_end = zs->zs_ipf_start = zs->zs_ipf_end;
mutex_exit(&zf->zf_lock);
ASSERT3S(pf_start, <=, pf_end);
ASSERT3S(ipf_start, <=, ipf_end);
@ -505,12 +518,12 @@ dmu_zfetch_run(zstream_t *zs, boolean_t missed, boolean_t have_lock)
for (int64_t blk = pf_start; blk < pf_end; blk++) {
issued += dbuf_prefetch_impl(zf->zf_dnode, 0, blk,
ZIO_PRIORITY_ASYNC_READ, ARC_FLAG_PREDICTIVE_PREFETCH,
dmu_zfetch_stream_done, zs);
dmu_zfetch_done, zs);
}
for (int64_t iblk = ipf_start; iblk < ipf_end; iblk++) {
issued += dbuf_prefetch_impl(zf->zf_dnode, 1, iblk,
ZIO_PRIORITY_ASYNC_READ, ARC_FLAG_PREDICTIVE_PREFETCH,
dmu_zfetch_stream_done, zs);
dmu_zfetch_done, zs);
}
if (!have_lock)
@ -540,6 +553,12 @@ ZFS_MODULE_PARAM(zfs_prefetch, zfetch_, max_streams, UINT, ZMOD_RW,
ZFS_MODULE_PARAM(zfs_prefetch, zfetch_, min_sec_reap, UINT, ZMOD_RW,
"Min time before stream reclaim");
ZFS_MODULE_PARAM(zfs_prefetch, zfetch_, max_sec_reap, UINT, ZMOD_RW,
"Max time before stream delete");
ZFS_MODULE_PARAM(zfs_prefetch, zfetch_, min_distance, UINT, ZMOD_RW,
"Min bytes to prefetch per stream");
ZFS_MODULE_PARAM(zfs_prefetch, zfetch_, max_distance, UINT, ZMOD_RW,
"Max bytes to prefetch per stream");

View file

@ -105,9 +105,8 @@ int zfs_dirty_data_max_percent = 10;
int zfs_dirty_data_max_max_percent = 25;
/*
* zfs_wrlog_data_max, the upper limit of TX_WRITE log data.
* Once it is reached, write operation is blocked,
* until log data is cleared out after txg sync.
* The upper limit of TX_WRITE log data. Write operations are throttled
* when approaching the limit until log data is cleared out after txg sync.
* It only counts TX_WRITE log with WR_COPIED or WR_NEED_COPY.
*/
unsigned long zfs_wrlog_data_max = 0;
@ -623,15 +622,18 @@ dsl_pool_wrlog_count(dsl_pool_t *dp, int64_t size, uint64_t txg)
/* Choose a value slightly bigger than min dirty sync bytes */
uint64_t sync_min =
zfs_dirty_data_max * (zfs_dirty_data_sync_percent + 10) / 100;
zfs_wrlog_data_max * (zfs_dirty_data_sync_percent + 10) / 200;
if (aggsum_compare(&dp->dp_wrlog_pertxg[txg & TXG_MASK], sync_min) > 0)
txg_kick(dp, txg);
}
boolean_t
dsl_pool_wrlog_over_max(dsl_pool_t *dp)
dsl_pool_need_wrlog_delay(dsl_pool_t *dp)
{
return (aggsum_compare(&dp->dp_wrlog_total, zfs_wrlog_data_max) > 0);
uint64_t delay_min_bytes =
zfs_wrlog_data_max * zfs_delay_min_dirty_percent / 100;
return (aggsum_compare(&dp->dp_wrlog_total, delay_min_bytes) > 0);
}
static void
@ -641,6 +643,9 @@ dsl_pool_wrlog_clear(dsl_pool_t *dp, uint64_t txg)
delta = -(int64_t)aggsum_value(&dp->dp_wrlog_pertxg[txg & TXG_MASK]);
aggsum_add(&dp->dp_wrlog_pertxg[txg & TXG_MASK], delta);
aggsum_add(&dp->dp_wrlog_total, delta);
/* Compact per-CPU sums after the big change. */
(void) aggsum_value(&dp->dp_wrlog_pertxg[txg & TXG_MASK]);
(void) aggsum_value(&dp->dp_wrlog_total);
}
#ifdef ZFS_DEBUG

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