zfs: merge openzfs/zfs@b9d98453f
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: b9d98453f9387c413f91d1d9cdb0cba8e04dbd95
This commit is contained in:
commit
e3aa18ad71
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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%/)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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}"
|
||||
|
@ -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@"
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -41,6 +41,6 @@ endef
|
||||
|
||||
SUBSTFILES =
|
||||
CLEANFILES += $(SUBSTFILES)
|
||||
EXTRA_DIST += $(SUBSTFILES:=.in)
|
||||
dist_noinst_DATA += $(SUBSTFILES:=.in)
|
||||
|
||||
$(call SUBST,%,)
|
||||
|
@ -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])
|
||||
|
@ -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])
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
@ -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
|
||||
])
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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])
|
||||
])
|
||||
|
@ -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])
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
32
sys/contrib/openzfs/config/kernel-vfs-read_folio.m4
Normal file
32
sys/contrib/openzfs/config/kernel-vfs-read_folio.m4
Normal 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])
|
||||
])
|
||||
])
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1 +1 @@
|
||||
EXTRA_DIST += $(addprefix %D%/,autosnap.lua)
|
||||
dist_noinst_DATA += %D%/autosnap.lua
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -28,7 +28,6 @@
|
||||
#define _THREAD_POOL_H_ extern __attribute__((visibility("default")))
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <thread.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 */
|
@ -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 */
|
@ -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
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -30,6 +30,5 @@
|
||||
#define ZFS_CONTEXT_OS_H_
|
||||
|
||||
#define HAVE_LARGE_STACKS 1
|
||||
#define ZFS_EXPORTS_PATH "/etc/zfs/exports"
|
||||
|
||||
#endif
|
||||
|
@ -46,7 +46,7 @@
|
||||
#endif
|
||||
|
||||
#include <sys/isa_defs.h>
|
||||
#include <sys/int_types.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -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 */
|
@ -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
|
@ -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
|
@ -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;
|
||||
|
@ -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 */
|
@ -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
|
||||
|
@ -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 */
|
@ -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
|
@ -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
|
@ -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 */
|
@ -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 */
|
@ -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
|
@ -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 @@ fail:
|
||||
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);
|
||||
|
@ -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
|
||||
|
@ -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
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 @@ retry:
|
||||
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 @@ retry:
|
||||
/* 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;
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user