mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-24 03:08:51 +03:00
Compare commits
148 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1222e921c9 | |||
| c37fa0d5a8 | |||
| 12a78fbb4f | |||
| 63d8f57fe7 | |||
| 9fa8b5b55b | |||
| e17445d1f7 | |||
| 97d4986214 | |||
| 0ae5f0c8d2 | |||
| 146d7d8846 | |||
| 9f261b1be6 | |||
| 5acba22ec0 | |||
| 38528476bf | |||
| beb21db3c6 | |||
| 13e5e396a3 | |||
| 3cf4ecb03f | |||
| 0e765c4eb8 | |||
| c7a4255f12 | |||
| 931bef81c8 | |||
| ea34735203 | |||
| 95319fc569 | |||
| 33374f21f0 | |||
| 512a50f38d | |||
| 023ab67a64 | |||
| 65469f6e30 | |||
| 569f5d5d05 | |||
| 6d1599c1e1 | |||
| 6c9882d5db | |||
| 8c00159411 | |||
| a8c5bcb5de | |||
| 6c68594675 | |||
| 1f5979d23f | |||
| 4f951b183c | |||
| 65a0b28b42 | |||
| be068aeea8 | |||
| 1c4b0fc745 | |||
| bbbe4b0a98 | |||
| 3c144b9267 | |||
| 428a63cc62 | |||
| 3982d959c5 | |||
| 54561073e7 | |||
| 4c98586daf | |||
| ceb516ac2f | |||
| 2b9f73e5e6 | |||
| 984bfb373f | |||
| 446d08fba4 | |||
| af7a5672c3 | |||
| 73e50a7d5d | |||
| d751b12a9d | |||
| 78831d4290 | |||
| 0a223246e1 | |||
| cf966cb19a | |||
| 6e19cc77cf | |||
| c3a3c5a30f | |||
| ccd8125e45 | |||
| 2ac233c633 | |||
| 1f72a18f59 | |||
| 14a11bf2f6 | |||
| 7a03d7c73c | |||
| 9e09826b33 | |||
| 093bb64461 | |||
| 7d2489cfad | |||
| 04d4df89f4 | |||
| 05006f125c | |||
| bfe5f029cf | |||
| cc7fe8a599 | |||
| 7d64595c25 | |||
| be4a282a8d | |||
| 2d88230d97 | |||
| 95fcb04215 | |||
| d053481523 | |||
| 7a5f4656ce | |||
| 1fd28bd8d4 | |||
| ab24c9cd4c | |||
| 3c2a42fd25 | |||
| 9af524b0ee | |||
| b96ceeead2 | |||
| 01cc94f68d | |||
| fb6f6b47d6 | |||
| 2087b6cf49 | |||
| 5b0327bc57 | |||
| b5e8d14a4b | |||
| ed7b0d357a | |||
| 9e54b9d930 | |||
| b033353b25 | |||
| 6083f40387 | |||
| 592ee2e6dd | |||
| cab7d856ea | |||
| 19cebf0518 | |||
| 77e64c6fff | |||
| 4f809bddc6 | |||
| 516a08ebb4 | |||
| 812c36fc71 | |||
| fe11968bbf | |||
| 4be4dedb9f | |||
| fb52bf9b1d | |||
| a22b00f924 | |||
| c350e62309 | |||
| 6f7bc75825 | |||
| 06900c409b | |||
| 60cbc18136 | |||
| b63ed49c29 | |||
| fafe72712a | |||
| 328c95e391 | |||
| 6ce10fdabb | |||
| e4a11acfac | |||
| 90d8067a77 | |||
| e5a877c5d0 | |||
| 4933b0a25b | |||
| e0cd6c28a3 | |||
| 63b88f7e22 | |||
| 72888812b0 | |||
| 581c77e725 | |||
| ba505f90d8 | |||
| eaa21b2349 | |||
| 8dc8bbde6e | |||
| 9fd95a2f1b | |||
| 35050ef39e | |||
| 5108d27aec | |||
| 02010e9c2c | |||
| a0bf24952d | |||
| d6920fb996 | |||
| 58b2de6420 | |||
| 11ad06d1d8 | |||
| 4f8eef29e0 | |||
| 94866d8309 | |||
| a1eaf0dde0 | |||
| 580256045b | |||
| aaf3b30dcf | |||
| 27b446f799 | |||
| 0c6206e7f1 | |||
| 51de7ccb42 | |||
| 69ae34076f | |||
| b746c397e3 | |||
| 2fb37bcadd | |||
| a727f69e52 | |||
| 8ec352be1f | |||
| df717bb835 | |||
| e0b3689ed5 | |||
| 438275c9a0 | |||
| 8cfa6d4a1c | |||
| ad0157ec91 | |||
| cd75d5f710 | |||
| c6bbacebc8 | |||
| 4d7cb872e8 | |||
| f91e7e6284 | |||
| abe267f677 | |||
| cc434dcf45 | |||
| e2e7b0a2cd |
+11
@@ -63,3 +63,14 @@ cscope.*
|
|||||||
*.log
|
*.log
|
||||||
venv
|
venv
|
||||||
|
|
||||||
|
#
|
||||||
|
# Module leftovers
|
||||||
|
#
|
||||||
|
/module/avl/zavl.mod
|
||||||
|
/module/icp/icp.mod
|
||||||
|
/module/lua/zlua.mod
|
||||||
|
/module/nvpair/znvpair.mod
|
||||||
|
/module/spl/spl.mod
|
||||||
|
/module/unicode/zunicode.mod
|
||||||
|
/module/zcommon/zcommon.mod
|
||||||
|
/module/zfs/zfs.mod
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
Meta: 1
|
Meta: 1
|
||||||
Name: zfs
|
Name: zfs
|
||||||
Branch: 1.0
|
Branch: 1.0
|
||||||
Version: 0.8.0
|
Version: 0.8.2
|
||||||
Release: 1
|
Release: 1
|
||||||
Release-Tags: relext
|
Release-Tags: relext
|
||||||
License: CDDL
|
License: CDDL
|
||||||
Author: OpenZFS on Linux
|
Author: OpenZFS on Linux
|
||||||
Linux-Maximum: 5.1
|
Linux-Maximum: 5.3
|
||||||
Linux-Minimum: 2.6.32
|
Linux-Minimum: 2.6.32
|
||||||
|
|||||||
+4
-2
@@ -52,7 +52,8 @@ distclean-local::
|
|||||||
-type f -print | xargs $(RM)
|
-type f -print | xargs $(RM)
|
||||||
|
|
||||||
all-local:
|
all-local:
|
||||||
-${top_srcdir}/scripts/zfs-tests.sh -c
|
-[ -x ${top_builddir}/scripts/zfs-tests.sh ] && \
|
||||||
|
${top_builddir}/scripts/zfs-tests.sh -c
|
||||||
|
|
||||||
dist-hook: gitrev
|
dist-hook: gitrev
|
||||||
cp ${top_srcdir}/include/zfs_gitrev.h $(distdir)/include; \
|
cp ${top_srcdir}/include/zfs_gitrev.h $(distdir)/include; \
|
||||||
@@ -111,9 +112,10 @@ mancheck:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
testscheck:
|
testscheck:
|
||||||
@find ${top_srcdir}/tests/zfs-tests/tests -type f \
|
@find ${top_srcdir}/tests/zfs-tests -type f \
|
||||||
\( -name '*.ksh' -not -executable \) -o \
|
\( -name '*.ksh' -not -executable \) -o \
|
||||||
\( -name '*.kshlib' -executable \) -o \
|
\( -name '*.kshlib' -executable \) -o \
|
||||||
|
\( -name '*.shlib' -executable \) -o \
|
||||||
\( -name '*.cfg' -executable \) | \
|
\( -name '*.cfg' -executable \) | \
|
||||||
xargs -r stat -c '%A %n' | \
|
xargs -r stat -c '%A %n' | \
|
||||||
awk '{c++; print} END {if(c>0) exit 1}'
|
awk '{c++; print} END {if(c>0) exit 1}'
|
||||||
|
|||||||
+7
-2
@@ -1,3 +1,8 @@
|
|||||||
SUBDIRS = zfs zpool zdb zhack zinject zstreamdump ztest
|
SUBDIRS = zfs zpool zdb zhack zinject zstreamdump ztest
|
||||||
SUBDIRS += mount_zfs fsck_zfs zvol_id vdev_id arcstat dbufstat zed
|
SUBDIRS += fsck_zfs vdev_id raidz_test zgenhostid
|
||||||
SUBDIRS += arc_summary raidz_test zgenhostid
|
|
||||||
|
if USING_PYTHON
|
||||||
|
SUBDIRS += arcstat arc_summary dbufstat
|
||||||
|
endif
|
||||||
|
|
||||||
|
SUBDIRS += mount_zfs zed zvol_id zvol_wait
|
||||||
|
|||||||
@@ -4,9 +4,7 @@ if USING_PYTHON_2
|
|||||||
dist_bin_SCRIPTS = arc_summary2
|
dist_bin_SCRIPTS = arc_summary2
|
||||||
install-exec-hook:
|
install-exec-hook:
|
||||||
mv $(DESTDIR)$(bindir)/arc_summary2 $(DESTDIR)$(bindir)/arc_summary
|
mv $(DESTDIR)$(bindir)/arc_summary2 $(DESTDIR)$(bindir)/arc_summary
|
||||||
endif
|
else
|
||||||
|
|
||||||
if USING_PYTHON_3
|
|
||||||
dist_bin_SCRIPTS = arc_summary3
|
dist_bin_SCRIPTS = arc_summary3
|
||||||
install-exec-hook:
|
install-exec-hook:
|
||||||
mv $(DESTDIR)$(bindir)/arc_summary3 $(DESTDIR)$(bindir)/arc_summary
|
mv $(DESTDIR)$(bindir)/arc_summary3 $(DESTDIR)$(bindir)/arc_summary
|
||||||
|
|||||||
+2
-55
@@ -1,12 +1,11 @@
|
|||||||
|
SUBDIRS = zed.d
|
||||||
|
|
||||||
include $(top_srcdir)/config/Rules.am
|
include $(top_srcdir)/config/Rules.am
|
||||||
|
|
||||||
DEFAULT_INCLUDES += \
|
DEFAULT_INCLUDES += \
|
||||||
-I$(top_srcdir)/include \
|
-I$(top_srcdir)/include \
|
||||||
-I$(top_srcdir)/lib/libspl/include
|
-I$(top_srcdir)/lib/libspl/include
|
||||||
|
|
||||||
EXTRA_DIST = zed.d/README \
|
|
||||||
zed.d/history_event-zfs-list-cacher.sh.in
|
|
||||||
|
|
||||||
sbin_PROGRAMS = zed
|
sbin_PROGRAMS = zed
|
||||||
|
|
||||||
ZED_SRC = \
|
ZED_SRC = \
|
||||||
@@ -47,55 +46,3 @@ zed_LDADD = \
|
|||||||
|
|
||||||
zed_LDADD += -lrt
|
zed_LDADD += -lrt
|
||||||
zed_LDFLAGS = -pthread
|
zed_LDFLAGS = -pthread
|
||||||
|
|
||||||
zedconfdir = $(sysconfdir)/zfs/zed.d
|
|
||||||
|
|
||||||
dist_zedconf_DATA = \
|
|
||||||
zed.d/zed-functions.sh \
|
|
||||||
zed.d/zed.rc
|
|
||||||
|
|
||||||
zedexecdir = $(zfsexecdir)/zed.d
|
|
||||||
|
|
||||||
dist_zedexec_SCRIPTS = \
|
|
||||||
zed.d/all-debug.sh \
|
|
||||||
zed.d/all-syslog.sh \
|
|
||||||
zed.d/data-notify.sh \
|
|
||||||
zed.d/generic-notify.sh \
|
|
||||||
zed.d/resilver_finish-notify.sh \
|
|
||||||
zed.d/scrub_finish-notify.sh \
|
|
||||||
zed.d/statechange-led.sh \
|
|
||||||
zed.d/statechange-notify.sh \
|
|
||||||
zed.d/vdev_clear-led.sh \
|
|
||||||
zed.d/vdev_attach-led.sh \
|
|
||||||
zed.d/pool_import-led.sh \
|
|
||||||
zed.d/resilver_finish-start-scrub.sh
|
|
||||||
|
|
||||||
nodist_zedexec_SCRIPTS = zed.d/history_event-zfs-list-cacher.sh
|
|
||||||
|
|
||||||
$(nodist_zedexec_SCRIPTS): %: %.in
|
|
||||||
-$(SED) -e 's,@bindir\@,$(bindir),g' \
|
|
||||||
-e 's,@runstatedir\@,$(runstatedir),g' \
|
|
||||||
-e 's,@sbindir\@,$(sbindir),g' \
|
|
||||||
-e 's,@sysconfdir\@,$(sysconfdir),g' \
|
|
||||||
$< >'$@'
|
|
||||||
|
|
||||||
zedconfdefaults = \
|
|
||||||
all-syslog.sh \
|
|
||||||
data-notify.sh \
|
|
||||||
resilver_finish-notify.sh \
|
|
||||||
scrub_finish-notify.sh \
|
|
||||||
statechange-led.sh \
|
|
||||||
statechange-notify.sh \
|
|
||||||
vdev_clear-led.sh \
|
|
||||||
vdev_attach-led.sh \
|
|
||||||
pool_import-led.sh \
|
|
||||||
resilver_finish-start-scrub.sh
|
|
||||||
|
|
||||||
install-data-hook:
|
|
||||||
$(MKDIR_P) "$(DESTDIR)$(zedconfdir)"
|
|
||||||
for f in $(zedconfdefaults); do \
|
|
||||||
test -f "$(DESTDIR)$(zedconfdir)/$${f}" -o \
|
|
||||||
-L "$(DESTDIR)$(zedconfdir)/$${f}" || \
|
|
||||||
ln -s "$(zedexecdir)/$${f}" "$(DESTDIR)$(zedconfdir)"; \
|
|
||||||
done
|
|
||||||
chmod 0600 "$(DESTDIR)$(zedconfdir)/zed.rc"
|
|
||||||
|
|||||||
@@ -116,7 +116,8 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
|||||||
/*
|
/*
|
||||||
* On a devid match, grab the vdev guid and expansion time, if any.
|
* On a devid match, grab the vdev guid and expansion time, if any.
|
||||||
*/
|
*/
|
||||||
if ((nvlist_lookup_string(nvl, ZPOOL_CONFIG_DEVID, &path) == 0) &&
|
if (gsp->gs_devid != NULL &&
|
||||||
|
(nvlist_lookup_string(nvl, ZPOOL_CONFIG_DEVID, &path) == 0) &&
|
||||||
(strcmp(gsp->gs_devid, path) == 0)) {
|
(strcmp(gsp->gs_devid, path) == 0)) {
|
||||||
(void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID,
|
(void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID,
|
||||||
&gsp->gs_vdev_guid);
|
&gsp->gs_vdev_guid);
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
include $(top_srcdir)/config/Rules.am
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
README \
|
||||||
|
history_event-zfs-list-cacher.sh.in
|
||||||
|
|
||||||
|
zedconfdir = $(sysconfdir)/zfs/zed.d
|
||||||
|
|
||||||
|
dist_zedconf_DATA = \
|
||||||
|
zed-functions.sh \
|
||||||
|
zed.rc
|
||||||
|
|
||||||
|
zedexecdir = $(zfsexecdir)/zed.d
|
||||||
|
|
||||||
|
dist_zedexec_SCRIPTS = \
|
||||||
|
all-debug.sh \
|
||||||
|
all-syslog.sh \
|
||||||
|
data-notify.sh \
|
||||||
|
generic-notify.sh \
|
||||||
|
resilver_finish-notify.sh \
|
||||||
|
scrub_finish-notify.sh \
|
||||||
|
statechange-led.sh \
|
||||||
|
statechange-notify.sh \
|
||||||
|
vdev_clear-led.sh \
|
||||||
|
vdev_attach-led.sh \
|
||||||
|
pool_import-led.sh \
|
||||||
|
resilver_finish-start-scrub.sh
|
||||||
|
|
||||||
|
nodist_zedexec_SCRIPTS = history_event-zfs-list-cacher.sh
|
||||||
|
|
||||||
|
$(nodist_zedexec_SCRIPTS): %: %.in
|
||||||
|
-$(SED) -e 's,@bindir\@,$(bindir),g' \
|
||||||
|
-e 's,@runstatedir\@,$(runstatedir),g' \
|
||||||
|
-e 's,@sbindir\@,$(sbindir),g' \
|
||||||
|
-e 's,@sysconfdir\@,$(sysconfdir),g' \
|
||||||
|
$< >'$@'
|
||||||
|
|
||||||
|
zedconfdefaults = \
|
||||||
|
all-syslog.sh \
|
||||||
|
data-notify.sh \
|
||||||
|
resilver_finish-notify.sh \
|
||||||
|
scrub_finish-notify.sh \
|
||||||
|
statechange-led.sh \
|
||||||
|
statechange-notify.sh \
|
||||||
|
vdev_clear-led.sh \
|
||||||
|
vdev_attach-led.sh \
|
||||||
|
pool_import-led.sh \
|
||||||
|
resilver_finish-start-scrub.sh
|
||||||
|
|
||||||
|
install-data-hook:
|
||||||
|
$(MKDIR_P) "$(DESTDIR)$(zedconfdir)"
|
||||||
|
for f in $(zedconfdefaults); do \
|
||||||
|
test -f "$(DESTDIR)$(zedconfdir)/$${f}" -o \
|
||||||
|
-L "$(DESTDIR)$(zedconfdir)/$${f}" || \
|
||||||
|
ln -s "$(zedexecdir)/$${f}" "$(DESTDIR)$(zedconfdir)"; \
|
||||||
|
done
|
||||||
|
chmod 0600 "$(DESTDIR)$(zedconfdir)/zed.rc"
|
||||||
@@ -47,7 +47,7 @@ case "${ZEVENT_HISTORY_INTERNAL_NAME}" in
|
|||||||
# Only act if one of the tracked properties is altered.
|
# Only act if one of the tracked properties is altered.
|
||||||
case "${ZEVENT_HISTORY_INTERNAL_STR%%=*}" in
|
case "${ZEVENT_HISTORY_INTERNAL_STR%%=*}" in
|
||||||
canmount|mountpoint|atime|relatime|devices|exec| \
|
canmount|mountpoint|atime|relatime|devices|exec| \
|
||||||
readonly|setuid|nbmand) ;;
|
readonly|setuid|nbmand|encroot|keylocation) ;;
|
||||||
*) exit 0 ;;
|
*) exit 0 ;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
@@ -62,7 +62,7 @@ zed_lock zfs-list
|
|||||||
trap abort_alter EXIT
|
trap abort_alter EXIT
|
||||||
|
|
||||||
PROPS="name,mountpoint,canmount,atime,relatime,devices,exec,readonly"
|
PROPS="name,mountpoint,canmount,atime,relatime,devices,exec,readonly"
|
||||||
PROPS="${PROPS},setuid,nbmand"
|
PROPS="${PROPS},setuid,nbmand,encroot,keylocation"
|
||||||
|
|
||||||
"${ZFS}" list -H -t filesystem -o $PROPS -r "${ZEVENT_POOL}" > "${FSLIST_TMP}"
|
"${ZFS}" list -H -t filesystem -o $PROPS -r "${ZEVENT_POOL}" > "${FSLIST_TMP}"
|
||||||
|
|
||||||
|
|||||||
+29
-8
@@ -28,6 +28,7 @@
|
|||||||
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
|
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
|
||||||
* Copyright 2016 Nexenta Systems, Inc.
|
* Copyright 2016 Nexenta Systems, Inc.
|
||||||
* Copyright (c) 2019 Datto Inc.
|
* Copyright (c) 2019 Datto Inc.
|
||||||
|
* Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@@ -2238,7 +2239,7 @@ zfs_do_upgrade(int argc, char **argv)
|
|||||||
boolean_t showversions = B_FALSE;
|
boolean_t showversions = B_FALSE;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
upgrade_cbdata_t cb = { 0 };
|
upgrade_cbdata_t cb = { 0 };
|
||||||
signed char c;
|
int c;
|
||||||
int flags = ZFS_ITER_ARGS_CAN_BE_PATHS;
|
int flags = ZFS_ITER_ARGS_CAN_BE_PATHS;
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
@@ -3932,7 +3933,7 @@ static int
|
|||||||
zfs_do_snapshot(int argc, char **argv)
|
zfs_do_snapshot(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
signed char c;
|
int c;
|
||||||
nvlist_t *props;
|
nvlist_t *props;
|
||||||
snap_cbdata_t sd = { 0 };
|
snap_cbdata_t sd = { 0 };
|
||||||
boolean_t multiple_snaps = B_FALSE;
|
boolean_t multiple_snaps = B_FALSE;
|
||||||
@@ -6445,8 +6446,25 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, char *protocol,
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zfs_mount(zhp, options, flags) != 0)
|
if (zfs_mount(zhp, options, flags) != 0) {
|
||||||
|
/*
|
||||||
|
* Check if a mount sneaked in after we checked
|
||||||
|
*/
|
||||||
|
if (!explicit &&
|
||||||
|
libzfs_errno(g_zfs) == EZFS_MOUNTFAILED) {
|
||||||
|
usleep(10 * MILLISEC);
|
||||||
|
libzfs_mnttab_cache(g_zfs, B_FALSE);
|
||||||
|
|
||||||
|
if (zfs_is_mounted(zhp, NULL)) {
|
||||||
|
(void) fprintf(stderr, gettext(
|
||||||
|
"Ignoring previous 'already "
|
||||||
|
"mounted' error for '%s'\n"),
|
||||||
|
zfs_get_name(zhp));
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
return (1);
|
return (1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6621,10 +6639,13 @@ share_mount(int op, int argc, char **argv)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* libshare isn't mt-safe, so only do the operation in parallel
|
* libshare isn't mt-safe, so only do the operation in parallel
|
||||||
* if we're mounting.
|
* if we're mounting. Additionally, the key-loading option must
|
||||||
|
* be serialized so that we can prompt the user for their keys
|
||||||
|
* in a consistent manner.
|
||||||
*/
|
*/
|
||||||
zfs_foreach_mountpoint(g_zfs, cb.cb_handles, cb.cb_used,
|
zfs_foreach_mountpoint(g_zfs, cb.cb_handles, cb.cb_used,
|
||||||
share_mount_one_cb, &share_mount_state, op == OP_MOUNT);
|
share_mount_one_cb, &share_mount_state,
|
||||||
|
op == OP_MOUNT && !(flags & MS_CRYPT));
|
||||||
ret = share_mount_state.sm_status;
|
ret = share_mount_state.sm_status;
|
||||||
|
|
||||||
for (int i = 0; i < cb.cb_used; i++)
|
for (int i = 0; i < cb.cb_used; i++)
|
||||||
@@ -6729,8 +6750,8 @@ unshare_unmount_compare(const void *larg, const void *rarg, void *unused)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Convenience routine used by zfs_do_umount() and manual_unmount(). Given an
|
* Convenience routine used by zfs_do_umount() and manual_unmount(). Given an
|
||||||
* absolute path, find the entry /proc/self/mounts, verify that its a
|
* absolute path, find the entry /proc/self/mounts, verify that it's a
|
||||||
* ZFS filesystems, and unmount it appropriately.
|
* ZFS filesystem, and unmount it appropriately.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual)
|
unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual)
|
||||||
@@ -7522,7 +7543,7 @@ zfs_do_channel_program(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((zhp = zpool_open(g_zfs, poolname)) == NULL) {
|
if ((zhp = zpool_open(g_zfs, poolname)) == NULL) {
|
||||||
(void) fprintf(stderr, gettext("cannot open pool '%s'"),
|
(void) fprintf(stderr, gettext("cannot open pool '%s'\n"),
|
||||||
poolname);
|
poolname);
|
||||||
if (fd != 0)
|
if (fd != 0)
|
||||||
(void) close(fd);
|
(void) close(fd);
|
||||||
|
|||||||
+12
-13
@@ -30,6 +30,7 @@
|
|||||||
* Copyright (c) 2017 Datto Inc.
|
* Copyright (c) 2017 Datto Inc.
|
||||||
* Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
|
* Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
|
||||||
* Copyright (c) 2017, Intel Corporation.
|
* Copyright (c) 2017, Intel Corporation.
|
||||||
|
* Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@@ -384,11 +385,11 @@ get_usage(zpool_help_t idx)
|
|||||||
case HELP_RESILVER:
|
case HELP_RESILVER:
|
||||||
return (gettext("\tresilver <pool> ...\n"));
|
return (gettext("\tresilver <pool> ...\n"));
|
||||||
case HELP_TRIM:
|
case HELP_TRIM:
|
||||||
return (gettext("\ttrim [-dp] [-r <rate>] [-c | -s] <pool> "
|
return (gettext("\ttrim [-d] [-r <rate>] [-c | -s] <pool> "
|
||||||
"[<device> ...]\n"));
|
"[<device> ...]\n"));
|
||||||
case HELP_STATUS:
|
case HELP_STATUS:
|
||||||
return (gettext("\tstatus [-c [script1,script2,...]] "
|
return (gettext("\tstatus [-c [script1,script2,...]] "
|
||||||
"[-igLpPsvxD] [-T d|u] [pool] ... \n"
|
"[-igLpPstvxD] [-T d|u] [pool] ... \n"
|
||||||
"\t [interval [count]]\n"));
|
"\t [interval [count]]\n"));
|
||||||
case HELP_UPGRADE:
|
case HELP_UPGRADE:
|
||||||
return (gettext("\tupgrade\n"
|
return (gettext("\tupgrade\n"
|
||||||
@@ -784,7 +785,7 @@ add_prop_list_default(const char *propname, char *propval, nvlist_t **props,
|
|||||||
* -P Display full path for vdev name.
|
* -P Display full path for vdev name.
|
||||||
*
|
*
|
||||||
* Adds the given vdevs to 'pool'. As with create, the bulk of this work is
|
* Adds the given vdevs to 'pool'. As with create, the bulk of this work is
|
||||||
* handled by get_vdev_spec(), which constructs the nvlist needed to pass to
|
* handled by make_root_vdev(), which constructs the nvlist needed to pass to
|
||||||
* libzfs.
|
* libzfs.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
@@ -882,7 +883,7 @@ zpool_do_add(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pass off to get_vdev_spec for processing */
|
/* pass off to make_root_vdev for processing */
|
||||||
nvroot = make_root_vdev(zhp, props, force, !force, B_FALSE, dryrun,
|
nvroot = make_root_vdev(zhp, props, force, !force, B_FALSE, dryrun,
|
||||||
argc, argv);
|
argc, argv);
|
||||||
if (nvroot == NULL) {
|
if (nvroot == NULL) {
|
||||||
@@ -972,7 +973,7 @@ zpool_do_remove(int argc, char **argv)
|
|||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
zpool_handle_t *zhp = NULL;
|
zpool_handle_t *zhp = NULL;
|
||||||
boolean_t stop = B_FALSE;
|
boolean_t stop = B_FALSE;
|
||||||
char c;
|
int c;
|
||||||
boolean_t noop = B_FALSE;
|
boolean_t noop = B_FALSE;
|
||||||
boolean_t parsable = B_FALSE;
|
boolean_t parsable = B_FALSE;
|
||||||
|
|
||||||
@@ -1231,9 +1232,9 @@ errout:
|
|||||||
* -O Set fsproperty=value in the pool's root file system
|
* -O Set fsproperty=value in the pool's root file system
|
||||||
*
|
*
|
||||||
* Creates the named pool according to the given vdev specification. The
|
* Creates the named pool according to the given vdev specification. The
|
||||||
* bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once
|
* bulk of the vdev processing is done in make_root_vdev() in zpool_vdev.c.
|
||||||
* we get the nvlist back from get_vdev_spec(), we either print out the contents
|
* Once we get the nvlist back from make_root_vdev(), we either print out the
|
||||||
* (if '-n' was specified), or pass it to libzfs to do the creation.
|
* contents (if '-n' was specified), or pass it to libzfs to do the creation.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zpool_do_create(int argc, char **argv)
|
zpool_do_create(int argc, char **argv)
|
||||||
@@ -1387,7 +1388,7 @@ zpool_do_create(int argc, char **argv)
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pass off to get_vdev_spec for bulk processing */
|
/* pass off to make_root_vdev for bulk processing */
|
||||||
nvroot = make_root_vdev(NULL, props, force, !force, B_FALSE, dryrun,
|
nvroot = make_root_vdev(NULL, props, force, !force, B_FALSE, dryrun,
|
||||||
argc - 1, argv + 1);
|
argc - 1, argv + 1);
|
||||||
if (nvroot == NULL)
|
if (nvroot == NULL)
|
||||||
@@ -6110,9 +6111,8 @@ zpool_do_detach(int argc, char **argv)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt(argc, argv, "f")) != -1) {
|
while ((c = getopt(argc, argv, "")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'f':
|
|
||||||
case '?':
|
case '?':
|
||||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||||
optopt);
|
optopt);
|
||||||
@@ -6341,12 +6341,11 @@ zpool_do_online(int argc, char **argv)
|
|||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt(argc, argv, "et")) != -1) {
|
while ((c = getopt(argc, argv, "e")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'e':
|
case 'e':
|
||||||
flags |= ZFS_ONLINE_EXPAND;
|
flags |= ZFS_ONLINE_EXPAND;
|
||||||
break;
|
break;
|
||||||
case 't':
|
|
||||||
case '?':
|
case '?':
|
||||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||||
optopt);
|
optopt);
|
||||||
|
|||||||
@@ -433,6 +433,7 @@ check_disk(const char *path, blkid_cache cache, int force,
|
|||||||
char *value = blkid_get_tag_value(cache, "TYPE", path);
|
char *value = blkid_get_tag_value(cache, "TYPE", path);
|
||||||
(void) fprintf(stderr, gettext("%s is in use and contains "
|
(void) fprintf(stderr, gettext("%s is in use and contains "
|
||||||
"a %s filesystem.\n"), path, value ? value : "unknown");
|
"a %s filesystem.\n"), path, value ? value : "unknown");
|
||||||
|
free(value);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
#define DUMP_GROUPING 4
|
#define DUMP_GROUPING 4
|
||||||
|
|
||||||
uint64_t total_write_size = 0;
|
|
||||||
uint64_t total_stream_len = 0;
|
uint64_t total_stream_len = 0;
|
||||||
FILE *send_stream = 0;
|
FILE *send_stream = 0;
|
||||||
boolean_t do_byteswap = B_FALSE;
|
boolean_t do_byteswap = B_FALSE;
|
||||||
@@ -219,6 +218,9 @@ main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
char *buf = safe_malloc(SPA_MAXBLOCKSIZE);
|
char *buf = safe_malloc(SPA_MAXBLOCKSIZE);
|
||||||
uint64_t drr_record_count[DRR_NUMTYPES] = { 0 };
|
uint64_t drr_record_count[DRR_NUMTYPES] = { 0 };
|
||||||
|
uint64_t total_payload_size = 0;
|
||||||
|
uint64_t total_overhead_size = 0;
|
||||||
|
uint64_t drr_byte_count[DRR_NUMTYPES] = { 0 };
|
||||||
char salt[ZIO_DATA_SALT_LEN * 2 + 1];
|
char salt[ZIO_DATA_SALT_LEN * 2 + 1];
|
||||||
char iv[ZIO_DATA_IV_LEN * 2 + 1];
|
char iv[ZIO_DATA_IV_LEN * 2 + 1];
|
||||||
char mac[ZIO_DATA_MAC_LEN * 2 + 1];
|
char mac[ZIO_DATA_MAC_LEN * 2 + 1];
|
||||||
@@ -237,7 +239,7 @@ main(int argc, char *argv[])
|
|||||||
struct drr_write_embedded *drrwe = &thedrr.drr_u.drr_write_embedded;
|
struct drr_write_embedded *drrwe = &thedrr.drr_u.drr_write_embedded;
|
||||||
struct drr_object_range *drror = &thedrr.drr_u.drr_object_range;
|
struct drr_object_range *drror = &thedrr.drr_u.drr_object_range;
|
||||||
struct drr_checksum *drrc = &thedrr.drr_u.drr_checksum;
|
struct drr_checksum *drrc = &thedrr.drr_u.drr_checksum;
|
||||||
char c;
|
int c;
|
||||||
boolean_t verbose = B_FALSE;
|
boolean_t verbose = B_FALSE;
|
||||||
boolean_t very_verbose = B_FALSE;
|
boolean_t very_verbose = B_FALSE;
|
||||||
boolean_t first = B_TRUE;
|
boolean_t first = B_TRUE;
|
||||||
@@ -336,7 +338,9 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
drr_record_count[drr->drr_type]++;
|
drr_record_count[drr->drr_type]++;
|
||||||
|
total_overhead_size += sizeof (*drr);
|
||||||
total_records++;
|
total_records++;
|
||||||
|
payload_size = 0;
|
||||||
|
|
||||||
switch (drr->drr_type) {
|
switch (drr->drr_type) {
|
||||||
case DRR_BEGIN:
|
case DRR_BEGIN:
|
||||||
@@ -390,6 +394,7 @@ main(int argc, char *argv[])
|
|||||||
nvlist_print(stdout, nv);
|
nvlist_print(stdout, nv);
|
||||||
nvlist_free(nv);
|
nvlist_free(nv);
|
||||||
}
|
}
|
||||||
|
payload_size = sz;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -554,7 +559,6 @@ main(int argc, char *argv[])
|
|||||||
if (dump) {
|
if (dump) {
|
||||||
print_block(buf, payload_size);
|
print_block(buf, payload_size);
|
||||||
}
|
}
|
||||||
total_write_size += payload_size;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DRR_WRITE_BYREF:
|
case DRR_WRITE_BYREF:
|
||||||
@@ -683,6 +687,7 @@ main(int argc, char *argv[])
|
|||||||
print_block(buf,
|
print_block(buf,
|
||||||
P2ROUNDUP(drrwe->drr_psize, 8));
|
P2ROUNDUP(drrwe->drr_psize, 8));
|
||||||
}
|
}
|
||||||
|
payload_size = P2ROUNDUP(drrwe->drr_psize, 8);
|
||||||
break;
|
break;
|
||||||
case DRR_OBJECT_RANGE:
|
case DRR_OBJECT_RANGE:
|
||||||
if (do_byteswap) {
|
if (do_byteswap) {
|
||||||
@@ -723,6 +728,8 @@ main(int argc, char *argv[])
|
|||||||
(longlong_t)drrc->drr_checksum.zc_word[3]);
|
(longlong_t)drrc->drr_checksum.zc_word[3]);
|
||||||
}
|
}
|
||||||
pcksum = zc;
|
pcksum = zc;
|
||||||
|
drr_byte_count[drr->drr_type] += payload_size;
|
||||||
|
total_payload_size += payload_size;
|
||||||
}
|
}
|
||||||
free(buf);
|
free(buf);
|
||||||
fletcher_4_fini();
|
fletcher_4_fini();
|
||||||
@@ -730,28 +737,40 @@ main(int argc, char *argv[])
|
|||||||
/* Print final summary */
|
/* Print final summary */
|
||||||
|
|
||||||
(void) printf("SUMMARY:\n");
|
(void) printf("SUMMARY:\n");
|
||||||
(void) printf("\tTotal DRR_BEGIN records = %lld\n",
|
(void) printf("\tTotal DRR_BEGIN records = %lld (%llu bytes)\n",
|
||||||
(u_longlong_t)drr_record_count[DRR_BEGIN]);
|
(u_longlong_t)drr_record_count[DRR_BEGIN],
|
||||||
(void) printf("\tTotal DRR_END records = %lld\n",
|
(u_longlong_t)drr_byte_count[DRR_BEGIN]);
|
||||||
(u_longlong_t)drr_record_count[DRR_END]);
|
(void) printf("\tTotal DRR_END records = %lld (%llu bytes)\n",
|
||||||
(void) printf("\tTotal DRR_OBJECT records = %lld\n",
|
(u_longlong_t)drr_record_count[DRR_END],
|
||||||
(u_longlong_t)drr_record_count[DRR_OBJECT]);
|
(u_longlong_t)drr_byte_count[DRR_END]);
|
||||||
(void) printf("\tTotal DRR_FREEOBJECTS records = %lld\n",
|
(void) printf("\tTotal DRR_OBJECT records = %lld (%llu bytes)\n",
|
||||||
(u_longlong_t)drr_record_count[DRR_FREEOBJECTS]);
|
(u_longlong_t)drr_record_count[DRR_OBJECT],
|
||||||
(void) printf("\tTotal DRR_WRITE records = %lld\n",
|
(u_longlong_t)drr_byte_count[DRR_OBJECT]);
|
||||||
(u_longlong_t)drr_record_count[DRR_WRITE]);
|
(void) printf("\tTotal DRR_FREEOBJECTS records = %lld (%llu bytes)\n",
|
||||||
(void) printf("\tTotal DRR_WRITE_BYREF records = %lld\n",
|
(u_longlong_t)drr_record_count[DRR_FREEOBJECTS],
|
||||||
(u_longlong_t)drr_record_count[DRR_WRITE_BYREF]);
|
(u_longlong_t)drr_byte_count[DRR_FREEOBJECTS]);
|
||||||
(void) printf("\tTotal DRR_WRITE_EMBEDDED records = %lld\n",
|
(void) printf("\tTotal DRR_WRITE records = %lld (%llu bytes)\n",
|
||||||
(u_longlong_t)drr_record_count[DRR_WRITE_EMBEDDED]);
|
(u_longlong_t)drr_record_count[DRR_WRITE],
|
||||||
(void) printf("\tTotal DRR_FREE records = %lld\n",
|
(u_longlong_t)drr_byte_count[DRR_WRITE]);
|
||||||
(u_longlong_t)drr_record_count[DRR_FREE]);
|
(void) printf("\tTotal DRR_WRITE_BYREF records = %lld (%llu bytes)\n",
|
||||||
(void) printf("\tTotal DRR_SPILL records = %lld\n",
|
(u_longlong_t)drr_record_count[DRR_WRITE_BYREF],
|
||||||
(u_longlong_t)drr_record_count[DRR_SPILL]);
|
(u_longlong_t)drr_byte_count[DRR_WRITE_BYREF]);
|
||||||
|
(void) printf("\tTotal DRR_WRITE_EMBEDDED records = %lld (%llu "
|
||||||
|
"bytes)\n", (u_longlong_t)drr_record_count[DRR_WRITE_EMBEDDED],
|
||||||
|
(u_longlong_t)drr_byte_count[DRR_WRITE_EMBEDDED]);
|
||||||
|
(void) printf("\tTotal DRR_FREE records = %lld (%llu bytes)\n",
|
||||||
|
(u_longlong_t)drr_record_count[DRR_FREE],
|
||||||
|
(u_longlong_t)drr_byte_count[DRR_FREE]);
|
||||||
|
(void) printf("\tTotal DRR_SPILL records = %lld (%llu bytes)\n",
|
||||||
|
(u_longlong_t)drr_record_count[DRR_SPILL],
|
||||||
|
(u_longlong_t)drr_byte_count[DRR_SPILL]);
|
||||||
(void) printf("\tTotal records = %lld\n",
|
(void) printf("\tTotal records = %lld\n",
|
||||||
(u_longlong_t)total_records);
|
(u_longlong_t)total_records);
|
||||||
(void) printf("\tTotal write size = %lld (0x%llx)\n",
|
(void) printf("\tTotal payload size = %lld (0x%llx)\n",
|
||||||
(u_longlong_t)total_write_size, (u_longlong_t)total_write_size);
|
(u_longlong_t)total_payload_size, (u_longlong_t)total_payload_size);
|
||||||
|
(void) printf("\tTotal header overhead = %lld (0x%llx)\n",
|
||||||
|
(u_longlong_t)total_overhead_size,
|
||||||
|
(u_longlong_t)total_overhead_size);
|
||||||
(void) printf("\tTotal stream length = %lld (0x%llx)\n",
|
(void) printf("\tTotal stream length = %lld (0x%llx)\n",
|
||||||
(u_longlong_t)total_stream_len, (u_longlong_t)total_stream_len);
|
(u_longlong_t)total_stream_len, (u_longlong_t)total_stream_len);
|
||||||
return (0);
|
return (0);
|
||||||
|
|||||||
+17
-1
@@ -2745,8 +2745,24 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
|
|||||||
VERIFY3U(EEXIST, ==,
|
VERIFY3U(EEXIST, ==,
|
||||||
spa_create(zo->zo_pool, nvroot, NULL, NULL, NULL));
|
spa_create(zo->zo_pool, nvroot, NULL, NULL, NULL));
|
||||||
nvlist_free(nvroot);
|
nvlist_free(nvroot);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We open a reference to the spa and then we try to export it
|
||||||
|
* expecting one of the following errors:
|
||||||
|
*
|
||||||
|
* EBUSY
|
||||||
|
* Because of the reference we just opened.
|
||||||
|
*
|
||||||
|
* ZFS_ERR_EXPORT_IN_PROGRESS
|
||||||
|
* For the case that there is another ztest thread doing
|
||||||
|
* an export concurrently.
|
||||||
|
*/
|
||||||
VERIFY3U(0, ==, spa_open(zo->zo_pool, &spa, FTAG));
|
VERIFY3U(0, ==, spa_open(zo->zo_pool, &spa, FTAG));
|
||||||
VERIFY3U(EBUSY, ==, spa_destroy(zo->zo_pool));
|
int error = spa_destroy(zo->zo_pool);
|
||||||
|
if (error != EBUSY && error != ZFS_ERR_EXPORT_IN_PROGRESS) {
|
||||||
|
fatal(0, "spa_destroy(%s) returned unexpected value %d",
|
||||||
|
spa->spa_name, error);
|
||||||
|
}
|
||||||
spa_close(spa, FTAG);
|
spa_close(spa, FTAG);
|
||||||
|
|
||||||
(void) pthread_rwlock_unlock(&ztest_name_lock);
|
(void) pthread_rwlock_unlock(&ztest_name_lock);
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
dist_bin_SCRIPTS = zvol_wait
|
||||||
Executable
+112
@@ -0,0 +1,112 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
count_zvols() {
|
||||||
|
if [ -z "$zvols" ]; then
|
||||||
|
echo 0
|
||||||
|
else
|
||||||
|
echo "$zvols" | wc -l
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
filter_out_zvols_with_links() {
|
||||||
|
while read -r zvol; do
|
||||||
|
if [ ! -L "/dev/zvol/$zvol" ]; then
|
||||||
|
echo "$zvol"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
filter_out_deleted_zvols() {
|
||||||
|
while read -r zvol; do
|
||||||
|
if zfs list "$zvol" >/dev/null 2>&1; then
|
||||||
|
echo "$zvol"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
list_zvols() {
|
||||||
|
zfs list -t volume -H -o name,volmode,receive_resume_token |
|
||||||
|
while read -r zvol_line; do
|
||||||
|
name=$(echo "$zvol_line" | awk '{print $1}')
|
||||||
|
volmode=$(echo "$zvol_line" | awk '{print $2}')
|
||||||
|
token=$(echo "$zvol_line" | awk '{print $3}')
|
||||||
|
#
|
||||||
|
# /dev links are not created for zvols with volmode = "none".
|
||||||
|
#
|
||||||
|
[ "$volmode" = "none" ] && continue
|
||||||
|
#
|
||||||
|
# We also also ignore partially received zvols if it is
|
||||||
|
# not an incremental receive, as those won't even have a block
|
||||||
|
# device minor node created yet.
|
||||||
|
#
|
||||||
|
if [ "$token" != "-" ]; then
|
||||||
|
#
|
||||||
|
# Incremental receives create an invisible clone that
|
||||||
|
# is not automatically displayed by zfs list.
|
||||||
|
#
|
||||||
|
if ! zfs list "$name/%recv" >/dev/null 2>&1; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "$name"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
zvols=$(list_zvols)
|
||||||
|
zvols_count=$(count_zvols)
|
||||||
|
if [ "$zvols_count" -eq 0 ]; then
|
||||||
|
echo "No zvols found, nothing to do."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Testing $zvols_count zvol links"
|
||||||
|
|
||||||
|
outer_loop=0
|
||||||
|
while [ "$outer_loop" -lt 20 ]; do
|
||||||
|
outer_loop=$((outer_loop + 1))
|
||||||
|
|
||||||
|
old_zvols_count=$(count_zvols)
|
||||||
|
|
||||||
|
inner_loop=0
|
||||||
|
while [ "$inner_loop" -lt 30 ]; do
|
||||||
|
inner_loop=$((inner_loop + 1))
|
||||||
|
|
||||||
|
zvols="$(echo "$zvols" | filter_out_zvols_with_links)"
|
||||||
|
|
||||||
|
zvols_count=$(count_zvols)
|
||||||
|
if [ "$zvols_count" -eq 0 ]; then
|
||||||
|
echo "All zvol links are now present."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Still waiting on $zvols_count zvol links ..."
|
||||||
|
#
|
||||||
|
# Although zvols should normally not be deleted at boot time,
|
||||||
|
# if that is the case then their links will be missing and
|
||||||
|
# we would stall.
|
||||||
|
#
|
||||||
|
if [ "$old_zvols_count" -eq "$zvols_count" ]; then
|
||||||
|
echo "No progress since last loop."
|
||||||
|
echo "Checking if any zvols were deleted."
|
||||||
|
|
||||||
|
zvols=$(echo "$zvols" | filter_out_deleted_zvols)
|
||||||
|
zvols_count=$(count_zvols)
|
||||||
|
|
||||||
|
if [ "$old_zvols_count" -ne "$zvols_count" ]; then
|
||||||
|
echo "$((old_zvols_count - zvols_count)) zvol(s) deleted."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$zvols_count" -ne 0 ]; then
|
||||||
|
echo "Remaining zvols:"
|
||||||
|
echo "$zvols"
|
||||||
|
else
|
||||||
|
echo "All zvol links are now present."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Timed out waiting on zvol links"
|
||||||
|
exit 1
|
||||||
+25
-61
@@ -1,36 +1,3 @@
|
|||||||
dnl #
|
|
||||||
dnl # ZFS_AC_PYTHON_VERSION(version, [action-if-true], [action-if-false])
|
|
||||||
dnl #
|
|
||||||
dnl # Verify Python version
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_PYTHON_VERSION], [
|
|
||||||
ver_check=`$PYTHON -c "import sys; print (sys.version.split()[[0]] $1)"`
|
|
||||||
AS_IF([test "$ver_check" = "True"], [
|
|
||||||
m4_ifvaln([$2], [$2])
|
|
||||||
], [
|
|
||||||
m4_ifvaln([$3], [$3])
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl #
|
|
||||||
dnl # ZFS_AC_PYTHON_MODULE(module_name, [action-if-true], [action-if-false])
|
|
||||||
dnl #
|
|
||||||
dnl # Checks for Python module. Freely inspired by AX_PYTHON_MODULE
|
|
||||||
dnl # https://www.gnu.org/software/autoconf-archive/ax_python_module.html
|
|
||||||
dnl # Required by ZFS_AC_CONFIG_ALWAYS_PYZFS.
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_PYTHON_MODULE], [
|
|
||||||
PYTHON_NAME=`basename $PYTHON`
|
|
||||||
AC_MSG_CHECKING([for $PYTHON_NAME module: $1])
|
|
||||||
AS_IF([$PYTHON -c "import $1" 2>/dev/null], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
m4_ifvaln([$2], [$2])
|
|
||||||
], [
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
m4_ifvaln([$3], [$3])
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # The majority of the python scripts are written to be compatible
|
dnl # The majority of the python scripts are written to be compatible
|
||||||
dnl # with Python 2.6 and Python 3.4. Therefore, they may be installed
|
dnl # with Python 2.6 and Python 3.4. Therefore, they may be installed
|
||||||
@@ -46,50 +13,47 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYTHON], [
|
|||||||
[with_python=check])
|
[with_python=check])
|
||||||
|
|
||||||
AS_CASE([$with_python],
|
AS_CASE([$with_python],
|
||||||
[check],
|
[check], [AC_CHECK_PROGS([PYTHON], [python3 python2], [:])],
|
||||||
[AS_IF([test -x /usr/bin/python3],
|
|
||||||
[PYTHON="python3"],
|
|
||||||
[AS_IF([test -x /usr/bin/python2],
|
|
||||||
[PYTHON="python2"],
|
|
||||||
[PYTHON=""]
|
|
||||||
)]
|
|
||||||
)],
|
|
||||||
[2*], [PYTHON="python${with_python}"],
|
[2*], [PYTHON="python${with_python}"],
|
||||||
[*python2*], [PYTHON="${with_python}"],
|
[*python2*], [PYTHON="${with_python}"],
|
||||||
[3*], [PYTHON="python${with_python}"],
|
[3*], [PYTHON="python${with_python}"],
|
||||||
[*python3*], [PYTHON="${with_python}"],
|
[*python3*], [PYTHON="${with_python}"],
|
||||||
[no], [PYTHON=""],
|
[no], [PYTHON=":"],
|
||||||
[AC_MSG_ERROR([Unknown --with-python value '$with_python'])]
|
[AC_MSG_ERROR([Unknown --with-python value '$with_python'])]
|
||||||
)
|
)
|
||||||
|
|
||||||
AS_IF([$PYTHON --version >/dev/null 2>&1], [ /bin/true ], [
|
|
||||||
AC_MSG_ERROR([Cannot find $PYTHON in your system path])
|
|
||||||
])
|
|
||||||
|
|
||||||
AM_PATH_PYTHON([2.6], [], [:])
|
|
||||||
AM_CONDITIONAL([USING_PYTHON], [test "$PYTHON" != :])
|
|
||||||
AM_CONDITIONAL([USING_PYTHON_2], [test "${PYTHON_VERSION:0:2}" = "2."])
|
|
||||||
AM_CONDITIONAL([USING_PYTHON_3], [test "${PYTHON_VERSION:0:2}" = "3."])
|
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Minimum supported Python versions for utilities:
|
dnl # Minimum supported Python versions for utilities:
|
||||||
dnl # Python 2.6.x, or Python 3.4.x
|
dnl # Python 2.6 or Python 3.4
|
||||||
dnl #
|
dnl #
|
||||||
AS_IF([test "${PYTHON_VERSION:0:2}" = "2."], [
|
AM_PATH_PYTHON([], [], [:])
|
||||||
ZFS_AC_PYTHON_VERSION([>= '2.6'], [ /bin/true ],
|
AS_IF([test -z "$PYTHON_VERSION"], [
|
||||||
[AC_MSG_ERROR("Python >= 2.6.x is not available")])
|
PYTHON_VERSION=$(basename $PYTHON | tr -cd 0-9.)
|
||||||
])
|
])
|
||||||
|
PYTHON_MINOR=${PYTHON_VERSION#*\.}
|
||||||
|
|
||||||
AS_IF([test "${PYTHON_VERSION:0:2}" = "3."], [
|
AS_CASE([$PYTHON_VERSION],
|
||||||
ZFS_AC_PYTHON_VERSION([>= '3.4'], [ /bin/true ],
|
[2.*], [
|
||||||
[AC_MSG_ERROR("Python >= 3.4.x is not available")])
|
AS_IF([test $PYTHON_MINOR -lt 6],
|
||||||
])
|
[AC_MSG_ERROR("Python >= 2.6 is required")])
|
||||||
|
],
|
||||||
|
[3.*], [
|
||||||
|
AS_IF([test $PYTHON_MINOR -lt 4],
|
||||||
|
[AC_MSG_ERROR("Python >= 3.4 is required")])
|
||||||
|
],
|
||||||
|
[:|2|3], [],
|
||||||
|
[PYTHON_VERSION=3]
|
||||||
|
)
|
||||||
|
|
||||||
|
AM_CONDITIONAL([USING_PYTHON], [test "$PYTHON" != :])
|
||||||
|
AM_CONDITIONAL([USING_PYTHON_2], [test "x${PYTHON_VERSION%%\.*}" = x2])
|
||||||
|
AM_CONDITIONAL([USING_PYTHON_3], [test "x${PYTHON_VERSION%%\.*}" = x3])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Request that packages be built for a specific Python version.
|
dnl # Request that packages be built for a specific Python version.
|
||||||
dnl #
|
dnl #
|
||||||
AS_IF([test $with_python != check], [
|
AS_IF([test "x$with_python" != xcheck], [
|
||||||
PYTHON_PKG_VERSION=`echo ${PYTHON} | tr -d 'a-zA-Z.'`
|
PYTHON_PKG_VERSION=$(echo $PYTHON_VERSION | tr -d .)
|
||||||
DEFINE_PYTHON_PKG_VERSION='--define "__use_python_pkg_version '${PYTHON_PKG_VERSION}'"'
|
DEFINE_PYTHON_PKG_VERSION='--define "__use_python_pkg_version '${PYTHON_PKG_VERSION}'"'
|
||||||
DEFINE_PYTHON_VERSION='--define "__use_python '${PYTHON}'"'
|
DEFINE_PYTHON_VERSION='--define "__use_python '${PYTHON}'"'
|
||||||
], [
|
], [
|
||||||
|
|||||||
+35
-15
@@ -1,5 +1,24 @@
|
|||||||
dnl #
|
dnl #
|
||||||
dnl # Determines if pyzfs can be built, requires Python 2.7 or latter.
|
dnl # ZFS_AC_PYTHON_MODULE(module_name, [action-if-true], [action-if-false])
|
||||||
|
dnl #
|
||||||
|
dnl # Checks for Python module. Freely inspired by AX_PYTHON_MODULE
|
||||||
|
dnl # https://www.gnu.org/software/autoconf-archive/ax_python_module.html
|
||||||
|
dnl # Required by ZFS_AC_CONFIG_ALWAYS_PYZFS.
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_PYTHON_MODULE], [
|
||||||
|
PYTHON_NAME=$(basename $PYTHON)
|
||||||
|
AC_MSG_CHECKING([for $PYTHON_NAME module: $1])
|
||||||
|
AS_IF([$PYTHON -c "import $1" 2>/dev/null], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
m4_ifvaln([$2], [$2])
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
m4_ifvaln([$3], [$3])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # Determines if pyzfs can be built, requires Python 2.7 or later.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
|
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
|
||||||
AC_ARG_ENABLE([pyzfs],
|
AC_ARG_ENABLE([pyzfs],
|
||||||
@@ -18,7 +37,12 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
|
|||||||
DEFINE_PYZFS='--without pyzfs'
|
DEFINE_PYZFS='--without pyzfs'
|
||||||
])
|
])
|
||||||
], [
|
], [
|
||||||
DEFINE_PYZFS=''
|
AS_IF([test "$PYTHON" != :], [
|
||||||
|
DEFINE_PYZFS=''
|
||||||
|
], [
|
||||||
|
enable_pyzfs=no
|
||||||
|
DEFINE_PYZFS='--without pyzfs'
|
||||||
|
])
|
||||||
])
|
])
|
||||||
AC_SUBST(DEFINE_PYZFS)
|
AC_SUBST(DEFINE_PYZFS)
|
||||||
|
|
||||||
@@ -26,20 +50,16 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
|
|||||||
dnl # Require python-devel libraries
|
dnl # Require python-devel libraries
|
||||||
dnl #
|
dnl #
|
||||||
AS_IF([test "x$enable_pyzfs" = xcheck -o "x$enable_pyzfs" = xyes], [
|
AS_IF([test "x$enable_pyzfs" = xcheck -o "x$enable_pyzfs" = xyes], [
|
||||||
AS_IF([test "${PYTHON_VERSION:0:2}" = "2."], [
|
AS_CASE([$PYTHON_VERSION],
|
||||||
PYTHON_REQUIRED_VERSION=">= '2.7.0'"
|
[3.*], [PYTHON_REQUIRED_VERSION=">= '3.4.0'"],
|
||||||
], [
|
[2.*], [PYTHON_REQUIRED_VERSION=">= '2.7.0'"],
|
||||||
AS_IF([test "${PYTHON_VERSION:0:2}" = "3."], [
|
[AC_MSG_ERROR("Python $PYTHON_VERSION unknown")]
|
||||||
PYTHON_REQUIRED_VERSION=">= '3.4.0'"
|
)
|
||||||
], [
|
|
||||||
AC_MSG_ERROR("Python $PYTHON_VERSION unknown")
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
AX_PYTHON_DEVEL([$PYTHON_REQUIRED_VERSION], [
|
AX_PYTHON_DEVEL([$PYTHON_REQUIRED_VERSION], [
|
||||||
AS_IF([test "x$enable_pyzfs" = xyes], [
|
AS_IF([test "x$enable_pyzfs" = xyes], [
|
||||||
AC_MSG_ERROR("Python $PYTHON_REQUIRED_VERSION development library is not installed")
|
AC_MSG_ERROR("Python $PYTHON_REQUIRED_VERSION development library is not installed")
|
||||||
], [test ! "x$enable_pyzfs" = xno], [
|
], [test "x$enable_pyzfs" != xno], [
|
||||||
enable_pyzfs=no
|
enable_pyzfs=no
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
@@ -52,7 +72,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
|
|||||||
ZFS_AC_PYTHON_MODULE([setuptools], [], [
|
ZFS_AC_PYTHON_MODULE([setuptools], [], [
|
||||||
AS_IF([test "x$enable_pyzfs" = xyes], [
|
AS_IF([test "x$enable_pyzfs" = xyes], [
|
||||||
AC_MSG_ERROR("Python $PYTHON_VERSION setuptools is not installed")
|
AC_MSG_ERROR("Python $PYTHON_VERSION setuptools is not installed")
|
||||||
], [test ! "x$enable_pyzfs" = xno], [
|
], [test "x$enable_pyzfs" != xno], [
|
||||||
enable_pyzfs=no
|
enable_pyzfs=no
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
@@ -65,7 +85,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
|
|||||||
ZFS_AC_PYTHON_MODULE([cffi], [], [
|
ZFS_AC_PYTHON_MODULE([cffi], [], [
|
||||||
AS_IF([test "x$enable_pyzfs" = xyes], [
|
AS_IF([test "x$enable_pyzfs" = xyes], [
|
||||||
AC_MSG_ERROR("Python $PYTHON_VERSION cffi is not installed")
|
AC_MSG_ERROR("Python $PYTHON_VERSION cffi is not installed")
|
||||||
], [test ! "x$enable_pyzfs" = xno], [
|
], [test "x$enable_pyzfs" != xno], [
|
||||||
enable_pyzfs=no
|
enable_pyzfs=no
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
@@ -76,7 +96,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [
|
|||||||
dnl #
|
dnl #
|
||||||
AS_IF([test "x$enable_pyzfs" = xcheck], [enable_pyzfs=yes])
|
AS_IF([test "x$enable_pyzfs" = xcheck], [enable_pyzfs=yes])
|
||||||
|
|
||||||
AM_CONDITIONAL([PYZFS_ENABLED], [test x$enable_pyzfs = xyes])
|
AM_CONDITIONAL([PYZFS_ENABLED], [test "x$enable_pyzfs" = xyes])
|
||||||
AC_SUBST([PYZFS_ENABLED], [$enable_pyzfs])
|
AC_SUBST([PYZFS_ENABLED], [$enable_pyzfs])
|
||||||
AC_SUBST(pythonsitedir, [$PYTHON_SITE_PKG])
|
AC_SUBST(pythonsitedir, [$PYTHON_SITE_PKG])
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -20,7 +20,7 @@ deb-kmod: deb-local rpm-kmod
|
|||||||
arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
|
arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
|
||||||
debarch=`$(DPKG) --print-architecture`; \
|
debarch=`$(DPKG) --print-architecture`; \
|
||||||
pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
|
pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
|
||||||
fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch $$pkg1; \
|
fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch $$pkg1 || exit 1; \
|
||||||
$(RM) $$pkg1
|
$(RM) $$pkg1
|
||||||
|
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ deb-dkms: deb-local rpm-dkms
|
|||||||
arch=`$(RPM) -qp $${name}-dkms-$${version}.src.rpm --qf %{arch} | tail -1`; \
|
arch=`$(RPM) -qp $${name}-dkms-$${version}.src.rpm --qf %{arch} | tail -1`; \
|
||||||
debarch=`$(DPKG) --print-architecture`; \
|
debarch=`$(DPKG) --print-architecture`; \
|
||||||
pkg1=$${name}-dkms-$${version}.$${arch}.rpm; \
|
pkg1=$${name}-dkms-$${version}.$${arch}.rpm; \
|
||||||
fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch $$pkg1; \
|
fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch $$pkg1 || exit 1; \
|
||||||
$(RM) $$pkg1
|
$(RM) $$pkg1
|
||||||
|
|
||||||
deb-utils: deb-local rpm-utils
|
deb-utils: deb-local rpm-utils
|
||||||
@@ -45,7 +45,7 @@ deb-utils: deb-local rpm-utils
|
|||||||
pkg5=libzpool2-$${version}.$${arch}.rpm; \
|
pkg5=libzpool2-$${version}.$${arch}.rpm; \
|
||||||
pkg6=libzfs2-devel-$${version}.$${arch}.rpm; \
|
pkg6=libzfs2-devel-$${version}.$${arch}.rpm; \
|
||||||
pkg7=$${name}-test-$${version}.$${arch}.rpm; \
|
pkg7=$${name}-test-$${version}.$${arch}.rpm; \
|
||||||
pkg8=$${name}-dracut-$${version}.$${arch}.rpm; \
|
pkg8=$${name}-dracut-$${version}.noarch.rpm; \
|
||||||
pkg9=$${name}-initramfs-$${version}.$${arch}.rpm; \
|
pkg9=$${name}-initramfs-$${version}.$${arch}.rpm; \
|
||||||
pkg10=`ls python*-pyzfs-$${version}* | tail -1`; \
|
pkg10=`ls python*-pyzfs-$${version}* | tail -1`; \
|
||||||
## Arguments need to be passed to dh_shlibdeps. Alien provides no mechanism
|
## Arguments need to be passed to dh_shlibdeps. Alien provides no mechanism
|
||||||
@@ -63,7 +63,7 @@ deb-utils: deb-local rpm-utils
|
|||||||
env PATH=$${path_prepend}:$${PATH} \
|
env PATH=$${path_prepend}:$${PATH} \
|
||||||
fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch \
|
fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch \
|
||||||
$$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
|
$$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
|
||||||
$$pkg8 $$pkg9 $$pkg10; \
|
$$pkg8 $$pkg9 $$pkg10 || exit 1; \
|
||||||
$(RM) $${path_prepend}/dh_shlibdeps; \
|
$(RM) $${path_prepend}/dh_shlibdeps; \
|
||||||
rmdir $${path_prepend}; \
|
rmdir $${path_prepend}; \
|
||||||
$(RM) $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
|
$(RM) $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ AC_DEFUN([ZFS_AC_KERNEL_FPU], [
|
|||||||
#include <asm/fpu/api.h>
|
#include <asm/fpu/api.h>
|
||||||
],[
|
],[
|
||||||
],[
|
],[
|
||||||
AC_DEFINE(HAVE_KERNEL_FPU_API_HEADER, 1, [kernel has asm/fpu/api.h])
|
AC_DEFINE(HAVE_KERNEL_FPU_API_HEADER, 1,
|
||||||
|
[kernel has asm/fpu/api.h])
|
||||||
AC_MSG_RESULT(asm/fpu/api.h)
|
AC_MSG_RESULT(asm/fpu/api.h)
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(i387.h & xcr.h)
|
AC_MSG_RESULT(i387.h & xcr.h)
|
||||||
@@ -39,8 +40,10 @@ AC_DEFUN([ZFS_AC_KERNEL_FPU], [
|
|||||||
kernel_fpu_end();
|
kernel_fpu_end();
|
||||||
], [kernel_fpu_begin], [arch/x86/kernel/fpu/core.c], [
|
], [kernel_fpu_begin], [arch/x86/kernel/fpu/core.c], [
|
||||||
AC_MSG_RESULT(kernel_fpu_*)
|
AC_MSG_RESULT(kernel_fpu_*)
|
||||||
AC_DEFINE(HAVE_KERNEL_FPU, 1, [kernel has kernel_fpu_* functions])
|
AC_DEFINE(HAVE_KERNEL_FPU, 1,
|
||||||
AC_DEFINE(KERNEL_EXPORTS_X86_FPU, 1, [kernel exports FPU functions])
|
[kernel has kernel_fpu_* functions])
|
||||||
|
AC_DEFINE(KERNEL_EXPORTS_X86_FPU, 1,
|
||||||
|
[kernel exports FPU functions])
|
||||||
],[
|
],[
|
||||||
ZFS_LINUX_TRY_COMPILE_SYMBOL([
|
ZFS_LINUX_TRY_COMPILE_SYMBOL([
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
dnl #
|
||||||
|
dnl # 2.6.39 API change
|
||||||
|
dnl #
|
||||||
|
dnl # 33ee3b2e2eb9 kstrto*: converting strings to integers done (hopefully) right
|
||||||
|
dnl #
|
||||||
|
dnl # If kstrtoul() doesn't exist, fallback to use strict_strtoul() which has
|
||||||
|
dnl # existed since 2.6.25.
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_KSTRTOUL], [
|
||||||
|
AC_MSG_CHECKING([whether kstrtoul() exists])
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
],[
|
||||||
|
int ret __attribute__ ((unused)) = kstrtoul(NULL, 10, NULL);
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_KSTRTOUL, 1, [kstrtoul() exists])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
dnl #
|
|
||||||
dnl # 3.9 API change
|
|
||||||
dnl # set_fs_pwd takes const struct path *
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SET_FS_PWD_WITH_CONST],
|
|
||||||
tmp_flags="$EXTRA_KCFLAGS"
|
|
||||||
EXTRA_KCFLAGS="-Werror"
|
|
||||||
[AC_MSG_CHECKING([whether set_fs_pwd() requires const struct path *])
|
|
||||||
ZFS_LINUX_TRY_COMPILE([
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <linux/fs_struct.h>
|
|
||||||
#include <linux/path.h>
|
|
||||||
void (*const set_fs_pwd_func)
|
|
||||||
(struct fs_struct *, const struct path *)
|
|
||||||
= set_fs_pwd;
|
|
||||||
],[
|
|
||||||
return 0;
|
|
||||||
],[
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_SET_FS_PWD_WITH_CONST, 1,
|
|
||||||
[set_fs_pwd() needs const path *])
|
|
||||||
],[
|
|
||||||
ZFS_LINUX_TRY_COMPILE([
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <linux/fs_struct.h>
|
|
||||||
#include <linux/path.h>
|
|
||||||
void (*const set_fs_pwd_func)
|
|
||||||
(struct fs_struct *, struct path *)
|
|
||||||
= set_fs_pwd;
|
|
||||||
],[
|
|
||||||
return 0;
|
|
||||||
],[
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
],[
|
|
||||||
AC_MSG_ERROR(unknown)
|
|
||||||
])
|
|
||||||
])
|
|
||||||
EXTRA_KCFLAGS="$tmp_flags"
|
|
||||||
])
|
|
||||||
+15
-7
@@ -144,7 +144,9 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
|
|||||||
ZFS_LINUX_TRY_COMPILE([
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
|
|
||||||
int shrinker_cb(int nr_to_scan, gfp_t gfp_mask);
|
int shrinker_cb(int nr_to_scan, gfp_t gfp_mask) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
],[
|
],[
|
||||||
struct shrinker cache_shrinker = {
|
struct shrinker cache_shrinker = {
|
||||||
.shrink = shrinker_cb,
|
.shrink = shrinker_cb,
|
||||||
@@ -166,8 +168,10 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
|
|||||||
ZFS_LINUX_TRY_COMPILE([
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
|
|
||||||
int shrinker_cb(struct shrinker *, int nr_to_scan,
|
int shrinker_cb(struct shrinker *shrink, int nr_to_scan,
|
||||||
gfp_t gfp_mask);
|
gfp_t gfp_mask) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
],[
|
],[
|
||||||
struct shrinker cache_shrinker = {
|
struct shrinker cache_shrinker = {
|
||||||
.shrink = shrinker_cb,
|
.shrink = shrinker_cb,
|
||||||
@@ -190,8 +194,10 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
|
|||||||
ZFS_LINUX_TRY_COMPILE([
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
|
|
||||||
int shrinker_cb(struct shrinker *,
|
int shrinker_cb(struct shrinker *shrink,
|
||||||
struct shrink_control *sc);
|
struct shrink_control *sc) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
],[
|
],[
|
||||||
struct shrinker cache_shrinker = {
|
struct shrinker cache_shrinker = {
|
||||||
.shrink = shrinker_cb,
|
.shrink = shrinker_cb,
|
||||||
@@ -215,8 +221,10 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
|
|||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
|
|
||||||
unsigned long shrinker_cb(
|
unsigned long shrinker_cb(
|
||||||
struct shrinker *,
|
struct shrinker *shrink,
|
||||||
struct shrink_control *sc);
|
struct shrink_control *sc) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
],[
|
],[
|
||||||
struct shrinker cache_shrinker = {
|
struct shrinker cache_shrinker = {
|
||||||
.count_objects = shrinker_cb,
|
.count_objects = shrinker_cb,
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
dnl #
|
|
||||||
dnl # 2.6.36 API change,
|
|
||||||
dnl # The 'struct fs_struct->lock' was changed from a rwlock_t to
|
|
||||||
dnl # a spinlock_t to improve the fastpath performance.
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_FS_STRUCT_SPINLOCK], [
|
|
||||||
AC_MSG_CHECKING([whether struct fs_struct uses spinlock_t])
|
|
||||||
tmp_flags="$EXTRA_KCFLAGS"
|
|
||||||
EXTRA_KCFLAGS="-Werror"
|
|
||||||
ZFS_LINUX_TRY_COMPILE([
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/fs_struct.h>
|
|
||||||
],[
|
|
||||||
static struct fs_struct fs;
|
|
||||||
spin_lock_init(&fs.lock);
|
|
||||||
],[
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_FS_STRUCT_SPINLOCK, 1,
|
|
||||||
[struct fs_struct uses spinlock_t])
|
|
||||||
],[
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
])
|
|
||||||
EXTRA_KCFLAGS="$tmp_flags"
|
|
||||||
])
|
|
||||||
+52
-11
@@ -1,26 +1,51 @@
|
|||||||
|
dnl # 4.14-rc3 API change
|
||||||
|
dnl # https://lwn.net/Articles/735887/
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 4.15 API change
|
|
||||||
dnl # https://lkml.org/lkml/2017/11/25/90
|
|
||||||
dnl # Check if timer_list.func get passed a timer_list or an unsigned long
|
dnl # Check if timer_list.func get passed a timer_list or an unsigned long
|
||||||
dnl # (older kernels). Also sanity check the from_timer() and timer_setup()
|
dnl # (older kernels). Also sanity check the from_timer() and timer_setup()
|
||||||
dnl # macros are available as well, since they will be used in the same newer
|
dnl # macros are available as well, since they will be used in the same newer
|
||||||
dnl # kernels that support the new timer_list.func signature.
|
dnl # kernels that support the new timer_list.func signature.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_TIMER_FUNCTION_TIMER_LIST], [
|
dnl # Also check for the existance of flags in struct timer_list, they were
|
||||||
AC_MSG_CHECKING([whether timer_list.function gets a timer_list])
|
dnl # added in 4.1-rc8 via 0eeda71bc30d.
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_TIMER_SETUP], [
|
||||||
|
AC_MSG_CHECKING([whether timer_setup() is available])
|
||||||
tmp_flags="$EXTRA_KCFLAGS"
|
tmp_flags="$EXTRA_KCFLAGS"
|
||||||
EXTRA_KCFLAGS="-Werror"
|
EXTRA_KCFLAGS="-Werror"
|
||||||
|
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
|
#include <linux/timer.h>
|
||||||
|
|
||||||
|
struct my_task_timer {
|
||||||
|
struct timer_list timer;
|
||||||
|
int data;
|
||||||
|
};
|
||||||
|
|
||||||
|
void task_expire(struct timer_list *tl)
|
||||||
|
{
|
||||||
|
struct my_task_timer *task_timer = from_timer(task_timer, tl, timer);
|
||||||
|
task_timer->data = 42;
|
||||||
|
}
|
||||||
|
],[
|
||||||
|
struct my_task_timer task_timer;
|
||||||
|
timer_setup(&task_timer.timer, task_expire, 0);
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_KERNEL_TIMER_SETUP, 1,
|
||||||
|
[timer_setup() is available])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([whether timer function expects timer_list])
|
||||||
|
|
||||||
ZFS_LINUX_TRY_COMPILE([
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
void task_expire(struct timer_list *tl) {}
|
void task_expire(struct timer_list *tl) {}
|
||||||
],[
|
],[
|
||||||
#ifndef from_timer
|
struct timer_list tl;
|
||||||
#error "No from_timer() macro"
|
tl.function = task_expire;
|
||||||
#endif
|
|
||||||
|
|
||||||
struct timer_list timer;
|
|
||||||
timer.function = task_expire;
|
|
||||||
timer_setup(&timer, NULL, 0);
|
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_KERNEL_TIMER_FUNCTION_TIMER_LIST, 1,
|
AC_DEFINE(HAVE_KERNEL_TIMER_FUNCTION_TIMER_LIST, 1,
|
||||||
@@ -28,5 +53,21 @@ AC_DEFUN([ZFS_AC_KERNEL_TIMER_FUNCTION_TIMER_LIST], [
|
|||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([whether struct timer_list has flags])
|
||||||
|
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
|
#include <linux/timer.h>
|
||||||
|
],[
|
||||||
|
struct timer_list tl;
|
||||||
|
tl.flags = 2;
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_KERNEL_TIMER_LIST_FLAGS, 1,
|
||||||
|
[struct timer_list has a flags member])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
|
||||||
EXTRA_KCFLAGS="$tmp_flags"
|
EXTRA_KCFLAGS="$tmp_flags"
|
||||||
])
|
])
|
||||||
|
|||||||
+5
-5
@@ -11,9 +11,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
|
|||||||
ZFS_AC_KERNEL_CONFIG
|
ZFS_AC_KERNEL_CONFIG
|
||||||
ZFS_AC_KERNEL_CTL_NAME
|
ZFS_AC_KERNEL_CTL_NAME
|
||||||
ZFS_AC_KERNEL_PDE_DATA
|
ZFS_AC_KERNEL_PDE_DATA
|
||||||
ZFS_AC_KERNEL_SET_FS_PWD_WITH_CONST
|
|
||||||
ZFS_AC_KERNEL_2ARGS_VFS_FSYNC
|
ZFS_AC_KERNEL_2ARGS_VFS_FSYNC
|
||||||
ZFS_AC_KERNEL_FS_STRUCT_SPINLOCK
|
|
||||||
ZFS_AC_KERNEL_KUIDGID_T
|
ZFS_AC_KERNEL_KUIDGID_T
|
||||||
ZFS_AC_KERNEL_FALLOCATE
|
ZFS_AC_KERNEL_FALLOCATE
|
||||||
ZFS_AC_KERNEL_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE
|
ZFS_AC_KERNEL_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE
|
||||||
@@ -37,7 +35,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
|
|||||||
ZFS_AC_KERNEL_GROUP_INFO_GID
|
ZFS_AC_KERNEL_GROUP_INFO_GID
|
||||||
ZFS_AC_KERNEL_WRITE
|
ZFS_AC_KERNEL_WRITE
|
||||||
ZFS_AC_KERNEL_READ
|
ZFS_AC_KERNEL_READ
|
||||||
ZFS_AC_KERNEL_TIMER_FUNCTION_TIMER_LIST
|
ZFS_AC_KERNEL_TIMER_SETUP
|
||||||
ZFS_AC_KERNEL_DECLARE_EVENT_CLASS
|
ZFS_AC_KERNEL_DECLARE_EVENT_CLASS
|
||||||
ZFS_AC_KERNEL_CURRENT_BIO_TAIL
|
ZFS_AC_KERNEL_CURRENT_BIO_TAIL
|
||||||
ZFS_AC_KERNEL_SUPER_USER_NS
|
ZFS_AC_KERNEL_SUPER_USER_NS
|
||||||
@@ -167,6 +165,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
|
|||||||
ZFS_AC_KERNEL_TOTALHIGH_PAGES
|
ZFS_AC_KERNEL_TOTALHIGH_PAGES
|
||||||
ZFS_AC_KERNEL_BLK_QUEUE_DISCARD
|
ZFS_AC_KERNEL_BLK_QUEUE_DISCARD
|
||||||
ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE
|
ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE
|
||||||
|
ZFS_AC_KERNEL_KSTRTOUL
|
||||||
|
|
||||||
AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
|
AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
|
||||||
KERNEL_MAKE="$KERNEL_MAKE O=$LINUX_OBJ"
|
KERNEL_MAKE="$KERNEL_MAKE O=$LINUX_OBJ"
|
||||||
@@ -529,10 +528,11 @@ AC_DEFUN([ZFS_AC_KERNEL_CONFIG_TRIM_UNUSED_KSYMS], [
|
|||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
AC_MSG_ERROR([
|
AS_IF([test "x$enable_linux_builtin" != xyes], [
|
||||||
|
AC_MSG_ERROR([
|
||||||
*** This kernel has unused symbols trimming enabled, please disable.
|
*** This kernel has unused symbols trimming enabled, please disable.
|
||||||
*** Rebuild the kernel with CONFIG_TRIM_UNUSED_KSYMS=n set.])
|
*** Rebuild the kernel with CONFIG_TRIM_UNUSED_KSYMS=n set.])
|
||||||
])
|
])])
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
|
|||||||
@@ -120,8 +120,10 @@ AC_CONFIG_FILES([
|
|||||||
cmd/dbufstat/Makefile
|
cmd/dbufstat/Makefile
|
||||||
cmd/arc_summary/Makefile
|
cmd/arc_summary/Makefile
|
||||||
cmd/zed/Makefile
|
cmd/zed/Makefile
|
||||||
|
cmd/zed/zed.d/Makefile
|
||||||
cmd/raidz_test/Makefile
|
cmd/raidz_test/Makefile
|
||||||
cmd/zgenhostid/Makefile
|
cmd/zgenhostid/Makefile
|
||||||
|
cmd/zvol_wait/Makefile
|
||||||
contrib/Makefile
|
contrib/Makefile
|
||||||
contrib/bash_completion.d/Makefile
|
contrib/bash_completion.d/Makefile
|
||||||
contrib/dracut/Makefile
|
contrib/dracut/Makefile
|
||||||
@@ -271,6 +273,7 @@ AC_CONFIG_FILES([
|
|||||||
tests/zfs-tests/tests/functional/cli_user/zfs_list/Makefile
|
tests/zfs-tests/tests/functional/cli_user/zfs_list/Makefile
|
||||||
tests/zfs-tests/tests/functional/cli_user/zpool_iostat/Makefile
|
tests/zfs-tests/tests/functional/cli_user/zpool_iostat/Makefile
|
||||||
tests/zfs-tests/tests/functional/cli_user/zpool_list/Makefile
|
tests/zfs-tests/tests/functional/cli_user/zpool_list/Makefile
|
||||||
|
tests/zfs-tests/tests/functional/cli_user/zpool_status/Makefile
|
||||||
tests/zfs-tests/tests/functional/compression/Makefile
|
tests/zfs-tests/tests/functional/compression/Makefile
|
||||||
tests/zfs-tests/tests/functional/cp_files/Makefile
|
tests/zfs-tests/tests/functional/cp_files/Makefile
|
||||||
tests/zfs-tests/tests/functional/ctime/Makefile
|
tests/zfs-tests/tests/functional/ctime/Makefile
|
||||||
@@ -326,6 +329,7 @@ AC_CONFIG_FILES([
|
|||||||
tests/zfs-tests/tests/functional/snapshot/Makefile
|
tests/zfs-tests/tests/functional/snapshot/Makefile
|
||||||
tests/zfs-tests/tests/functional/snapused/Makefile
|
tests/zfs-tests/tests/functional/snapused/Makefile
|
||||||
tests/zfs-tests/tests/functional/sparse/Makefile
|
tests/zfs-tests/tests/functional/sparse/Makefile
|
||||||
|
tests/zfs-tests/tests/functional/suid/Makefile
|
||||||
tests/zfs-tests/tests/functional/alloc_class/Makefile
|
tests/zfs-tests/tests/functional/alloc_class/Makefile
|
||||||
tests/zfs-tests/tests/functional/threadsappend/Makefile
|
tests/zfs-tests/tests/functional/threadsappend/Makefile
|
||||||
tests/zfs-tests/tests/functional/tmpfile/Makefile
|
tests/zfs-tests/tests/functional/tmpfile/Makefile
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ ask_for_password() {
|
|||||||
|
|
||||||
{ flock -s 9;
|
{ flock -s 9;
|
||||||
# Prompt for password with plymouth, if installed and running.
|
# Prompt for password with plymouth, if installed and running.
|
||||||
if whereis plymouth >/dev/null 2>&1 && plymouth --ping 2>/dev/null; then
|
if type plymouth >/dev/null 2>&1 && plymouth --ping 2>/dev/null; then
|
||||||
plymouth ask-for-password \
|
plymouth ask-for-password \
|
||||||
--prompt "$ply_prompt" --number-of-tries="$ply_tries" \
|
--prompt "$ply_prompt" --number-of-tries="$ply_tries" \
|
||||||
--command="$ply_cmd"
|
--command="$ply_cmd"
|
||||||
|
|||||||
@@ -11,13 +11,18 @@ EXTRA_DIST = \
|
|||||||
$(top_srcdir)/contrib/initramfs/README.initramfs.markdown
|
$(top_srcdir)/contrib/initramfs/README.initramfs.markdown
|
||||||
|
|
||||||
install-initrdSCRIPTS: $(EXTRA_DIST)
|
install-initrdSCRIPTS: $(EXTRA_DIST)
|
||||||
for d in conf.d conf-hooks.d hooks scripts scripts/local-top; do \
|
for d in conf.d conf-hooks.d scripts/local-top; do \
|
||||||
$(MKDIR_P) $(DESTDIR)$(initrddir)/$$d; \
|
$(MKDIR_P) $(DESTDIR)$(initrddir)/$$d; \
|
||||||
cp $(top_srcdir)/contrib/initramfs/$$d/zfs \
|
cp $(top_srcdir)/contrib/initramfs/$$d/zfs \
|
||||||
$(DESTDIR)$(initrddir)/$$d/; \
|
$(DESTDIR)$(initrddir)/$$d/; \
|
||||||
done
|
done
|
||||||
if [ -f etc/init.d/zfs ]; then \
|
for d in hooks scripts; do \
|
||||||
$(MKDIR_P) $(DESTDIR)$(DEFAULT_INITCONF_DIR); \
|
$(MKDIR_P) $(DESTDIR)$(initrddir)/$$d; \
|
||||||
cp $(top_srcdir)/etc/init.d/zfs \
|
cp $(top_builddir)/contrib/initramfs/$$d/zfs \
|
||||||
$(DESTDIR)$(DEFAULT_INITCONF_DIR)/; \
|
$(DESTDIR)$(initrddir)/$$d/; \
|
||||||
|
done
|
||||||
|
if [ -f $(top_builddir)/etc/init.d/zfs ]; then \
|
||||||
|
$(MKDIR_P) $(DESTDIR)$(DEFAULT_INITCONF_DIR); \
|
||||||
|
cp $(top_builddir)/etc/init.d/zfs \
|
||||||
|
$(DESTDIR)$(DEFAULT_INITCONF_DIR)/; \
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -411,29 +411,29 @@ decrypt_fs()
|
|||||||
|
|
||||||
# Determine dataset that holds key for root dataset
|
# Determine dataset that holds key for root dataset
|
||||||
ENCRYPTIONROOT=$(${ZFS} get -H -o value encryptionroot "${fs}")
|
ENCRYPTIONROOT=$(${ZFS} get -H -o value encryptionroot "${fs}")
|
||||||
DECRYPT_CMD="${ZFS} load-key '${ENCRYPTIONROOT}'"
|
|
||||||
|
|
||||||
# If root dataset is encrypted...
|
# If root dataset is encrypted...
|
||||||
if ! [ "${ENCRYPTIONROOT}" = "-" ]; then
|
if ! [ "${ENCRYPTIONROOT}" = "-" ]; then
|
||||||
|
TRY_COUNT=3
|
||||||
# Prompt with plymouth, if active
|
# Prompt with plymouth, if active
|
||||||
if [ -e /bin/plymouth ] && /bin/plymouth --ping 2>/dev/null; then
|
if [ -e /bin/plymouth ] && /bin/plymouth --ping 2>/dev/null; then
|
||||||
plymouth ask-for-password --prompt "Encrypted ZFS password for ${ENCRYPTIONROOT}" \
|
while [ $TRY_COUNT -gt 0 ]; do
|
||||||
--number-of-tries="3" \
|
plymouth ask-for-password --prompt "Encrypted ZFS password for ${ENCRYPTIONROOT}" | \
|
||||||
--command="${DECRYPT_CMD}"
|
$ZFS load-key "${ENCRYPTIONROOT}" && break
|
||||||
|
TRY_COUNT=$((TRY_COUNT - 1))
|
||||||
|
done
|
||||||
|
|
||||||
# Prompt with systemd, if active
|
# Prompt with systemd, if active
|
||||||
elif [ -e /run/systemd/system ]; then
|
elif [ -e /run/systemd/system ]; then
|
||||||
TRY_COUNT=3
|
|
||||||
while [ $TRY_COUNT -gt 0 ]; do
|
while [ $TRY_COUNT -gt 0 ]; do
|
||||||
systemd-ask-password "Encrypted ZFS password for ${ENCRYPTIONROOT}" --no-tty | \
|
systemd-ask-password "Encrypted ZFS password for ${ENCRYPTIONROOT}" --no-tty | \
|
||||||
${DECRYPT_CMD} && break
|
$ZFS load-key "${ENCRYPTIONROOT}" && break
|
||||||
TRY_COUNT=$((TRY_COUNT - 1))
|
TRY_COUNT=$((TRY_COUNT - 1))
|
||||||
done
|
done
|
||||||
|
|
||||||
# Prompt with ZFS tty, otherwise
|
# Prompt with ZFS tty, otherwise
|
||||||
else
|
else
|
||||||
eval "${DECRYPT_CMD}"
|
$ZFS load-key "${ENCRYPTIONROOT}"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -878,7 +878,9 @@ mountroot()
|
|||||||
pool="$("${ZPOOL}" get name,guid -o name,value -H | \
|
pool="$("${ZPOOL}" get name,guid -o name,value -H | \
|
||||||
awk -v pool="${ZFS_RPOOL}" '$2 == pool { print $1 }')"
|
awk -v pool="${ZFS_RPOOL}" '$2 == pool { print $1 }')"
|
||||||
if [ -n "$pool" ]; then
|
if [ -n "$pool" ]; then
|
||||||
ZFS_BOOTFS="${pool}/${ZFS_BOOTFS#*/}"
|
# If $ZFS_BOOTFS contains guid, replace the guid portion with $pool
|
||||||
|
ZFS_BOOTFS=$(echo "$ZFS_BOOTFS" | \
|
||||||
|
sed -e "s/$("${ZPOOL}" get guid -o value "$pool" -H)/$pool/g")
|
||||||
ZFS_RPOOL="${pool}"
|
ZFS_RPOOL="${pool}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ all-local:
|
|||||||
# files are later created by manually loading the Python modules.
|
# files are later created by manually loading the Python modules.
|
||||||
#
|
#
|
||||||
install-exec-local:
|
install-exec-local:
|
||||||
$(PYTHON) $(srcdir)/setup.py install \
|
$(PYTHON) $(builddir)/setup.py install \
|
||||||
--prefix $(prefix) \
|
--prefix $(prefix) \
|
||||||
--root $(DESTDIR)/ \
|
--root $(DESTDIR)/ \
|
||||||
--install-lib $(pythonsitedir) \
|
--install-lib $(pythonsitedir) \
|
||||||
|
|||||||
@@ -294,13 +294,6 @@ checksystem()
|
|||||||
# Just make sure that /dev/zfs is created.
|
# Just make sure that /dev/zfs is created.
|
||||||
udev_trigger
|
udev_trigger
|
||||||
|
|
||||||
if ! [ "$(uname -m)" = "x86_64" ]; then
|
|
||||||
echo "Warning: You're not running 64bit. Currently native zfs in";
|
|
||||||
echo " Linux is only supported and tested on 64bit.";
|
|
||||||
# should we break here? People doing this should know what they
|
|
||||||
# do, thus i'm not breaking here.
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ process_line() {
|
|||||||
p_readonly="${8}"
|
p_readonly="${8}"
|
||||||
p_setuid="${9}"
|
p_setuid="${9}"
|
||||||
p_nbmand="${10}"
|
p_nbmand="${10}"
|
||||||
|
p_encroot="${11}"
|
||||||
|
p_keyloc="${12}"
|
||||||
|
|
||||||
# Check for canmount=off .
|
# Check for canmount=off .
|
||||||
if [ "${p_canmount}" = "off" ] ; then
|
if [ "${p_canmount}" = "off" ] ; then
|
||||||
@@ -168,6 +170,54 @@ process_line() {
|
|||||||
"${dataset}" >/dev/kmsg
|
"${dataset}" >/dev/kmsg
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Minimal pre-requisites to mount a ZFS dataset
|
||||||
|
wants="zfs-import.target"
|
||||||
|
if [ -n "${p_encroot}" ] &&
|
||||||
|
[ "${p_encroot}" != "-" ] ; then
|
||||||
|
keyloadunit="zfs-load-key-$(systemd-escape "${p_encroot}").service"
|
||||||
|
if [ "${p_encroot}" = "${dataset}" ] ; then
|
||||||
|
pathdep=""
|
||||||
|
if [ "${p_keyloc%%://*}" = "file" ] ; then
|
||||||
|
pathdep="RequiresMountsFor='${p_keyloc#file://}'"
|
||||||
|
keyloadcmd="@sbindir@/zfs load-key '${dataset}'"
|
||||||
|
elif [ "${p_keyloc}" = "prompt" ] ; then
|
||||||
|
keyloadcmd="sh -c 'set -eu;"\
|
||||||
|
"count=0;"\
|
||||||
|
"while [ \$\$count -lt 3 ];do"\
|
||||||
|
" systemd-ask-password --id=\"zfs:${dataset}\""\
|
||||||
|
" \"Enter passphrase for ${dataset}:\"|"\
|
||||||
|
" @sbindir@/zfs load-key \"${dataset}\" && exit 0;"\
|
||||||
|
" count=\$\$((count + 1));"\
|
||||||
|
"done;"\
|
||||||
|
"exit 1'"
|
||||||
|
else
|
||||||
|
printf 'zfs-mount-generator: (%s) invalid keylocation\n' \
|
||||||
|
"${dataset}" >/dev/kmsg
|
||||||
|
fi
|
||||||
|
cat > "${dest_norm}/${keyloadunit}" << EOF
|
||||||
|
# Automatically generated by zfs-mount-generator
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Load ZFS key for ${dataset}
|
||||||
|
SourcePath=${cachefile}
|
||||||
|
Documentation=man:zfs-mount-generator(8)
|
||||||
|
DefaultDependencies=no
|
||||||
|
Wants=${wants}
|
||||||
|
After=${wants}
|
||||||
|
${pathdep}
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
RemainAfterExit=yes
|
||||||
|
ExecStart=${keyloadcmd}
|
||||||
|
ExecStop=@sbindir@/zfs unload-key '${dataset}'
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
# Update the dependencies for the mount file to require the
|
||||||
|
# key-loading unit.
|
||||||
|
wants="${wants} ${keyloadunit}"
|
||||||
|
fi
|
||||||
|
|
||||||
# If the mountpoint has already been created, give it precedence.
|
# If the mountpoint has already been created, give it precedence.
|
||||||
if [ -e "${dest_norm}/${mountfile}" ] ; then
|
if [ -e "${dest_norm}/${mountfile}" ] ; then
|
||||||
printf 'zfs-mount-generator: %s already exists\n' "${mountfile}" \
|
printf 'zfs-mount-generator: %s already exists\n' "${mountfile}" \
|
||||||
@@ -183,8 +233,8 @@ process_line() {
|
|||||||
SourcePath=${cachefile}
|
SourcePath=${cachefile}
|
||||||
Documentation=man:zfs-mount-generator(8)
|
Documentation=man:zfs-mount-generator(8)
|
||||||
Before=local-fs.target zfs-mount.service
|
Before=local-fs.target zfs-mount.service
|
||||||
After=zfs-import.target
|
After=${wants}
|
||||||
Wants=zfs-import.target
|
Wants=${wants}
|
||||||
|
|
||||||
[Mount]
|
[Mount]
|
||||||
Where=${p_mountpoint}
|
Where=${p_mountpoint}
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ enable zfs-import.target
|
|||||||
enable zfs-mount.service
|
enable zfs-mount.service
|
||||||
enable zfs-share.service
|
enable zfs-share.service
|
||||||
enable zfs-zed.service
|
enable zfs-zed.service
|
||||||
|
enable zfs-volume-wait.service
|
||||||
enable zfs.target
|
enable zfs.target
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ systemdunit_DATA = \
|
|||||||
zfs-import-scan.service \
|
zfs-import-scan.service \
|
||||||
zfs-mount.service \
|
zfs-mount.service \
|
||||||
zfs-share.service \
|
zfs-share.service \
|
||||||
|
zfs-volume-wait.service \
|
||||||
zfs-import.target \
|
zfs-import.target \
|
||||||
|
zfs-volumes.target \
|
||||||
zfs.target
|
zfs.target
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
@@ -17,6 +19,8 @@ EXTRA_DIST = \
|
|||||||
$(top_srcdir)/etc/systemd/system/zfs-mount.service.in \
|
$(top_srcdir)/etc/systemd/system/zfs-mount.service.in \
|
||||||
$(top_srcdir)/etc/systemd/system/zfs-share.service.in \
|
$(top_srcdir)/etc/systemd/system/zfs-share.service.in \
|
||||||
$(top_srcdir)/etc/systemd/system/zfs-import.target.in \
|
$(top_srcdir)/etc/systemd/system/zfs-import.target.in \
|
||||||
|
$(top_srcdir)/etc/systemd/system/zfs-volume-wait.service.in \
|
||||||
|
$(top_srcdir)/etc/systemd/system/zfs-volumes.target.in \
|
||||||
$(top_srcdir)/etc/systemd/system/zfs.target.in \
|
$(top_srcdir)/etc/systemd/system/zfs.target.in \
|
||||||
$(top_srcdir)/etc/systemd/system/50-zfs.preset.in
|
$(top_srcdir)/etc/systemd/system/50-zfs.preset.in
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ After=nfs-server.service nfs-kernel-server.service
|
|||||||
After=smb.service
|
After=smb.service
|
||||||
Before=rpc-statd-notify.service
|
Before=rpc-statd-notify.service
|
||||||
Wants=zfs-mount.service
|
Wants=zfs-mount.service
|
||||||
|
After=zfs-mount.service
|
||||||
PartOf=nfs-server.service nfs-kernel-server.service
|
PartOf=nfs-server.service nfs-kernel-server.service
|
||||||
PartOf=smb.service
|
PartOf=smb.service
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Wait for ZFS Volume (zvol) links in /dev
|
||||||
|
DefaultDependencies=no
|
||||||
|
After=systemd-udev-settle.service
|
||||||
|
After=zfs-import.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
RemainAfterExit=yes
|
||||||
|
ExecStart=@bindir@/zvol_wait
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=zfs-volumes.target
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=ZFS volumes are ready
|
||||||
|
After=zfs-volume-wait.service
|
||||||
|
Requires=zfs-volume-wait.service
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=zfs.target
|
||||||
@@ -147,6 +147,7 @@ typedef enum zfs_error {
|
|||||||
EZFS_NO_TRIM, /* no active trim */
|
EZFS_NO_TRIM, /* no active trim */
|
||||||
EZFS_TRIM_NOTSUP, /* device does not support trim */
|
EZFS_TRIM_NOTSUP, /* device does not support trim */
|
||||||
EZFS_NO_RESILVER_DEFER, /* pool doesn't support resilver_defer */
|
EZFS_NO_RESILVER_DEFER, /* pool doesn't support resilver_defer */
|
||||||
|
EZFS_EXPORT_IN_PROGRESS, /* currently exporting the pool */
|
||||||
EZFS_UNKNOWN
|
EZFS_UNKNOWN
|
||||||
} zfs_error_t;
|
} zfs_error_t;
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,10 @@
|
|||||||
* USER API:
|
* USER API:
|
||||||
*
|
*
|
||||||
* Kernel fpu methods:
|
* Kernel fpu methods:
|
||||||
* kfpu_begin()
|
* kfpu_allowed()
|
||||||
* kfpu_end()
|
* kfpu_initialize()
|
||||||
|
* kfpu_begin()
|
||||||
|
* kfpu_end()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SIMD_AARCH64_H
|
#ifndef _SIMD_AARCH64_H
|
||||||
|
|||||||
+25
-23
@@ -26,8 +26,10 @@
|
|||||||
* USER API:
|
* USER API:
|
||||||
*
|
*
|
||||||
* Kernel fpu methods:
|
* Kernel fpu methods:
|
||||||
* kfpu_begin()
|
* kfpu_allowed()
|
||||||
* kfpu_end()
|
* kfpu_initialize()
|
||||||
|
* kfpu_begin()
|
||||||
|
* kfpu_end()
|
||||||
*
|
*
|
||||||
* SIMD support:
|
* SIMD support:
|
||||||
*
|
*
|
||||||
@@ -37,31 +39,31 @@
|
|||||||
* all relevant feature test functions should be called.
|
* all relevant feature test functions should be called.
|
||||||
*
|
*
|
||||||
* Supported features:
|
* Supported features:
|
||||||
* zfs_sse_available()
|
* zfs_sse_available()
|
||||||
* zfs_sse2_available()
|
* zfs_sse2_available()
|
||||||
* zfs_sse3_available()
|
* zfs_sse3_available()
|
||||||
* zfs_ssse3_available()
|
* zfs_ssse3_available()
|
||||||
* zfs_sse4_1_available()
|
* zfs_sse4_1_available()
|
||||||
* zfs_sse4_2_available()
|
* zfs_sse4_2_available()
|
||||||
*
|
*
|
||||||
* zfs_avx_available()
|
* zfs_avx_available()
|
||||||
* zfs_avx2_available()
|
* zfs_avx2_available()
|
||||||
*
|
*
|
||||||
* zfs_bmi1_available()
|
* zfs_bmi1_available()
|
||||||
* zfs_bmi2_available()
|
* zfs_bmi2_available()
|
||||||
*
|
*
|
||||||
* zfs_avx512f_available()
|
* zfs_avx512f_available()
|
||||||
* zfs_avx512cd_available()
|
* zfs_avx512cd_available()
|
||||||
* zfs_avx512er_available()
|
* zfs_avx512er_available()
|
||||||
* zfs_avx512pf_available()
|
* zfs_avx512pf_available()
|
||||||
* zfs_avx512bw_available()
|
* zfs_avx512bw_available()
|
||||||
* zfs_avx512dq_available()
|
* zfs_avx512dq_available()
|
||||||
* zfs_avx512vl_available()
|
* zfs_avx512vl_available()
|
||||||
* zfs_avx512ifma_available()
|
* zfs_avx512ifma_available()
|
||||||
* zfs_avx512vbmi_available()
|
* zfs_avx512vbmi_available()
|
||||||
*
|
*
|
||||||
* NOTE(AVX-512VL): If using AVX-512 instructions with 128Bit registers
|
* NOTE(AVX-512VL): If using AVX-512 instructions with 128Bit registers
|
||||||
* also add zfs_avx512vl_available() to feature check.
|
* also add zfs_avx512vl_available() to feature check.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SIMD_X86_H
|
#ifndef _SIMD_X86_H
|
||||||
@@ -190,7 +192,7 @@ typedef struct cpuid_feature_desc {
|
|||||||
* Descriptions of supported instruction sets
|
* Descriptions of supported instruction sets
|
||||||
*/
|
*/
|
||||||
static const cpuid_feature_desc_t cpuid_features[] = {
|
static const cpuid_feature_desc_t cpuid_features[] = {
|
||||||
[SSE] = {1U, 0U, 1U << 25, EDX },
|
[SSE] = {1U, 0U, 1U << 25, EDX },
|
||||||
[SSE2] = {1U, 0U, 1U << 26, EDX },
|
[SSE2] = {1U, 0U, 1U << 26, EDX },
|
||||||
[SSE3] = {1U, 0U, 1U << 0, ECX },
|
[SSE3] = {1U, 0U, 1U << 0, ECX },
|
||||||
[SSSE3] = {1U, 0U, 1U << 9, ECX },
|
[SSSE3] = {1U, 0U, 1U << 9, ECX },
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ void spl_dumpstack(void);
|
|||||||
if (!(_verify3_left OP _verify3_right)) \
|
if (!(_verify3_left OP _verify3_right)) \
|
||||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||||
"failed (%px" #OP " %px)\n", \
|
"failed (%px " #OP " %px)\n", \
|
||||||
(void *) (_verify3_left), \
|
(void *) (_verify3_left), \
|
||||||
(void *) (_verify3_right)); \
|
(void *) (_verify3_right)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|||||||
@@ -127,6 +127,8 @@ spl_mutex_lockdep_on_maybe(kmutex_t *mp) \
|
|||||||
})
|
})
|
||||||
/* END CSTYLED */
|
/* END CSTYLED */
|
||||||
|
|
||||||
|
#define NESTED_SINGLE 1
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||||
#define mutex_enter_nested(mp, subclass) \
|
#define mutex_enter_nested(mp, subclass) \
|
||||||
{ \
|
{ \
|
||||||
@@ -179,7 +181,4 @@ spl_mutex_lockdep_on_maybe(kmutex_t *mp) \
|
|||||||
/* NOTE: do not dereference mp after this point */ \
|
/* NOTE: do not dereference mp after this point */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
int spl_mutex_init(void);
|
|
||||||
void spl_mutex_fini(void);
|
|
||||||
|
|
||||||
#endif /* _SPL_MUTEX_H */
|
#endif /* _SPL_MUTEX_H */
|
||||||
|
|||||||
+12
-120
@@ -29,43 +29,6 @@
|
|||||||
#include <linux/rwsem.h>
|
#include <linux/rwsem.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
|
||||||
/* Linux kernel compatibility */
|
|
||||||
#if defined(CONFIG_PREEMPT_RT_FULL)
|
|
||||||
#define SPL_RWSEM_SINGLE_READER_VALUE (1)
|
|
||||||
#define SPL_RWSEM_SINGLE_WRITER_VALUE (0)
|
|
||||||
#elif defined(CONFIG_RWSEM_GENERIC_SPINLOCK)
|
|
||||||
#define SPL_RWSEM_SINGLE_READER_VALUE (1)
|
|
||||||
#define SPL_RWSEM_SINGLE_WRITER_VALUE (-1)
|
|
||||||
#elif defined(RWSEM_ACTIVE_MASK)
|
|
||||||
#define SPL_RWSEM_SINGLE_READER_VALUE (RWSEM_ACTIVE_READ_BIAS)
|
|
||||||
#define SPL_RWSEM_SINGLE_WRITER_VALUE (RWSEM_ACTIVE_WRITE_BIAS)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Linux 3.16 changed activity to count for rwsem-spinlock */
|
|
||||||
#if defined(CONFIG_PREEMPT_RT_FULL)
|
|
||||||
#define RWSEM_COUNT(sem) sem->read_depth
|
|
||||||
#elif defined(HAVE_RWSEM_ACTIVITY)
|
|
||||||
#define RWSEM_COUNT(sem) sem->activity
|
|
||||||
/* Linux 4.8 changed count to an atomic_long_t for !rwsem-spinlock */
|
|
||||||
#elif defined(HAVE_RWSEM_ATOMIC_LONG_COUNT)
|
|
||||||
#define RWSEM_COUNT(sem) atomic_long_read(&(sem)->count)
|
|
||||||
#else
|
|
||||||
#define RWSEM_COUNT(sem) sem->count
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(RWSEM_SPINLOCK_IS_RAW)
|
|
||||||
#define spl_rwsem_lock_irqsave(lk, fl) raw_spin_lock_irqsave(lk, fl)
|
|
||||||
#define spl_rwsem_unlock_irqrestore(lk, fl) \
|
|
||||||
raw_spin_unlock_irqrestore(lk, fl)
|
|
||||||
#define spl_rwsem_trylock_irqsave(lk, fl) raw_spin_trylock_irqsave(lk, fl)
|
|
||||||
#else
|
|
||||||
#define spl_rwsem_lock_irqsave(lk, fl) spin_lock_irqsave(lk, fl)
|
|
||||||
#define spl_rwsem_unlock_irqrestore(lk, fl) spin_unlock_irqrestore(lk, fl)
|
|
||||||
#define spl_rwsem_trylock_irqsave(lk, fl) spin_trylock_irqsave(lk, fl)
|
|
||||||
#endif /* RWSEM_SPINLOCK_IS_RAW */
|
|
||||||
|
|
||||||
#define spl_rwsem_is_locked(rwsem) rwsem_is_locked(rwsem)
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RW_DRIVER = 2,
|
RW_DRIVER = 2,
|
||||||
RW_DEFAULT = 4,
|
RW_DEFAULT = 4,
|
||||||
@@ -78,15 +41,9 @@ typedef enum {
|
|||||||
RW_READER = 2
|
RW_READER = 2
|
||||||
} krw_t;
|
} krw_t;
|
||||||
|
|
||||||
/*
|
|
||||||
* If CONFIG_RWSEM_SPIN_ON_OWNER is defined, rw_semaphore will have an owner
|
|
||||||
* field, so we don't need our own.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct rw_semaphore rw_rwlock;
|
struct rw_semaphore rw_rwlock;
|
||||||
#ifndef CONFIG_RWSEM_SPIN_ON_OWNER
|
|
||||||
kthread_t *rw_owner;
|
kthread_t *rw_owner;
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_LOCKDEP
|
#ifdef CONFIG_LOCKDEP
|
||||||
krw_type_t rw_type;
|
krw_type_t rw_type;
|
||||||
#endif /* CONFIG_LOCKDEP */
|
#endif /* CONFIG_LOCKDEP */
|
||||||
@@ -97,31 +54,19 @@ typedef struct {
|
|||||||
static inline void
|
static inline void
|
||||||
spl_rw_set_owner(krwlock_t *rwp)
|
spl_rw_set_owner(krwlock_t *rwp)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* If CONFIG_RWSEM_SPIN_ON_OWNER is defined, down_write, up_write,
|
|
||||||
* downgrade_write and __init_rwsem will set/clear owner for us.
|
|
||||||
*/
|
|
||||||
#ifndef CONFIG_RWSEM_SPIN_ON_OWNER
|
|
||||||
rwp->rw_owner = current;
|
rwp->rw_owner = current;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
spl_rw_clear_owner(krwlock_t *rwp)
|
spl_rw_clear_owner(krwlock_t *rwp)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_RWSEM_SPIN_ON_OWNER
|
|
||||||
rwp->rw_owner = NULL;
|
rwp->rw_owner = NULL;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline kthread_t *
|
static inline kthread_t *
|
||||||
rw_owner(krwlock_t *rwp)
|
rw_owner(krwlock_t *rwp)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
|
|
||||||
return (SEM(rwp)->owner);
|
|
||||||
#else
|
|
||||||
return (rwp->rw_owner);
|
return (rwp->rw_owner);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_LOCKDEP
|
#ifdef CONFIG_LOCKDEP
|
||||||
@@ -148,6 +93,11 @@ spl_rw_lockdep_on_maybe(krwlock_t *rwp) \
|
|||||||
#define spl_rw_lockdep_on_maybe(rwp)
|
#define spl_rw_lockdep_on_maybe(rwp)
|
||||||
#endif /* CONFIG_LOCKDEP */
|
#endif /* CONFIG_LOCKDEP */
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
RW_LOCK_HELD(krwlock_t *rwp)
|
||||||
|
{
|
||||||
|
return (rwsem_is_locked(SEM(rwp)));
|
||||||
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
RW_WRITE_HELD(krwlock_t *rwp)
|
RW_WRITE_HELD(krwlock_t *rwp)
|
||||||
@@ -155,55 +105,10 @@ RW_WRITE_HELD(krwlock_t *rwp)
|
|||||||
return (rw_owner(rwp) == current);
|
return (rw_owner(rwp) == current);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
|
||||||
RW_LOCK_HELD(krwlock_t *rwp)
|
|
||||||
{
|
|
||||||
return (spl_rwsem_is_locked(SEM(rwp)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
RW_READ_HELD(krwlock_t *rwp)
|
RW_READ_HELD(krwlock_t *rwp)
|
||||||
{
|
{
|
||||||
if (!RW_LOCK_HELD(rwp))
|
return (RW_LOCK_HELD(rwp) && rw_owner(rwp) == NULL);
|
||||||
return (0);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rw_semaphore cheat sheet:
|
|
||||||
*
|
|
||||||
* < 3.16:
|
|
||||||
* There's no rw_semaphore.owner, so use rwp.owner instead.
|
|
||||||
* If rwp.owner == NULL then it's a reader
|
|
||||||
*
|
|
||||||
* 3.16 - 4.7:
|
|
||||||
* rw_semaphore.owner added (https://lwn.net/Articles/596656/)
|
|
||||||
* and CONFIG_RWSEM_SPIN_ON_OWNER introduced.
|
|
||||||
* If rw_semaphore.owner == NULL then it's a reader
|
|
||||||
*
|
|
||||||
* 4.8 - 4.16.16:
|
|
||||||
* RWSEM_READER_OWNED added as an internal #define.
|
|
||||||
* (https://lore.kernel.org/patchwork/patch/678590/)
|
|
||||||
* If rw_semaphore.owner == 1 then it's a reader
|
|
||||||
*
|
|
||||||
* 4.16.17 - 4.19:
|
|
||||||
* RWSEM_OWNER_UNKNOWN introduced as ((struct task_struct *)-1L)
|
|
||||||
* (https://do-db2.lkml.org/lkml/2018/5/15/985)
|
|
||||||
* If rw_semaphore.owner == 1 then it's a reader.
|
|
||||||
*
|
|
||||||
* 4.20+:
|
|
||||||
* RWSEM_OWNER_UNKNOWN changed to ((struct task_struct *)-2L)
|
|
||||||
* (https://lkml.org/lkml/2018/9/6/986)
|
|
||||||
* If rw_semaphore.owner & 1 then it's a reader, and also the reader's
|
|
||||||
* task_struct may be embedded in rw_semaphore->owner.
|
|
||||||
*/
|
|
||||||
#if defined(CONFIG_RWSEM_SPIN_ON_OWNER) && defined(RWSEM_OWNER_UNKNOWN)
|
|
||||||
if (RWSEM_OWNER_UNKNOWN == (struct task_struct *)-2L) {
|
|
||||||
/* 4.20+ kernels with CONFIG_RWSEM_SPIN_ON_OWNER */
|
|
||||||
return ((unsigned long) SEM(rwp)->owner & 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* < 4.20 kernel or !CONFIG_RWSEM_SPIN_ON_OWNER */
|
|
||||||
return (rw_owner(rwp) == NULL || (unsigned long) rw_owner(rwp) == 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -228,6 +133,12 @@ RW_READ_HELD(krwlock_t *rwp)
|
|||||||
*/
|
*/
|
||||||
#define rw_destroy(rwp) ((void) 0)
|
#define rw_destroy(rwp) ((void) 0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Upgrading a rwsem from a reader to a writer is not supported by the
|
||||||
|
* Linux kernel. The lock must be dropped and reacquired as a writer.
|
||||||
|
*/
|
||||||
|
#define rw_tryupgrade(rwp) RW_WRITE_HELD(rwp)
|
||||||
|
|
||||||
#define rw_tryenter(rwp, rw) \
|
#define rw_tryenter(rwp, rw) \
|
||||||
({ \
|
({ \
|
||||||
int _rc_ = 0; \
|
int _rc_ = 0; \
|
||||||
@@ -285,25 +196,6 @@ RW_READ_HELD(krwlock_t *rwp)
|
|||||||
downgrade_write(SEM(rwp)); \
|
downgrade_write(SEM(rwp)); \
|
||||||
spl_rw_lockdep_on_maybe(rwp); \
|
spl_rw_lockdep_on_maybe(rwp); \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define rw_tryupgrade(rwp) \
|
|
||||||
({ \
|
|
||||||
int _rc_ = 0; \
|
|
||||||
\
|
|
||||||
if (RW_WRITE_HELD(rwp)) { \
|
|
||||||
_rc_ = 1; \
|
|
||||||
} else { \
|
|
||||||
spl_rw_lockdep_off_maybe(rwp); \
|
|
||||||
if ((_rc_ = rwsem_tryupgrade(SEM(rwp)))) \
|
|
||||||
spl_rw_set_owner(rwp); \
|
|
||||||
spl_rw_lockdep_on_maybe(rwp); \
|
|
||||||
} \
|
|
||||||
_rc_; \
|
|
||||||
})
|
|
||||||
/* END CSTYLED */
|
/* END CSTYLED */
|
||||||
|
|
||||||
int spl_rw_init(void);
|
|
||||||
void spl_rw_fini(void);
|
|
||||||
int rwsem_tryupgrade(struct rw_semaphore *rwsem);
|
|
||||||
|
|
||||||
#endif /* _SPL_RWLOCK_H */
|
#endif /* _SPL_RWLOCK_H */
|
||||||
|
|||||||
@@ -28,4 +28,8 @@
|
|||||||
#define bcopy(src, dest, size) memmove(dest, src, size)
|
#define bcopy(src, dest, size) memmove(dest, src, size)
|
||||||
#define bcmp(src, dest, size) memcmp((src), (dest), (size_t)(size))
|
#define bcmp(src, dest, size) memcmp((src), (dest), (size_t)(size))
|
||||||
|
|
||||||
|
#ifndef HAVE_KSTRTOUL
|
||||||
|
#define kstrtoul strict_strtoul
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _SPL_SYS_STRINGS_H */
|
#endif /* _SPL_SYS_STRINGS_H */
|
||||||
|
|||||||
@@ -72,4 +72,29 @@ usleep_range(unsigned long min, unsigned long max)
|
|||||||
#define USEC_TO_TICK(us) usecs_to_jiffies(us)
|
#define USEC_TO_TICK(us) usecs_to_jiffies(us)
|
||||||
#define NSEC_TO_TICK(ns) usecs_to_jiffies(ns / NSEC_PER_USEC)
|
#define NSEC_TO_TICK(ns) usecs_to_jiffies(ns / NSEC_PER_USEC)
|
||||||
|
|
||||||
|
#ifndef from_timer
|
||||||
|
#define from_timer(var, timer, timer_field) \
|
||||||
|
container_of(timer, typeof(*var), timer_field)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_KERNEL_TIMER_FUNCTION_TIMER_LIST
|
||||||
|
typedef struct timer_list *spl_timer_list_t;
|
||||||
|
#else
|
||||||
|
typedef unsigned long spl_timer_list_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_KERNEL_TIMER_SETUP
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
timer_setup(struct timer_list *timer, void (*func)(spl_timer_list_t), u32 fl)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_KERNEL_TIMER_LIST_FLAGS
|
||||||
|
(timer)->flags = fl;
|
||||||
|
#endif
|
||||||
|
init_timer(timer);
|
||||||
|
setup_timer(timer, func, (spl_timer_list_t)(timer));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_KERNEL_TIMER_SETUP */
|
||||||
|
|
||||||
#endif /* _SPL_TIMER_H */
|
#endif /* _SPL_TIMER_H */
|
||||||
|
|||||||
@@ -182,7 +182,6 @@ extern int vn_space(vnode_t *vp, int cmd, struct flock *bfp, int flag,
|
|||||||
extern file_t *vn_getf(int fd);
|
extern file_t *vn_getf(int fd);
|
||||||
extern void vn_releasef(int fd);
|
extern void vn_releasef(int fd);
|
||||||
extern void vn_areleasef(int fd, uf_info_t *fip);
|
extern void vn_areleasef(int fd, uf_info_t *fip);
|
||||||
extern int vn_set_pwd(const char *filename);
|
|
||||||
|
|
||||||
int spl_vn_init(void);
|
int spl_vn_init(void);
|
||||||
void spl_vn_fini(void);
|
void spl_vn_fini(void);
|
||||||
|
|||||||
+2
-5
@@ -46,6 +46,7 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
#define DNODE_MUST_BE_ALLOCATED 1
|
#define DNODE_MUST_BE_ALLOCATED 1
|
||||||
#define DNODE_MUST_BE_FREE 2
|
#define DNODE_MUST_BE_FREE 2
|
||||||
|
#define DNODE_DRY_RUN 4
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dnode_next_offset() flags.
|
* dnode_next_offset() flags.
|
||||||
@@ -415,6 +416,7 @@ int dnode_hold_impl(struct objset *dd, uint64_t object, int flag, int dn_slots,
|
|||||||
boolean_t dnode_add_ref(dnode_t *dn, void *ref);
|
boolean_t dnode_add_ref(dnode_t *dn, void *ref);
|
||||||
void dnode_rele(dnode_t *dn, void *ref);
|
void dnode_rele(dnode_t *dn, void *ref);
|
||||||
void dnode_rele_and_unlock(dnode_t *dn, void *tag, boolean_t evicting);
|
void dnode_rele_and_unlock(dnode_t *dn, void *tag, boolean_t evicting);
|
||||||
|
int dnode_try_claim(objset_t *os, uint64_t object, int slots);
|
||||||
void dnode_setdirty(dnode_t *dn, dmu_tx_t *tx);
|
void dnode_setdirty(dnode_t *dn, dmu_tx_t *tx);
|
||||||
void dnode_sync(dnode_t *dn, dmu_tx_t *tx);
|
void dnode_sync(dnode_t *dn, dmu_tx_t *tx);
|
||||||
void dnode_allocate(dnode_t *dn, dmu_object_type_t ot, int blocksize, int ibs,
|
void dnode_allocate(dnode_t *dn, dmu_object_type_t ot, int blocksize, int ibs,
|
||||||
@@ -532,11 +534,6 @@ typedef struct dnode_stats {
|
|||||||
* a range of dnode slots which would overflow the dnode_phys_t.
|
* a range of dnode slots which would overflow the dnode_phys_t.
|
||||||
*/
|
*/
|
||||||
kstat_named_t dnode_hold_free_overflow;
|
kstat_named_t dnode_hold_free_overflow;
|
||||||
/*
|
|
||||||
* Number of times a dnode_hold(...) was attempted on a dnode
|
|
||||||
* which had already been unlinked in an earlier txg.
|
|
||||||
*/
|
|
||||||
kstat_named_t dnode_hold_free_txg;
|
|
||||||
/*
|
/*
|
||||||
* Number of times dnode_free_interior_slots() needed to retry
|
* Number of times dnode_free_interior_slots() needed to retry
|
||||||
* acquiring a slot zrl lock due to contention.
|
* acquiring a slot zrl lock due to contention.
|
||||||
|
|||||||
@@ -37,9 +37,11 @@ typedef struct zfs_bookmark_phys {
|
|||||||
uint64_t zbm_creation_txg; /* birth transaction group */
|
uint64_t zbm_creation_txg; /* birth transaction group */
|
||||||
uint64_t zbm_creation_time; /* bookmark creation time */
|
uint64_t zbm_creation_time; /* bookmark creation time */
|
||||||
|
|
||||||
/* the following fields are reserved for redacted send / recv */
|
/* fields used for redacted send / recv */
|
||||||
uint64_t zbm_redaction_obj; /* redaction list object */
|
uint64_t zbm_redaction_obj; /* redaction list object */
|
||||||
uint64_t zbm_flags; /* ZBM_FLAG_* */
|
uint64_t zbm_flags; /* ZBM_FLAG_* */
|
||||||
|
|
||||||
|
/* fields used for bookmark written size */
|
||||||
uint64_t zbm_referenced_bytes_refd;
|
uint64_t zbm_referenced_bytes_refd;
|
||||||
uint64_t zbm_compressed_bytes_refd;
|
uint64_t zbm_compressed_bytes_refd;
|
||||||
uint64_t zbm_uncompressed_bytes_refd;
|
uint64_t zbm_uncompressed_bytes_refd;
|
||||||
|
|||||||
@@ -209,7 +209,6 @@ void dsl_dataset_create_crypt_sync(uint64_t dsobj, dsl_dir_t *dd,
|
|||||||
struct dsl_dataset *origin, dsl_crypto_params_t *dcp, dmu_tx_t *tx);
|
struct dsl_dataset *origin, dsl_crypto_params_t *dcp, dmu_tx_t *tx);
|
||||||
uint64_t dsl_crypto_key_create_sync(uint64_t crypt, dsl_wrapping_key_t *wkey,
|
uint64_t dsl_crypto_key_create_sync(uint64_t crypt, dsl_wrapping_key_t *wkey,
|
||||||
dmu_tx_t *tx);
|
dmu_tx_t *tx);
|
||||||
int dmu_objset_clone_crypt_check(dsl_dir_t *parentdd, dsl_dir_t *origindd);
|
|
||||||
uint64_t dsl_crypto_key_clone_sync(dsl_dir_t *origindd, dmu_tx_t *tx);
|
uint64_t dsl_crypto_key_clone_sync(dsl_dir_t *origindd, dmu_tx_t *tx);
|
||||||
void dsl_crypto_key_destroy_sync(uint64_t dckobj, dmu_tx_t *tx);
|
void dsl_crypto_key_destroy_sync(uint64_t dckobj, dmu_tx_t *tx);
|
||||||
|
|
||||||
|
|||||||
@@ -1318,6 +1318,7 @@ typedef enum {
|
|||||||
ZFS_ERR_FROM_IVSET_GUID_MISSING,
|
ZFS_ERR_FROM_IVSET_GUID_MISSING,
|
||||||
ZFS_ERR_FROM_IVSET_GUID_MISMATCH,
|
ZFS_ERR_FROM_IVSET_GUID_MISMATCH,
|
||||||
ZFS_ERR_SPILL_BLOCK_FLAG_MISSING,
|
ZFS_ERR_SPILL_BLOCK_FLAG_MISSING,
|
||||||
|
ZFS_ERR_EXPORT_IN_PROGRESS,
|
||||||
} zfs_errno_t;
|
} zfs_errno_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ int metaslab_init(metaslab_group_t *, uint64_t, uint64_t, uint64_t,
|
|||||||
void metaslab_fini(metaslab_t *);
|
void metaslab_fini(metaslab_t *);
|
||||||
|
|
||||||
int metaslab_load(metaslab_t *);
|
int metaslab_load(metaslab_t *);
|
||||||
|
void metaslab_potentially_unload(metaslab_t *, uint64_t);
|
||||||
void metaslab_unload(metaslab_t *);
|
void metaslab_unload(metaslab_t *);
|
||||||
|
|
||||||
uint64_t metaslab_allocated_space(metaslab_t *);
|
uint64_t metaslab_allocated_space(metaslab_t *);
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ void multilist_sublist_insert_head(multilist_sublist_t *, void *);
|
|||||||
void multilist_sublist_insert_tail(multilist_sublist_t *, void *);
|
void multilist_sublist_insert_tail(multilist_sublist_t *, void *);
|
||||||
void multilist_sublist_move_forward(multilist_sublist_t *mls, void *obj);
|
void multilist_sublist_move_forward(multilist_sublist_t *mls, void *obj);
|
||||||
void multilist_sublist_remove(multilist_sublist_t *, void *);
|
void multilist_sublist_remove(multilist_sublist_t *, void *);
|
||||||
|
int multilist_sublist_is_empty(multilist_sublist_t *);
|
||||||
|
int multilist_sublist_is_empty_idx(multilist_t *, unsigned int);
|
||||||
|
|
||||||
void *multilist_sublist_head(multilist_sublist_t *);
|
void *multilist_sublist_head(multilist_sublist_t *);
|
||||||
void *multilist_sublist_tail(multilist_sublist_t *);
|
void *multilist_sublist_tail(multilist_sublist_t *);
|
||||||
|
|||||||
@@ -54,8 +54,10 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
typedef struct pathname {
|
typedef struct pathname {
|
||||||
char *pn_buf; /* underlying storage */
|
char *pn_buf; /* underlying storage */
|
||||||
|
#if 0 /* unused in ZoL */
|
||||||
char *pn_path; /* remaining pathname */
|
char *pn_path; /* remaining pathname */
|
||||||
size_t pn_pathlen; /* remaining length */
|
size_t pn_pathlen; /* remaining length */
|
||||||
|
#endif
|
||||||
size_t pn_bufsize; /* total size of pn_buf */
|
size_t pn_bufsize; /* total size of pn_buf */
|
||||||
} pathname_t;
|
} pathname_t;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1104,7 +1104,7 @@ extern uint64_t spa_missing_tvds_allowed(spa_t *spa);
|
|||||||
extern void spa_set_missing_tvds(spa_t *spa, uint64_t missing);
|
extern void spa_set_missing_tvds(spa_t *spa, uint64_t missing);
|
||||||
extern boolean_t spa_top_vdevs_spacemap_addressable(spa_t *spa);
|
extern boolean_t spa_top_vdevs_spacemap_addressable(spa_t *spa);
|
||||||
extern boolean_t spa_multihost(spa_t *spa);
|
extern boolean_t spa_multihost(spa_t *spa);
|
||||||
extern unsigned long spa_get_hostid(void);
|
extern uint32_t spa_get_hostid(spa_t *spa);
|
||||||
extern void spa_activate_allocation_classes(spa_t *, dmu_tx_t *);
|
extern void spa_activate_allocation_classes(spa_t *, dmu_tx_t *);
|
||||||
|
|
||||||
extern int spa_mode(spa_t *spa);
|
extern int spa_mode(spa_t *spa);
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ struct spa {
|
|||||||
spa_taskqs_t spa_zio_taskq[ZIO_TYPES][ZIO_TASKQ_TYPES];
|
spa_taskqs_t spa_zio_taskq[ZIO_TYPES][ZIO_TASKQ_TYPES];
|
||||||
dsl_pool_t *spa_dsl_pool;
|
dsl_pool_t *spa_dsl_pool;
|
||||||
boolean_t spa_is_initializing; /* true while opening pool */
|
boolean_t spa_is_initializing; /* true while opening pool */
|
||||||
|
boolean_t spa_is_exporting; /* true while exporting pool */
|
||||||
metaslab_class_t *spa_normal_class; /* normal data class */
|
metaslab_class_t *spa_normal_class; /* normal data class */
|
||||||
metaslab_class_t *spa_log_class; /* intent log data class */
|
metaslab_class_t *spa_log_class; /* intent log data class */
|
||||||
metaslab_class_t *spa_special_class; /* special allocation class */
|
metaslab_class_t *spa_special_class; /* special allocation class */
|
||||||
@@ -394,6 +395,7 @@ struct spa {
|
|||||||
mmp_thread_t spa_mmp; /* multihost mmp thread */
|
mmp_thread_t spa_mmp; /* multihost mmp thread */
|
||||||
list_t spa_leaf_list; /* list of leaf vdevs */
|
list_t spa_leaf_list; /* list of leaf vdevs */
|
||||||
uint64_t spa_leaf_list_gen; /* track leaf_list changes */
|
uint64_t spa_leaf_list_gen; /* track leaf_list changes */
|
||||||
|
uint32_t spa_hostid; /* cached system hostid */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* spa_refcount & spa_config_lock must be the last elements
|
* spa_refcount & spa_config_lock must be the last elements
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2017 by Delphix. All rights reserved.
|
* Copyright (c) 2014, 2019 by Delphix. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SYS_VDEV_REMOVAL_H
|
#ifndef _SYS_VDEV_REMOVAL_H
|
||||||
@@ -81,13 +81,13 @@ extern void spa_vdev_condense_suspend(spa_t *);
|
|||||||
extern int spa_vdev_remove(spa_t *, uint64_t, boolean_t);
|
extern int spa_vdev_remove(spa_t *, uint64_t, boolean_t);
|
||||||
extern void free_from_removing_vdev(vdev_t *, uint64_t, uint64_t);
|
extern void free_from_removing_vdev(vdev_t *, uint64_t, uint64_t);
|
||||||
extern int spa_removal_get_stats(spa_t *, pool_removal_stat_t *);
|
extern int spa_removal_get_stats(spa_t *, pool_removal_stat_t *);
|
||||||
extern void svr_sync(spa_t *spa, dmu_tx_t *tx);
|
extern void svr_sync(spa_t *, dmu_tx_t *);
|
||||||
extern void spa_vdev_remove_suspend(spa_t *);
|
extern void spa_vdev_remove_suspend(spa_t *);
|
||||||
extern int spa_vdev_remove_cancel(spa_t *);
|
extern int spa_vdev_remove_cancel(spa_t *);
|
||||||
extern void spa_vdev_removal_destroy(spa_vdev_removal_t *svr);
|
extern void spa_vdev_removal_destroy(spa_vdev_removal_t *);
|
||||||
|
extern uint64_t spa_remove_max_segment(spa_t *);
|
||||||
|
|
||||||
extern int vdev_removal_max_span;
|
extern int vdev_removal_max_span;
|
||||||
extern int zfs_remove_max_segment;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2013 by Delphix. All rights reserved.
|
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||||
* Copyright 2017 Nexenta Systems, Inc.
|
* Copyright 2017 Nexenta Systems, Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -350,6 +350,7 @@ typedef struct zap_cursor {
|
|||||||
uint64_t zc_serialized;
|
uint64_t zc_serialized;
|
||||||
uint64_t zc_hash;
|
uint64_t zc_hash;
|
||||||
uint32_t zc_cd;
|
uint32_t zc_cd;
|
||||||
|
boolean_t zc_prefetch;
|
||||||
} zap_cursor_t;
|
} zap_cursor_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -375,7 +376,9 @@ typedef struct {
|
|||||||
* Initialize a zap cursor, pointing to the "first" attribute of the
|
* Initialize a zap cursor, pointing to the "first" attribute of the
|
||||||
* zapobj. You must _fini the cursor when you are done with it.
|
* zapobj. You must _fini the cursor when you are done with it.
|
||||||
*/
|
*/
|
||||||
void zap_cursor_init(zap_cursor_t *zc, objset_t *ds, uint64_t zapobj);
|
void zap_cursor_init(zap_cursor_t *zc, objset_t *os, uint64_t zapobj);
|
||||||
|
void zap_cursor_init_noprefetch(zap_cursor_t *zc, objset_t *os,
|
||||||
|
uint64_t zapobj);
|
||||||
void zap_cursor_fini(zap_cursor_t *zc);
|
void zap_cursor_fini(zap_cursor_t *zc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -257,6 +257,8 @@ extern void mutex_enter(kmutex_t *mp);
|
|||||||
extern void mutex_exit(kmutex_t *mp);
|
extern void mutex_exit(kmutex_t *mp);
|
||||||
extern int mutex_tryenter(kmutex_t *mp);
|
extern int mutex_tryenter(kmutex_t *mp);
|
||||||
|
|
||||||
|
#define NESTED_SINGLE 1
|
||||||
|
#define mutex_enter_nested(mp, class) mutex_enter(mp)
|
||||||
/*
|
/*
|
||||||
* RW locks
|
* RW locks
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -196,6 +196,7 @@ typedef struct znode {
|
|||||||
uint8_t z_atime_dirty; /* atime needs to be synced */
|
uint8_t z_atime_dirty; /* atime needs to be synced */
|
||||||
uint8_t z_zn_prefetch; /* Prefetch znodes? */
|
uint8_t z_zn_prefetch; /* Prefetch znodes? */
|
||||||
uint8_t z_moved; /* Has this znode been moved? */
|
uint8_t z_moved; /* Has this znode been moved? */
|
||||||
|
boolean_t z_suspended; /* extra ref from a suspend? */
|
||||||
uint_t z_blksz; /* block size in bytes */
|
uint_t z_blksz; /* block size in bytes */
|
||||||
uint_t z_seq; /* modification sequence number */
|
uint_t z_seq; /* modification sequence number */
|
||||||
uint64_t z_mapcnt; /* number of pages mapped to file */
|
uint64_t z_mapcnt; /* number of pages mapped to file */
|
||||||
@@ -371,7 +372,7 @@ extern void zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
|
|||||||
extern int zfs_log_create_txtype(zil_create_t, vsecattr_t *vsecp,
|
extern int zfs_log_create_txtype(zil_create_t, vsecattr_t *vsecp,
|
||||||
vattr_t *vap);
|
vattr_t *vap);
|
||||||
extern void zfs_log_remove(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
|
extern void zfs_log_remove(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
|
||||||
znode_t *dzp, char *name, uint64_t foid);
|
znode_t *dzp, char *name, uint64_t foid, boolean_t unlinked);
|
||||||
#define ZFS_NO_OBJECT 0 /* no object id */
|
#define ZFS_NO_OBJECT 0 /* no object id */
|
||||||
extern void zfs_log_link(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
|
extern void zfs_log_link(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
|
||||||
znode_t *dzp, znode_t *zp, char *name);
|
znode_t *dzp, znode_t *zp, char *name);
|
||||||
|
|||||||
@@ -105,8 +105,7 @@ extern size_t lz4_compress_zfs(void *src, void *dst, size_t s_len, size_t d_len,
|
|||||||
int level);
|
int level);
|
||||||
extern int lz4_decompress_zfs(void *src, void *dst, size_t s_len, size_t d_len,
|
extern int lz4_decompress_zfs(void *src, void *dst, size_t s_len, size_t d_len,
|
||||||
int level);
|
int level);
|
||||||
extern int lz4_decompress_abd(abd_t *src, void *dst, size_t s_len, size_t d_len,
|
|
||||||
int level);
|
|
||||||
/*
|
/*
|
||||||
* Compress and decompress data if necessary.
|
* Compress and decompress data if necessary.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ typedef enum {
|
|||||||
NAME_ERR_RESERVED, /* entire name is reserved */
|
NAME_ERR_RESERVED, /* entire name is reserved */
|
||||||
NAME_ERR_DISKLIKE, /* reserved disk name (c[0-9].*) */
|
NAME_ERR_DISKLIKE, /* reserved disk name (c[0-9].*) */
|
||||||
NAME_ERR_TOOLONG, /* name is too long */
|
NAME_ERR_TOOLONG, /* name is too long */
|
||||||
|
NAME_ERR_SELF_REF, /* reserved self path name ('.') */
|
||||||
|
NAME_ERR_PARENT_REF, /* reserved parent path name ('..') */
|
||||||
NAME_ERR_NO_AT, /* permission set is missing '@' */
|
NAME_ERR_NO_AT, /* permission set is missing '@' */
|
||||||
} namecheck_err_t;
|
} namecheck_err_t;
|
||||||
|
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ Version: @VERSION@
|
|||||||
URL: http://zfsonlinux.org
|
URL: http://zfsonlinux.org
|
||||||
Requires: libzfs_core
|
Requires: libzfs_core
|
||||||
Cflags: -I${includedir}/libzfs -I${includedir}/libspl
|
Cflags: -I${includedir}/libzfs -I${includedir}/libspl
|
||||||
Libs: -L${libdir} -lzfs
|
Libs: -L${libdir} -lzfs -lnvpair
|
||||||
|
|||||||
@@ -475,9 +475,10 @@ change_one(zfs_handle_t *zhp, void *data)
|
|||||||
prop_changelist_t *clp = data;
|
prop_changelist_t *clp = data;
|
||||||
char property[ZFS_MAXPROPLEN];
|
char property[ZFS_MAXPROPLEN];
|
||||||
char where[64];
|
char where[64];
|
||||||
prop_changenode_t *cn;
|
prop_changenode_t *cn = NULL;
|
||||||
zprop_source_t sourcetype = ZPROP_SRC_NONE;
|
zprop_source_t sourcetype = ZPROP_SRC_NONE;
|
||||||
zprop_source_t share_sourcetype = ZPROP_SRC_NONE;
|
zprop_source_t share_sourcetype = ZPROP_SRC_NONE;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We only want to unmount/unshare those filesystems that may inherit
|
* We only want to unmount/unshare those filesystems that may inherit
|
||||||
@@ -493,8 +494,7 @@ change_one(zfs_handle_t *zhp, void *data)
|
|||||||
zfs_prop_get(zhp, clp->cl_prop, property,
|
zfs_prop_get(zhp, clp->cl_prop, property,
|
||||||
sizeof (property), &sourcetype, where, sizeof (where),
|
sizeof (property), &sourcetype, where, sizeof (where),
|
||||||
B_FALSE) != 0) {
|
B_FALSE) != 0) {
|
||||||
zfs_close(zhp);
|
goto out;
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -506,8 +506,7 @@ change_one(zfs_handle_t *zhp, void *data)
|
|||||||
zfs_prop_get(zhp, clp->cl_shareprop, property,
|
zfs_prop_get(zhp, clp->cl_shareprop, property,
|
||||||
sizeof (property), &share_sourcetype, where, sizeof (where),
|
sizeof (property), &share_sourcetype, where, sizeof (where),
|
||||||
B_FALSE) != 0) {
|
B_FALSE) != 0) {
|
||||||
zfs_close(zhp);
|
goto out;
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clp->cl_alldependents || clp->cl_allchildren ||
|
if (clp->cl_alldependents || clp->cl_allchildren ||
|
||||||
@@ -518,8 +517,8 @@ change_one(zfs_handle_t *zhp, void *data)
|
|||||||
share_sourcetype == ZPROP_SRC_INHERITED))) {
|
share_sourcetype == ZPROP_SRC_INHERITED))) {
|
||||||
if ((cn = zfs_alloc(zfs_get_handle(zhp),
|
if ((cn = zfs_alloc(zfs_get_handle(zhp),
|
||||||
sizeof (prop_changenode_t))) == NULL) {
|
sizeof (prop_changenode_t))) == NULL) {
|
||||||
zfs_close(zhp);
|
ret = -1;
|
||||||
return (-1);
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
cn->cn_handle = zhp;
|
cn->cn_handle = zhp;
|
||||||
@@ -541,16 +540,23 @@ change_one(zfs_handle_t *zhp, void *data)
|
|||||||
uu_avl_insert(clp->cl_tree, cn, idx);
|
uu_avl_insert(clp->cl_tree, cn, idx);
|
||||||
} else {
|
} else {
|
||||||
free(cn);
|
free(cn);
|
||||||
zfs_close(zhp);
|
cn = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!clp->cl_alldependents)
|
if (!clp->cl_alldependents)
|
||||||
return (zfs_iter_children(zhp, change_one, data));
|
ret = zfs_iter_children(zhp, change_one, data);
|
||||||
} else {
|
|
||||||
zfs_close(zhp);
|
/*
|
||||||
|
* If we added the handle to the changelist, we will re-use it
|
||||||
|
* later so return without closing it.
|
||||||
|
*/
|
||||||
|
if (cn != NULL)
|
||||||
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
out:
|
||||||
|
zfs_close(zhp);
|
||||||
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|||||||
@@ -740,14 +740,6 @@ zfs_crypto_create(libzfs_handle_t *hdl, char *parent_name, nvlist_t *props,
|
|||||||
pcrypt = ZIO_CRYPT_OFF;
|
pcrypt = ZIO_CRYPT_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for encryption being explicitly truned off */
|
|
||||||
if (crypt == ZIO_CRYPT_OFF && pcrypt != ZIO_CRYPT_OFF) {
|
|
||||||
ret = EINVAL;
|
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
|
||||||
"Invalid encryption value. Dataset must be encrypted."));
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the inherited encryption property if we don't have it locally */
|
/* Get the inherited encryption property if we don't have it locally */
|
||||||
if (!local_crypt)
|
if (!local_crypt)
|
||||||
crypt = pcrypt;
|
crypt = pcrypt;
|
||||||
@@ -849,10 +841,7 @@ int
|
|||||||
zfs_crypto_clone_check(libzfs_handle_t *hdl, zfs_handle_t *origin_zhp,
|
zfs_crypto_clone_check(libzfs_handle_t *hdl, zfs_handle_t *origin_zhp,
|
||||||
char *parent_name, nvlist_t *props)
|
char *parent_name, nvlist_t *props)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
char errbuf[1024];
|
char errbuf[1024];
|
||||||
zfs_handle_t *pzhp = NULL;
|
|
||||||
uint64_t pcrypt, ocrypt;
|
|
||||||
|
|
||||||
(void) snprintf(errbuf, sizeof (errbuf),
|
(void) snprintf(errbuf, sizeof (errbuf),
|
||||||
dgettext(TEXT_DOMAIN, "Encryption clone error"));
|
dgettext(TEXT_DOMAIN, "Encryption clone error"));
|
||||||
@@ -865,40 +854,12 @@ zfs_crypto_clone_check(libzfs_handle_t *hdl, zfs_handle_t *origin_zhp,
|
|||||||
nvlist_exists(props, zfs_prop_to_name(ZFS_PROP_KEYLOCATION)) ||
|
nvlist_exists(props, zfs_prop_to_name(ZFS_PROP_KEYLOCATION)) ||
|
||||||
nvlist_exists(props, zfs_prop_to_name(ZFS_PROP_ENCRYPTION)) ||
|
nvlist_exists(props, zfs_prop_to_name(ZFS_PROP_ENCRYPTION)) ||
|
||||||
nvlist_exists(props, zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS))) {
|
nvlist_exists(props, zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS))) {
|
||||||
ret = EINVAL;
|
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
"Encryption properties must inherit from origin dataset."));
|
"Encryption properties must inherit from origin dataset."));
|
||||||
goto out;
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get a reference to parent dataset, should never be NULL */
|
|
||||||
pzhp = make_dataset_handle(hdl, parent_name);
|
|
||||||
if (pzhp == NULL) {
|
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
|
||||||
"Failed to lookup parent."));
|
|
||||||
return (ENOENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lookup parent's crypt */
|
|
||||||
pcrypt = zfs_prop_get_int(pzhp, ZFS_PROP_ENCRYPTION);
|
|
||||||
ocrypt = zfs_prop_get_int(origin_zhp, ZFS_PROP_ENCRYPTION);
|
|
||||||
|
|
||||||
/* all children of encrypted parents must be encrypted */
|
|
||||||
if (pcrypt != ZIO_CRYPT_OFF && ocrypt == ZIO_CRYPT_OFF) {
|
|
||||||
ret = EINVAL;
|
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
|
||||||
"Cannot create unencrypted clone as a child "
|
|
||||||
"of encrypted parent."));
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
zfs_close(pzhp);
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
out:
|
|
||||||
if (pzhp != NULL)
|
|
||||||
zfs_close(pzhp);
|
|
||||||
return (ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct loadkeys_cbdata {
|
typedef struct loadkeys_cbdata {
|
||||||
|
|||||||
+31
-20
@@ -31,6 +31,7 @@
|
|||||||
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
|
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
|
||||||
* Copyright 2017-2018 RackTop Systems.
|
* Copyright 2017-2018 RackTop Systems.
|
||||||
* Copyright (c) 2019 Datto Inc.
|
* Copyright (c) 2019 Datto Inc.
|
||||||
|
* Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -196,6 +197,16 @@ zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
|
|||||||
"reserved disk name"));
|
"reserved disk name"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case NAME_ERR_SELF_REF:
|
||||||
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
|
"self reference, '.' is found in name"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_ERR_PARENT_REF:
|
||||||
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
|
"parent reference, '..' is found in name"));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
"(%d) not defined"), why);
|
"(%d) not defined"), why);
|
||||||
@@ -2969,8 +2980,10 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
|||||||
|
|
||||||
case ZFS_PROP_GUID:
|
case ZFS_PROP_GUID:
|
||||||
case ZFS_PROP_CREATETXG:
|
case ZFS_PROP_CREATETXG:
|
||||||
|
case ZFS_PROP_OBJSETID:
|
||||||
/*
|
/*
|
||||||
* GUIDs are stored as numbers, but they are identifiers.
|
* These properties are stored as numbers, but they are
|
||||||
|
* identifiers.
|
||||||
* We don't want them to be pretty printed, because pretty
|
* We don't want them to be pretty printed, because pretty
|
||||||
* printing mangles the ID into a truncated and useless value.
|
* printing mangles the ID into a truncated and useless value.
|
||||||
*/
|
*/
|
||||||
@@ -4104,6 +4117,16 @@ zfs_promote(zfs_handle_t *zhp)
|
|||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
|
case EACCES:
|
||||||
|
/*
|
||||||
|
* Promoting encrypted dataset outside its
|
||||||
|
* encryption root.
|
||||||
|
*/
|
||||||
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
|
"cannot promote dataset outside its "
|
||||||
|
"encryption root"));
|
||||||
|
return (zfs_error(hdl, EZFS_EXISTS, errbuf));
|
||||||
|
|
||||||
case EEXIST:
|
case EEXIST:
|
||||||
/* There is a conflicting snapshot name. */
|
/* There is a conflicting snapshot name. */
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
@@ -4467,8 +4490,6 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
|||||||
zfs_cmd_t zc = {"\0"};
|
zfs_cmd_t zc = {"\0"};
|
||||||
char *delim;
|
char *delim;
|
||||||
prop_changelist_t *cl = NULL;
|
prop_changelist_t *cl = NULL;
|
||||||
zfs_handle_t *zhrp = NULL;
|
|
||||||
char *parentname = NULL;
|
|
||||||
char parent[ZFS_MAX_DATASET_NAME_LEN];
|
char parent[ZFS_MAX_DATASET_NAME_LEN];
|
||||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||||
char errbuf[1024];
|
char errbuf[1024];
|
||||||
@@ -4563,7 +4584,8 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
|
zfs_handle_t *zhrp;
|
||||||
|
char *parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
|
||||||
if (parentname == NULL) {
|
if (parentname == NULL) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto error;
|
goto error;
|
||||||
@@ -4571,10 +4593,12 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
|||||||
delim = strchr(parentname, '@');
|
delim = strchr(parentname, '@');
|
||||||
*delim = '\0';
|
*delim = '\0';
|
||||||
zhrp = zfs_open(zhp->zfs_hdl, parentname, ZFS_TYPE_DATASET);
|
zhrp = zfs_open(zhp->zfs_hdl, parentname, ZFS_TYPE_DATASET);
|
||||||
|
free(parentname);
|
||||||
if (zhrp == NULL) {
|
if (zhrp == NULL) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
zfs_close(zhrp);
|
||||||
} else if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT) {
|
} else if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT) {
|
||||||
if ((cl = changelist_gather(zhp, ZFS_PROP_NAME,
|
if ((cl = changelist_gather(zhp, ZFS_PROP_NAME,
|
||||||
CL_GATHER_ITER_MOUNTED,
|
CL_GATHER_ITER_MOUNTED,
|
||||||
@@ -4618,16 +4642,9 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
|||||||
"with the new name"));
|
"with the new name"));
|
||||||
(void) zfs_error(hdl, EZFS_EXISTS, errbuf);
|
(void) zfs_error(hdl, EZFS_EXISTS, errbuf);
|
||||||
} else if (errno == EACCES) {
|
} else if (errno == EACCES) {
|
||||||
if (zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) ==
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
ZIO_CRYPT_OFF) {
|
"cannot move encrypted child outside of "
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
"its encryption root"));
|
||||||
"cannot rename an unencrypted dataset to "
|
|
||||||
"be a decendent of an encrypted one"));
|
|
||||||
} else {
|
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
|
||||||
"cannot move encryption child outside of "
|
|
||||||
"its encryption root"));
|
|
||||||
}
|
|
||||||
(void) zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
|
(void) zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
|
||||||
} else {
|
} else {
|
||||||
(void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf);
|
(void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf);
|
||||||
@@ -4647,12 +4664,6 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
|||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (parentname != NULL) {
|
|
||||||
free(parentname);
|
|
||||||
}
|
|
||||||
if (zhrp != NULL) {
|
|
||||||
zfs_close(zhrp);
|
|
||||||
}
|
|
||||||
if (cl != NULL) {
|
if (cl != NULL) {
|
||||||
changelist_free(cl);
|
changelist_free(cl);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1302,12 +1302,14 @@ mountpoint_cmp(const void *arga, const void *argb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return true if path2 is a child of path1.
|
* Return true if path2 is a child of path1 or path2 equals path1 or
|
||||||
|
* path1 is "/" (path2 is always a child of "/").
|
||||||
*/
|
*/
|
||||||
static boolean_t
|
static boolean_t
|
||||||
libzfs_path_contains(const char *path1, const char *path2)
|
libzfs_path_contains(const char *path1, const char *path2)
|
||||||
{
|
{
|
||||||
return (strstr(path2, path1) == path2 && path2[strlen(path1)] == '/');
|
return (strcmp(path1, path2) == 0 || strcmp(path1, "/") == 0 ||
|
||||||
|
(strstr(path2, path1) == path2 && path2[strlen(path1)] == '/'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -2827,7 +2827,7 @@ recv_fix_encryption_hierarchy(libzfs_handle_t *hdl, const char *destname,
|
|||||||
is_clone = zhp->zfs_dmustats.dds_origin[0] != '\0';
|
is_clone = zhp->zfs_dmustats.dds_origin[0] != '\0';
|
||||||
(void) zfs_crypto_get_encryption_root(zhp, &is_encroot, NULL);
|
(void) zfs_crypto_get_encryption_root(zhp, &is_encroot, NULL);
|
||||||
|
|
||||||
/* we don't need to do anything for unencrypted filesystems */
|
/* we don't need to do anything for unencrypted datasets */
|
||||||
if (crypt == ZIO_CRYPT_OFF) {
|
if (crypt == ZIO_CRYPT_OFF) {
|
||||||
zfs_close(zhp);
|
zfs_close(zhp);
|
||||||
continue;
|
continue;
|
||||||
@@ -3992,11 +3992,18 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* if the fs does not exist, look for it based on the
|
* If the fs does not exist, look for it based on the
|
||||||
* fromsnap GUID
|
* fromsnap GUID.
|
||||||
*/
|
*/
|
||||||
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
|
if (resuming) {
|
||||||
"cannot receive incremental stream"));
|
(void) snprintf(errbuf, sizeof (errbuf),
|
||||||
|
dgettext(TEXT_DOMAIN,
|
||||||
|
"cannot receive resume stream"));
|
||||||
|
} else {
|
||||||
|
(void) snprintf(errbuf, sizeof (errbuf),
|
||||||
|
dgettext(TEXT_DOMAIN,
|
||||||
|
"cannot receive incremental stream"));
|
||||||
|
}
|
||||||
|
|
||||||
(void) strcpy(name, destsnap);
|
(void) strcpy(name, destsnap);
|
||||||
*strchr(name, '@') = '\0';
|
*strchr(name, '@') = '\0';
|
||||||
@@ -4210,34 +4217,6 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* It is invalid to receive a properties stream that was
|
|
||||||
* unencrypted on the send side as a child of an encrypted
|
|
||||||
* parent. Technically there is nothing preventing this, but
|
|
||||||
* it would mean that the encryption=off property which is
|
|
||||||
* locally set on the send side would not be received correctly.
|
|
||||||
* We can infer encryption=off if the stream is not raw and
|
|
||||||
* properties were included since the send side will only ever
|
|
||||||
* send the encryption property in a raw nvlist header. This
|
|
||||||
* check will be avoided if the user specifically overrides
|
|
||||||
* the encryption property on the command line.
|
|
||||||
*/
|
|
||||||
if (!raw && rcvprops != NULL &&
|
|
||||||
!nvlist_exists(cmdprops,
|
|
||||||
zfs_prop_to_name(ZFS_PROP_ENCRYPTION))) {
|
|
||||||
uint64_t crypt;
|
|
||||||
|
|
||||||
crypt = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION);
|
|
||||||
|
|
||||||
if (crypt != ZIO_CRYPT_OFF) {
|
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
|
||||||
"parent '%s' must not be encrypted to "
|
|
||||||
"receive unenecrypted property"), name);
|
|
||||||
err = zfs_error(hdl, EZFS_BADPROP, errbuf);
|
|
||||||
zfs_close(zhp);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
zfs_close(zhp);
|
zfs_close(zhp);
|
||||||
|
|
||||||
newfs = B_TRUE;
|
newfs = B_TRUE;
|
||||||
@@ -4274,6 +4253,24 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
|||||||
&oxprops, &wkeydata, &wkeylen, errbuf)) != 0)
|
&oxprops, &wkeydata, &wkeylen, errbuf)) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When sending with properties (zfs send -p), the encryption property
|
||||||
|
* is not included because it is a SETONCE property and therefore
|
||||||
|
* treated as read only. However, we are always able to determine its
|
||||||
|
* value because raw sends will include it in the DRR_BDEGIN payload
|
||||||
|
* and non-raw sends with properties are not allowed for encrypted
|
||||||
|
* datasets. Therefore, if this is a non-raw properties stream, we can
|
||||||
|
* infer that the value should be ZIO_CRYPT_OFF and manually add that
|
||||||
|
* to the received properties.
|
||||||
|
*/
|
||||||
|
if (stream_wantsnewfs && !raw && rcvprops != NULL &&
|
||||||
|
!nvlist_exists(cmdprops, zfs_prop_to_name(ZFS_PROP_ENCRYPTION))) {
|
||||||
|
if (oxprops == NULL)
|
||||||
|
oxprops = fnvlist_alloc();
|
||||||
|
fnvlist_add_uint64(oxprops,
|
||||||
|
zfs_prop_to_name(ZFS_PROP_ENCRYPTION), ZIO_CRYPT_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
err = ioctl_err = lzc_receive_with_cmdprops(destsnap, rcvprops,
|
err = ioctl_err = lzc_receive_with_cmdprops(destsnap, rcvprops,
|
||||||
oxprops, wkeydata, wkeylen, origin, flags->force, flags->resumable,
|
oxprops, wkeydata, wkeylen, origin, flags->force, flags->resumable,
|
||||||
raw, infd, drr_noswap, cleanup_fd, &read_bytes, &errflags,
|
raw, infd, drr_noswap, cleanup_fd, &read_bytes, &errflags,
|
||||||
@@ -4428,14 +4425,15 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
|||||||
*cp = '@';
|
*cp = '@';
|
||||||
break;
|
break;
|
||||||
case EINVAL:
|
case EINVAL:
|
||||||
if (flags->resumable)
|
if (flags->resumable) {
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
"kernel modules must be upgraded to "
|
"kernel modules must be upgraded to "
|
||||||
"receive this stream."));
|
"receive this stream."));
|
||||||
if (embedded && !raw)
|
} else if (embedded && !raw) {
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
"incompatible embedded data stream "
|
"incompatible embedded data stream "
|
||||||
"feature with encrypted receive."));
|
"feature with encrypted receive."));
|
||||||
|
}
|
||||||
(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
|
(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
|
||||||
break;
|
break;
|
||||||
case ECKSUM:
|
case ECKSUM:
|
||||||
|
|||||||
@@ -303,6 +303,8 @@ libzfs_error_description(libzfs_handle_t *hdl)
|
|||||||
case EZFS_NO_RESILVER_DEFER:
|
case EZFS_NO_RESILVER_DEFER:
|
||||||
return (dgettext(TEXT_DOMAIN, "this action requires the "
|
return (dgettext(TEXT_DOMAIN, "this action requires the "
|
||||||
"resilver_defer feature"));
|
"resilver_defer feature"));
|
||||||
|
case EZFS_EXPORT_IN_PROGRESS:
|
||||||
|
return (dgettext(TEXT_DOMAIN, "pool export in progress"));
|
||||||
case EZFS_UNKNOWN:
|
case EZFS_UNKNOWN:
|
||||||
return (dgettext(TEXT_DOMAIN, "unknown error"));
|
return (dgettext(TEXT_DOMAIN, "unknown error"));
|
||||||
default:
|
default:
|
||||||
@@ -598,6 +600,9 @@ zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
|
|||||||
case ZFS_ERR_VDEV_TOO_BIG:
|
case ZFS_ERR_VDEV_TOO_BIG:
|
||||||
zfs_verror(hdl, EZFS_VDEV_TOO_BIG, fmt, ap);
|
zfs_verror(hdl, EZFS_VDEV_TOO_BIG, fmt, ap);
|
||||||
break;
|
break;
|
||||||
|
case ZFS_ERR_EXPORT_IN_PROGRESS:
|
||||||
|
zfs_verror(hdl, EZFS_EXPORT_IN_PROGRESS, fmt, ap);
|
||||||
|
break;
|
||||||
case ZFS_ERR_IOC_CMD_UNAVAIL:
|
case ZFS_ERR_IOC_CMD_UNAVAIL:
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "the loaded zfs "
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "the loaded zfs "
|
||||||
"module does not support this operation. A reboot may "
|
"module does not support this operation. A reboot may "
|
||||||
@@ -1134,7 +1139,7 @@ int
|
|||||||
zcmd_alloc_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, size_t len)
|
zcmd_alloc_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, size_t len)
|
||||||
{
|
{
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
len = 16 * 1024;
|
len = 256 * 1024;
|
||||||
zc->zc_nvlist_dst_size = len;
|
zc->zc_nvlist_dst_size = len;
|
||||||
zc->zc_nvlist_dst =
|
zc->zc_nvlist_dst =
|
||||||
(uint64_t)(uintptr_t)zfs_alloc(hdl, zc->zc_nvlist_dst_size);
|
(uint64_t)(uintptr_t)zfs_alloc(hdl, zc->zc_nvlist_dst_size);
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
*
|
*
|
||||||
* - Thin Layer. libzfs_core is a thin layer, marshaling arguments
|
* - Thin Layer. libzfs_core is a thin layer, marshaling arguments
|
||||||
* to/from the kernel ioctls. There is generally a 1:1 correspondence
|
* to/from the kernel ioctls. There is generally a 1:1 correspondence
|
||||||
* between libzfs_core functions and ioctls to /dev/zfs.
|
* between libzfs_core functions and ioctls to ZFS_DEV.
|
||||||
*
|
*
|
||||||
* - Clear Atomicity. Because libzfs_core functions are generally 1:1
|
* - Clear Atomicity. Because libzfs_core functions are generally 1:1
|
||||||
* with kernel ioctls, and kernel ioctls are general atomic, each
|
* with kernel ioctls, and kernel ioctls are general atomic, each
|
||||||
@@ -135,7 +135,7 @@ libzfs_core_init(void)
|
|||||||
{
|
{
|
||||||
(void) pthread_mutex_lock(&g_lock);
|
(void) pthread_mutex_lock(&g_lock);
|
||||||
if (g_refcount == 0) {
|
if (g_refcount == 0) {
|
||||||
g_fd = open("/dev/zfs", O_RDWR);
|
g_fd = open(ZFS_DEV, O_RDWR);
|
||||||
if (g_fd < 0) {
|
if (g_fd < 0) {
|
||||||
(void) pthread_mutex_unlock(&g_lock);
|
(void) pthread_mutex_unlock(&g_lock);
|
||||||
return (errno);
|
return (errno);
|
||||||
@@ -499,7 +499,7 @@ lzc_sync(const char *pool_name, nvlist_t *innvl, nvlist_t **outnvl)
|
|||||||
* The snapshots must all be in the same pool.
|
* The snapshots must all be in the same pool.
|
||||||
* The value is the name of the hold (string type).
|
* The value is the name of the hold (string type).
|
||||||
*
|
*
|
||||||
* If cleanup_fd is not -1, it must be the result of open("/dev/zfs", O_EXCL).
|
* If cleanup_fd is not -1, it must be the result of open(ZFS_DEV, O_EXCL).
|
||||||
* In this case, when the cleanup_fd is closed (including on process
|
* In this case, when the cleanup_fd is closed (including on process
|
||||||
* termination), the holds will be released. If the system is shut down
|
* termination), the holds will be released. If the system is shut down
|
||||||
* uncleanly, the holds will be released when the pool is next opened
|
* uncleanly, the holds will be released when the pool is next opened
|
||||||
|
|||||||
+1
-1
@@ -223,7 +223,7 @@ pool_active(void *unused, const char *name, uint64_t guid,
|
|||||||
* Use ZFS_IOC_POOL_SYNC to confirm if a pool is active
|
* Use ZFS_IOC_POOL_SYNC to confirm if a pool is active
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fd = open("/dev/zfs", O_RDWR);
|
fd = open(ZFS_DEV, O_RDWR);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
dist_man_MANS = zhack.1 ztest.1 raidz_test.1
|
dist_man_MANS = zhack.1 ztest.1 raidz_test.1 zvol_wait.1
|
||||||
EXTRA_DIST = cstyle.1
|
EXTRA_DIST = cstyle.1
|
||||||
|
|
||||||
install-data-local:
|
install-data-local:
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
.TH raidz_test 1 "2016" "ZFS on Linux" "User Commands"
|
.TH raidz_test 1 "2016" "ZFS on Linux" "User Commands"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
\fBraidz_test\fR \- raidz implementation verification and bencmarking tool
|
\fBraidz_test\fR \- raidz implementation verification and benchmarking tool
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.LP
|
.LP
|
||||||
.BI "raidz_test <options>"
|
.BI "raidz_test <options>"
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
.Dd July 5, 2019
|
||||||
|
.Dt ZVOL_WAIT 1 SMM
|
||||||
|
.Os Linux
|
||||||
|
.Sh NAME
|
||||||
|
.Nm zvol_wait
|
||||||
|
.Nd Wait for ZFS volume links in
|
||||||
|
.Em /dev
|
||||||
|
to be created.
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
When a ZFS pool is imported, ZFS will register each ZFS volume
|
||||||
|
(zvol) as a disk device with the system. As the disks are registered,
|
||||||
|
.Xr \fBudev 7\fR
|
||||||
|
will asynchronously create symlinks under
|
||||||
|
.Em /dev/zvol
|
||||||
|
using the zvol's name.
|
||||||
|
.Nm
|
||||||
|
will wait for all those symlinks to be created before returning.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr \fBudev 7\fR
|
||||||
@@ -104,6 +104,18 @@ to a log2 fraction of the target arc size.
|
|||||||
Default value: \fB6\fR.
|
Default value: \fB6\fR.
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
.ne 2
|
||||||
|
.na
|
||||||
|
\fBdmu_prefetch_max\fR (int)
|
||||||
|
.ad
|
||||||
|
.RS 12n
|
||||||
|
Limit the amount we can prefetch with one call to this amount (in bytes).
|
||||||
|
This helps to limit the amount of memory that can be used by prefetching.
|
||||||
|
.sp
|
||||||
|
Default value: \fB134,217,728\fR (128MB).
|
||||||
|
.RE
|
||||||
|
|
||||||
.sp
|
.sp
|
||||||
.ne 2
|
.ne 2
|
||||||
.na
|
.na
|
||||||
@@ -502,6 +514,19 @@ regular reads (but there's no reason it has to be the same).
|
|||||||
Default value: \fB32,768\fR.
|
Default value: \fB32,768\fR.
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
.ne 2
|
||||||
|
.na
|
||||||
|
\fBzap_iterate_prefetch\fR (int)
|
||||||
|
.ad
|
||||||
|
.RS 12n
|
||||||
|
If this is set, when we start iterating over a ZAP object, zfs will prefetch
|
||||||
|
the entire object (all leaf blocks). However, this is limited by
|
||||||
|
\fBdmu_prefetch_max\fR.
|
||||||
|
.sp
|
||||||
|
Use \fB1\fR for on (default) and \fB0\fR for off.
|
||||||
|
.RE
|
||||||
|
|
||||||
.sp
|
.sp
|
||||||
.ne 2
|
.ne 2
|
||||||
.na
|
.na
|
||||||
@@ -1817,7 +1842,7 @@ this value. If a metaslab group exceeds this threshold then it will be
|
|||||||
skipped unless all metaslab groups within the metaslab class have also
|
skipped unless all metaslab groups within the metaslab class have also
|
||||||
crossed this threshold.
|
crossed this threshold.
|
||||||
.sp
|
.sp
|
||||||
Default value: \fB85\fR.
|
Default value: \fB95\fR.
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
.sp
|
.sp
|
||||||
@@ -2169,6 +2194,33 @@ pool cannot be returned to a healthy state prior to removing the device.
|
|||||||
Default value: \fB0\fR.
|
Default value: \fB0\fR.
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
.ne 2
|
||||||
|
.na
|
||||||
|
\fBzfs_removal_suspend_progress\fR (int)
|
||||||
|
.ad
|
||||||
|
.RS 12n
|
||||||
|
.sp
|
||||||
|
This is used by the test suite so that it can ensure that certain actions
|
||||||
|
happen while in the middle of a removal.
|
||||||
|
.sp
|
||||||
|
Default value: \fB0\fR.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
.ne 2
|
||||||
|
.na
|
||||||
|
\fBzfs_remove_max_segment\fR (int)
|
||||||
|
.ad
|
||||||
|
.RS 12n
|
||||||
|
.sp
|
||||||
|
The largest contiguous segment that we will attempt to allocate when removing
|
||||||
|
a device. This can be no larger than 16MB. If there is a performance
|
||||||
|
problem with attempting to allocate large blocks, consider decreasing this.
|
||||||
|
.sp
|
||||||
|
Default value: \fB16,777,216\fR (16MB).
|
||||||
|
.RE
|
||||||
|
|
||||||
.sp
|
.sp
|
||||||
.ne 2
|
.ne 2
|
||||||
.na
|
.na
|
||||||
@@ -2419,9 +2471,21 @@ Default value: \fB25\fR.
|
|||||||
\fBzfs_sync_pass_dont_compress\fR (int)
|
\fBzfs_sync_pass_dont_compress\fR (int)
|
||||||
.ad
|
.ad
|
||||||
.RS 12n
|
.RS 12n
|
||||||
Don't compress starting in this pass
|
Starting in this sync pass, we disable compression (including of metadata).
|
||||||
|
With the default setting, in practice, we don't have this many sync passes,
|
||||||
|
so this has no effect.
|
||||||
.sp
|
.sp
|
||||||
Default value: \fB5\fR.
|
The original intent was that disabling compression would help the sync passes
|
||||||
|
to converge. However, in practice disabling compression increases the average
|
||||||
|
number of sync passes, because when we turn compression off, a lot of block's
|
||||||
|
size will change and thus we have to re-allocate (not overwrite) them. It
|
||||||
|
also increases the number of 128KB allocations (e.g. for indirect blocks and
|
||||||
|
spacemaps) because these will not be compressed. The 128K allocations are
|
||||||
|
especially detrimental to performance on highly fragmented systems, which may
|
||||||
|
have very few free segments of this size, and may need to load new metaslabs
|
||||||
|
to satisfy 128K allocations.
|
||||||
|
.sp
|
||||||
|
Default value: \fB8\fR.
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
.sp
|
.sp
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ information on ZFS mountpoints must be stored separately. The output
|
|||||||
of the command
|
of the command
|
||||||
.PP
|
.PP
|
||||||
.RS 4
|
.RS 4
|
||||||
zfs list -H -o name,mountpoint,canmount,atime,relatime,devices,exec,readonly,setuid,nbmand
|
zfs list -H -o name,mountpoint,canmount,atime,relatime,devices,exec,readonly,setuid,nbmand,encroot,keylocation
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
for datasets that should be mounted by systemd, should be kept
|
for datasets that should be mounted by systemd, should be kept
|
||||||
|
|||||||
+14
-13
@@ -1,11 +1,11 @@
|
|||||||
subdir-m += avl
|
obj-m += avl/
|
||||||
subdir-m += icp
|
obj-m += icp/
|
||||||
subdir-m += lua
|
obj-m += lua/
|
||||||
subdir-m += nvpair
|
obj-m += nvpair/
|
||||||
subdir-m += spl
|
obj-m += spl/
|
||||||
subdir-m += unicode
|
obj-m += unicode/
|
||||||
subdir-m += zcommon
|
obj-m += zcommon/
|
||||||
subdir-m += zfs
|
obj-m += zfs/
|
||||||
|
|
||||||
INSTALL_MOD_DIR ?= extra
|
INSTALL_MOD_DIR ?= extra
|
||||||
|
|
||||||
@@ -60,14 +60,15 @@ modules_install:
|
|||||||
modules_uninstall:
|
modules_uninstall:
|
||||||
@# Uninstall the kernel modules
|
@# Uninstall the kernel modules
|
||||||
kmoddir=$(DESTDIR)$(INSTALL_MOD_PATH)/lib/modules/@LINUX_VERSION@
|
kmoddir=$(DESTDIR)$(INSTALL_MOD_PATH)/lib/modules/@LINUX_VERSION@
|
||||||
list='$(subdir-m)'; for subdir in $$list; do \
|
list='$(obj-m)'; for objdir in $$list; do \
|
||||||
$(RM) -R $$kmoddir/$(INSTALL_MOD_DIR)/$$subdir; \
|
$(RM) -R $$kmoddir/$(INSTALL_MOD_DIR)/$$objdir; \
|
||||||
done
|
done
|
||||||
|
|
||||||
distdir:
|
distdir:
|
||||||
list='$(subdir-m)'; for subdir in $$list; do \
|
list='$(obj-m)'; for objdir in $$list; do \
|
||||||
(cd @top_srcdir@/module && find $$subdir -name '*.c' -o -name '*.h' -o -name '*.S' |\
|
(cd @top_srcdir@/module && find $$objdir \
|
||||||
xargs cp --parents -t $$distdir); \
|
-name '*.c' -o -name '*.h' -o -name '*.S' | \
|
||||||
|
xargs cp --parents -t @abs_top_builddir@/module/$$distdir); \
|
||||||
done
|
done
|
||||||
|
|
||||||
distclean maintainer-clean: clean
|
distclean maintainer-clean: clean
|
||||||
|
|||||||
@@ -303,16 +303,21 @@ aes_impl_init(void)
|
|||||||
}
|
}
|
||||||
aes_supp_impl_cnt = c;
|
aes_supp_impl_cnt = c;
|
||||||
|
|
||||||
/* set fastest implementation. assume hardware accelerated is fastest */
|
/*
|
||||||
|
* Set the fastest implementation given the assumption that the
|
||||||
|
* hardware accelerated version is the fastest.
|
||||||
|
*/
|
||||||
#if defined(__x86_64)
|
#if defined(__x86_64)
|
||||||
#if defined(HAVE_AES)
|
#if defined(HAVE_AES)
|
||||||
if (aes_aesni_impl.is_supported())
|
if (aes_aesni_impl.is_supported()) {
|
||||||
memcpy(&aes_fastest_impl, &aes_aesni_impl,
|
memcpy(&aes_fastest_impl, &aes_aesni_impl,
|
||||||
sizeof (aes_fastest_impl));
|
sizeof (aes_fastest_impl));
|
||||||
else
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
memcpy(&aes_fastest_impl, &aes_x86_64_impl,
|
memcpy(&aes_fastest_impl, &aes_x86_64_impl,
|
||||||
sizeof (aes_fastest_impl));
|
sizeof (aes_fastest_impl));
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
memcpy(&aes_fastest_impl, &aes_generic_impl,
|
memcpy(&aes_fastest_impl, &aes_generic_impl,
|
||||||
sizeof (aes_fastest_impl));
|
sizeof (aes_fastest_impl));
|
||||||
|
|||||||
@@ -646,7 +646,7 @@ const gcm_impl_ops_t *gcm_all_impl[] = {
|
|||||||
/* Indicate that benchmark has been completed */
|
/* Indicate that benchmark has been completed */
|
||||||
static boolean_t gcm_impl_initialized = B_FALSE;
|
static boolean_t gcm_impl_initialized = B_FALSE;
|
||||||
|
|
||||||
/* Select aes implementation */
|
/* Select GCM implementation */
|
||||||
#define IMPL_FASTEST (UINT32_MAX)
|
#define IMPL_FASTEST (UINT32_MAX)
|
||||||
#define IMPL_CYCLE (UINT32_MAX-1)
|
#define IMPL_CYCLE (UINT32_MAX-1)
|
||||||
|
|
||||||
@@ -713,13 +713,15 @@ gcm_impl_init(void)
|
|||||||
|
|
||||||
/* set fastest implementation. assume hardware accelerated is fastest */
|
/* set fastest implementation. assume hardware accelerated is fastest */
|
||||||
#if defined(__x86_64) && defined(HAVE_PCLMULQDQ)
|
#if defined(__x86_64) && defined(HAVE_PCLMULQDQ)
|
||||||
if (gcm_pclmulqdq_impl.is_supported())
|
if (gcm_pclmulqdq_impl.is_supported()) {
|
||||||
memcpy(&gcm_fastest_impl, &gcm_pclmulqdq_impl,
|
memcpy(&gcm_fastest_impl, &gcm_pclmulqdq_impl,
|
||||||
sizeof (gcm_fastest_impl));
|
sizeof (gcm_fastest_impl));
|
||||||
else
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
memcpy(&gcm_fastest_impl, &gcm_generic_impl,
|
memcpy(&gcm_fastest_impl, &gcm_generic_impl,
|
||||||
sizeof (gcm_fastest_impl));
|
sizeof (gcm_fastest_impl));
|
||||||
|
}
|
||||||
|
|
||||||
strcpy(gcm_fastest_impl.name, "fastest");
|
strcpy(gcm_fastest_impl.name, "fastest");
|
||||||
|
|
||||||
@@ -742,7 +744,7 @@ static const struct {
|
|||||||
* If we are called before init(), user preference will be saved in
|
* If we are called before init(), user preference will be saved in
|
||||||
* user_sel_impl, and applied in later init() call. This occurs when module
|
* user_sel_impl, and applied in later init() call. This occurs when module
|
||||||
* parameter is specified on module load. Otherwise, directly update
|
* parameter is specified on module load. Otherwise, directly update
|
||||||
* icp_aes_impl.
|
* icp_gcm_impl.
|
||||||
*
|
*
|
||||||
* @val Name of gcm implementation to use
|
* @val Name of gcm implementation to use
|
||||||
* @param Unused.
|
* @param Unused.
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ typedef enum aes_mech_type {
|
|||||||
#endif /* _AES_IMPL */
|
#endif /* _AES_IMPL */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Methods used to define aes implementation
|
* Methods used to define AES implementation
|
||||||
*
|
*
|
||||||
* @aes_gen_f Key generation
|
* @aes_gen_f Key generation
|
||||||
* @aes_enc_f Function encrypts one block
|
* @aes_enc_f Function encrypts one block
|
||||||
|
|||||||
@@ -37,12 +37,12 @@ extern "C" {
|
|||||||
#include <sys/crypto/common.h>
|
#include <sys/crypto/common.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Methods used to define gcm implementation
|
* Methods used to define GCM implementation
|
||||||
*
|
*
|
||||||
* @gcm_mul_f Perform carry-less multiplication
|
* @gcm_mul_f Perform carry-less multiplication
|
||||||
* @gcm_will_work_f Function tests whether implementation will function
|
* @gcm_will_work_f Function tests whether implementation will function
|
||||||
*/
|
*/
|
||||||
typedef void (*gcm_mul_f)(uint64_t *, uint64_t *, uint64_t *);
|
typedef void (*gcm_mul_f)(uint64_t *, uint64_t *, uint64_t *);
|
||||||
typedef boolean_t (*gcm_will_work_f)(void);
|
typedef boolean_t (*gcm_will_work_f)(void);
|
||||||
|
|
||||||
#define GCM_IMPL_NAME_MAX (16)
|
#define GCM_IMPL_NAME_MAX (16)
|
||||||
|
|||||||
+1
-1
@@ -61,7 +61,7 @@
|
|||||||
#elif defined(__mips__)
|
#elif defined(__mips__)
|
||||||
#define JMP_BUF_CNT 12
|
#define JMP_BUF_CNT 12
|
||||||
#elif defined(__s390x__)
|
#elif defined(__s390x__)
|
||||||
#define JMP_BUF_CNT 9
|
#define JMP_BUF_CNT 18
|
||||||
#else
|
#else
|
||||||
#define JMP_BUF_CNT 1
|
#define JMP_BUF_CNT 1
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+6
-3
@@ -431,9 +431,12 @@ static int llex (LexState *ls, SemInfo *seminfo) {
|
|||||||
if (sep >= 0) {
|
if (sep >= 0) {
|
||||||
read_long_string(ls, seminfo, sep);
|
read_long_string(ls, seminfo, sep);
|
||||||
return TK_STRING;
|
return TK_STRING;
|
||||||
}
|
} else if (sep == -1) {
|
||||||
else if (sep == -1) return '[';
|
return '[';
|
||||||
else lexerror(ls, "invalid long string delimiter", TK_STRING);
|
} else {
|
||||||
|
lexerror(ls, "invalid long string delimiter", TK_STRING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case '=': {
|
case '=': {
|
||||||
next(ls);
|
next(ls);
|
||||||
|
|||||||
@@ -16,10 +16,8 @@ $(MODULE)-objs += spl-kmem.o
|
|||||||
$(MODULE)-objs += spl-kmem-cache.o
|
$(MODULE)-objs += spl-kmem-cache.o
|
||||||
$(MODULE)-objs += spl-kobj.o
|
$(MODULE)-objs += spl-kobj.o
|
||||||
$(MODULE)-objs += spl-kstat.o
|
$(MODULE)-objs += spl-kstat.o
|
||||||
$(MODULE)-objs += spl-mutex.o
|
|
||||||
$(MODULE)-objs += spl-proc.o
|
$(MODULE)-objs += spl-proc.o
|
||||||
$(MODULE)-objs += spl-procfs-list.o
|
$(MODULE)-objs += spl-procfs-list.o
|
||||||
$(MODULE)-objs += spl-rwlock.o
|
|
||||||
$(MODULE)-objs += spl-taskq.o
|
$(MODULE)-objs += spl-taskq.o
|
||||||
$(MODULE)-objs += spl-thread.o
|
$(MODULE)-objs += spl-thread.o
|
||||||
$(MODULE)-objs += spl-tsd.o
|
$(MODULE)-objs += spl-tsd.o
|
||||||
|
|||||||
@@ -154,26 +154,39 @@ EXPORT_SYMBOL(__cv_wait_sig);
|
|||||||
#if defined(HAVE_IO_SCHEDULE_TIMEOUT)
|
#if defined(HAVE_IO_SCHEDULE_TIMEOUT)
|
||||||
#define spl_io_schedule_timeout(t) io_schedule_timeout(t)
|
#define spl_io_schedule_timeout(t) io_schedule_timeout(t)
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
struct spl_task_timer {
|
||||||
|
struct timer_list timer;
|
||||||
|
struct task_struct *task;
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
__cv_wakeup(unsigned long data)
|
__cv_wakeup(spl_timer_list_t t)
|
||||||
{
|
{
|
||||||
wake_up_process((struct task_struct *)data);
|
struct timer_list *tmr = (struct timer_list *)t;
|
||||||
|
struct spl_task_timer *task_timer = from_timer(task_timer, tmr, timer);
|
||||||
|
|
||||||
|
wake_up_process(task_timer->task);
|
||||||
}
|
}
|
||||||
|
|
||||||
static long
|
static long
|
||||||
spl_io_schedule_timeout(long time_left)
|
spl_io_schedule_timeout(long time_left)
|
||||||
{
|
{
|
||||||
long expire_time = jiffies + time_left;
|
long expire_time = jiffies + time_left;
|
||||||
struct timer_list timer;
|
struct spl_task_timer task_timer;
|
||||||
|
struct timer_list *timer = &task_timer.timer;
|
||||||
|
|
||||||
init_timer(&timer);
|
task_timer.task = current;
|
||||||
setup_timer(&timer, __cv_wakeup, (unsigned long)current);
|
|
||||||
timer.expires = expire_time;
|
timer_setup(timer, __cv_wakeup, 0);
|
||||||
add_timer(&timer);
|
|
||||||
|
timer->expires = expire_time;
|
||||||
|
add_timer(timer);
|
||||||
|
|
||||||
io_schedule();
|
io_schedule();
|
||||||
|
|
||||||
del_timer_sync(&timer);
|
del_timer_sync(timer);
|
||||||
|
|
||||||
time_left = expire_time - jiffies;
|
time_left = expire_time - jiffies;
|
||||||
|
|
||||||
return (time_left < 0 ? 0 : time_left);
|
return (time_left < 0 ? 0 : time_left);
|
||||||
|
|||||||
+13
-25
@@ -694,51 +694,41 @@ spl_init(void)
|
|||||||
if ((rc = spl_kvmem_init()))
|
if ((rc = spl_kvmem_init()))
|
||||||
goto out1;
|
goto out1;
|
||||||
|
|
||||||
if ((rc = spl_mutex_init()))
|
if ((rc = spl_tsd_init()))
|
||||||
goto out2;
|
goto out2;
|
||||||
|
|
||||||
if ((rc = spl_rw_init()))
|
if ((rc = spl_taskq_init()))
|
||||||
goto out3;
|
goto out3;
|
||||||
|
|
||||||
if ((rc = spl_tsd_init()))
|
if ((rc = spl_kmem_cache_init()))
|
||||||
goto out4;
|
goto out4;
|
||||||
|
|
||||||
if ((rc = spl_taskq_init()))
|
if ((rc = spl_vn_init()))
|
||||||
goto out5;
|
goto out5;
|
||||||
|
|
||||||
if ((rc = spl_kmem_cache_init()))
|
if ((rc = spl_proc_init()))
|
||||||
goto out6;
|
goto out6;
|
||||||
|
|
||||||
if ((rc = spl_vn_init()))
|
if ((rc = spl_kstat_init()))
|
||||||
goto out7;
|
goto out7;
|
||||||
|
|
||||||
if ((rc = spl_proc_init()))
|
|
||||||
goto out8;
|
|
||||||
|
|
||||||
if ((rc = spl_kstat_init()))
|
|
||||||
goto out9;
|
|
||||||
|
|
||||||
if ((rc = spl_zlib_init()))
|
if ((rc = spl_zlib_init()))
|
||||||
goto out10;
|
goto out8;
|
||||||
|
|
||||||
return (rc);
|
return (rc);
|
||||||
|
|
||||||
out10:
|
|
||||||
spl_kstat_fini();
|
|
||||||
out9:
|
|
||||||
spl_proc_fini();
|
|
||||||
out8:
|
out8:
|
||||||
spl_vn_fini();
|
spl_kstat_fini();
|
||||||
out7:
|
out7:
|
||||||
spl_kmem_cache_fini();
|
spl_proc_fini();
|
||||||
out6:
|
out6:
|
||||||
spl_taskq_fini();
|
spl_vn_fini();
|
||||||
out5:
|
out5:
|
||||||
spl_tsd_fini();
|
spl_kmem_cache_fini();
|
||||||
out4:
|
out4:
|
||||||
spl_rw_fini();
|
spl_taskq_fini();
|
||||||
out3:
|
out3:
|
||||||
spl_mutex_fini();
|
spl_tsd_fini();
|
||||||
out2:
|
out2:
|
||||||
spl_kvmem_fini();
|
spl_kvmem_fini();
|
||||||
out1:
|
out1:
|
||||||
@@ -755,8 +745,6 @@ spl_fini(void)
|
|||||||
spl_kmem_cache_fini();
|
spl_kmem_cache_fini();
|
||||||
spl_taskq_fini();
|
spl_taskq_fini();
|
||||||
spl_tsd_fini();
|
spl_tsd_fini();
|
||||||
spl_rw_fini();
|
|
||||||
spl_mutex_fini();
|
|
||||||
spl_kvmem_fini();
|
spl_kvmem_fini();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -180,7 +180,8 @@ spl_kmem_alloc_impl(size_t size, int flags, int node)
|
|||||||
*/
|
*/
|
||||||
if ((size > spl_kmem_alloc_max) || use_vmem) {
|
if ((size > spl_kmem_alloc_max) || use_vmem) {
|
||||||
if (flags & KM_VMEM) {
|
if (flags & KM_VMEM) {
|
||||||
ptr = __vmalloc(size, lflags, PAGE_KERNEL);
|
ptr = __vmalloc(size, lflags | __GFP_HIGHMEM,
|
||||||
|
PAGE_KERNEL);
|
||||||
} else {
|
} else {
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
|
|
||||||
* Copyright (C) 2007 The Regents of the University of California.
|
|
||||||
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
|
|
||||||
* Written by Brian Behlendorf <behlendorf1@llnl.gov>.
|
|
||||||
* UCRL-CODE-235197
|
|
||||||
*
|
|
||||||
* This file is part of the SPL, Solaris Porting Layer.
|
|
||||||
* For details, see <http://zfsonlinux.org/>.
|
|
||||||
*
|
|
||||||
* The SPL is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the
|
|
||||||
* Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
* option) any later version.
|
|
||||||
*
|
|
||||||
* The SPL is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with the SPL. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Solaris Porting Layer (SPL) Mutex Implementation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/mutex.h>
|
|
||||||
|
|
||||||
int spl_mutex_init(void) { return 0; }
|
|
||||||
void spl_mutex_fini(void) { }
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
|
|
||||||
* Copyright (C) 2007 The Regents of the University of California.
|
|
||||||
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
|
|
||||||
* Written by Brian Behlendorf <behlendorf1@llnl.gov>.
|
|
||||||
* UCRL-CODE-235197
|
|
||||||
*
|
|
||||||
* This file is part of the SPL, Solaris Porting Layer.
|
|
||||||
* For details, see <http://zfsonlinux.org/>.
|
|
||||||
*
|
|
||||||
* The SPL is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the
|
|
||||||
* Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
* option) any later version.
|
|
||||||
*
|
|
||||||
* The SPL is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with the SPL. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Solaris Porting Layer (SPL) Reader/Writer Lock Implementation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/rwlock.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
|
|
||||||
#if defined(CONFIG_PREEMPT_RT_FULL)
|
|
||||||
|
|
||||||
#include <linux/rtmutex.h>
|
|
||||||
#define RT_MUTEX_OWNER_MASKALL 1UL
|
|
||||||
|
|
||||||
static int
|
|
||||||
__rwsem_tryupgrade(struct rw_semaphore *rwsem)
|
|
||||||
{
|
|
||||||
#if defined(READER_BIAS) && defined(WRITER_BIAS)
|
|
||||||
/*
|
|
||||||
* After the 4.9.20-rt16 kernel the realtime patch series lifted the
|
|
||||||
* single reader restriction. While this could be accommodated by
|
|
||||||
* adding additional compatibility code assume the rwsem can never
|
|
||||||
* be upgraded. All caller must already cleanly handle this case.
|
|
||||||
*/
|
|
||||||
return (0);
|
|
||||||
#else
|
|
||||||
ASSERT((struct task_struct *)
|
|
||||||
((unsigned long)rwsem->lock.owner & ~RT_MUTEX_OWNER_MASKALL) ==
|
|
||||||
current);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prior to 4.9.20-rt16 kernel the realtime patch series, rwsem is
|
|
||||||
* implemented as a single mutex held by readers and writers alike.
|
|
||||||
* However, this implementation would prevent a thread from taking
|
|
||||||
* a read lock twice, as the mutex would already be locked on
|
|
||||||
* the second attempt. Therefore the implementation allows a
|
|
||||||
* single thread to take a rwsem as read lock multiple times
|
|
||||||
* tracking that nesting as read_depth counter.
|
|
||||||
*/
|
|
||||||
if (rwsem->read_depth <= 1) {
|
|
||||||
/*
|
|
||||||
* In case, the current thread has not taken the lock
|
|
||||||
* more than once as read lock, we can allow an
|
|
||||||
* upgrade to a write lock. rwsem_rt.h implements
|
|
||||||
* write locks as read_depth == 0.
|
|
||||||
*/
|
|
||||||
rwsem->read_depth = 0;
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#elif defined(CONFIG_RWSEM_GENERIC_SPINLOCK)
|
|
||||||
static int
|
|
||||||
__rwsem_tryupgrade(struct rw_semaphore *rwsem)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
unsigned long flags;
|
|
||||||
spl_rwsem_lock_irqsave(&rwsem->wait_lock, flags);
|
|
||||||
if (RWSEM_COUNT(rwsem) == SPL_RWSEM_SINGLE_READER_VALUE &&
|
|
||||||
list_empty(&rwsem->wait_list)) {
|
|
||||||
ret = 1;
|
|
||||||
RWSEM_COUNT(rwsem) = SPL_RWSEM_SINGLE_WRITER_VALUE;
|
|
||||||
}
|
|
||||||
spl_rwsem_unlock_irqrestore(&rwsem->wait_lock, flags);
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
#elif defined(RWSEM_ACTIVE_MASK)
|
|
||||||
#if defined(HAVE_RWSEM_ATOMIC_LONG_COUNT)
|
|
||||||
static int
|
|
||||||
__rwsem_tryupgrade(struct rw_semaphore *rwsem)
|
|
||||||
{
|
|
||||||
long val;
|
|
||||||
val = atomic_long_cmpxchg(&rwsem->count, SPL_RWSEM_SINGLE_READER_VALUE,
|
|
||||||
SPL_RWSEM_SINGLE_WRITER_VALUE);
|
|
||||||
return (val == SPL_RWSEM_SINGLE_READER_VALUE);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static int
|
|
||||||
__rwsem_tryupgrade(struct rw_semaphore *rwsem)
|
|
||||||
{
|
|
||||||
typeof(rwsem->count) val;
|
|
||||||
val = cmpxchg(&rwsem->count, SPL_RWSEM_SINGLE_READER_VALUE,
|
|
||||||
SPL_RWSEM_SINGLE_WRITER_VALUE);
|
|
||||||
return (val == SPL_RWSEM_SINGLE_READER_VALUE);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
static int
|
|
||||||
__rwsem_tryupgrade(struct rw_semaphore *rwsem)
|
|
||||||
{
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
|
||||||
rwsem_tryupgrade(struct rw_semaphore *rwsem)
|
|
||||||
{
|
|
||||||
if (__rwsem_tryupgrade(rwsem)) {
|
|
||||||
rwsem_release(&rwsem->dep_map, 1, _RET_IP_);
|
|
||||||
rwsem_acquire(&rwsem->dep_map, 0, 1, _RET_IP_);
|
|
||||||
#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
|
|
||||||
rwsem->owner = current;
|
|
||||||
#endif
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(rwsem_tryupgrade);
|
|
||||||
|
|
||||||
int spl_rw_init(void) { return 0; }
|
|
||||||
void spl_rw_fini(void) { }
|
|
||||||
+4
-20
@@ -24,6 +24,7 @@
|
|||||||
* Solaris Porting Layer (SPL) Task Queue Implementation.
|
* Solaris Porting Layer (SPL) Task Queue Implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <sys/timer.h>
|
||||||
#include <sys/taskq.h>
|
#include <sys/taskq.h>
|
||||||
#include <sys/kmem.h>
|
#include <sys/kmem.h>
|
||||||
#include <sys/tsd.h>
|
#include <sys/tsd.h>
|
||||||
@@ -242,20 +243,13 @@ task_expire_impl(taskq_ent_t *t)
|
|||||||
wake_up(&tq->tq_work_waitq);
|
wake_up(&tq->tq_work_waitq);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_KERNEL_TIMER_FUNCTION_TIMER_LIST
|
|
||||||
static void
|
static void
|
||||||
task_expire(struct timer_list *tl)
|
task_expire(spl_timer_list_t tl)
|
||||||
{
|
{
|
||||||
taskq_ent_t *t = from_timer(t, tl, tqent_timer);
|
struct timer_list *tmr = (struct timer_list *)tl;
|
||||||
|
taskq_ent_t *t = from_timer(t, tmr, tqent_timer);
|
||||||
task_expire_impl(t);
|
task_expire_impl(t);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static void
|
|
||||||
task_expire(unsigned long data)
|
|
||||||
{
|
|
||||||
task_expire_impl((taskq_ent_t *)data);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the lowest incomplete taskqid_t. The taskqid_t may
|
* Returns the lowest incomplete taskqid_t. The taskqid_t may
|
||||||
@@ -597,9 +591,6 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags)
|
|||||||
t->tqent_func = func;
|
t->tqent_func = func;
|
||||||
t->tqent_arg = arg;
|
t->tqent_arg = arg;
|
||||||
t->tqent_taskq = tq;
|
t->tqent_taskq = tq;
|
||||||
#ifndef HAVE_KERNEL_TIMER_FUNCTION_TIMER_LIST
|
|
||||||
t->tqent_timer.data = 0;
|
|
||||||
#endif
|
|
||||||
t->tqent_timer.function = NULL;
|
t->tqent_timer.function = NULL;
|
||||||
t->tqent_timer.expires = 0;
|
t->tqent_timer.expires = 0;
|
||||||
t->tqent_birth = jiffies;
|
t->tqent_birth = jiffies;
|
||||||
@@ -649,9 +640,6 @@ taskq_dispatch_delay(taskq_t *tq, task_func_t func, void *arg,
|
|||||||
t->tqent_func = func;
|
t->tqent_func = func;
|
||||||
t->tqent_arg = arg;
|
t->tqent_arg = arg;
|
||||||
t->tqent_taskq = tq;
|
t->tqent_taskq = tq;
|
||||||
#ifndef HAVE_KERNEL_TIMER_FUNCTION_TIMER_LIST
|
|
||||||
t->tqent_timer.data = (unsigned long)t;
|
|
||||||
#endif
|
|
||||||
t->tqent_timer.function = task_expire;
|
t->tqent_timer.function = task_expire;
|
||||||
t->tqent_timer.expires = (unsigned long)expire_time;
|
t->tqent_timer.expires = (unsigned long)expire_time;
|
||||||
add_timer(&t->tqent_timer);
|
add_timer(&t->tqent_timer);
|
||||||
@@ -744,11 +732,7 @@ taskq_init_ent(taskq_ent_t *t)
|
|||||||
{
|
{
|
||||||
spin_lock_init(&t->tqent_lock);
|
spin_lock_init(&t->tqent_lock);
|
||||||
init_waitqueue_head(&t->tqent_waitq);
|
init_waitqueue_head(&t->tqent_waitq);
|
||||||
#ifdef HAVE_KERNEL_TIMER_FUNCTION_TIMER_LIST
|
|
||||||
timer_setup(&t->tqent_timer, NULL, 0);
|
timer_setup(&t->tqent_timer, NULL, 0);
|
||||||
#else
|
|
||||||
init_timer(&t->tqent_timer);
|
|
||||||
#endif
|
|
||||||
INIT_LIST_HEAD(&t->tqent_list);
|
INIT_LIST_HEAD(&t->tqent_list);
|
||||||
t->tqent_id = 0;
|
t->tqent_id = 0;
|
||||||
t->tqent_func = NULL;
|
t->tqent_func = NULL;
|
||||||
|
|||||||
@@ -153,8 +153,9 @@ spl_kthread_create(int (*func)(void *), void *data, const char namefmt[], ...)
|
|||||||
if (PTR_ERR(tsk) == -ENOMEM)
|
if (PTR_ERR(tsk) == -ENOMEM)
|
||||||
continue;
|
continue;
|
||||||
return (NULL);
|
return (NULL);
|
||||||
} else
|
} else {
|
||||||
return (tsk);
|
return (tsk);
|
||||||
|
}
|
||||||
} while (1);
|
} while (1);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(spl_kthread_create);
|
EXPORT_SYMBOL(spl_kthread_create);
|
||||||
|
|||||||
@@ -641,68 +641,6 @@ vn_areleasef(int fd, uf_info_t *fip)
|
|||||||
} /* releasef() */
|
} /* releasef() */
|
||||||
EXPORT_SYMBOL(areleasef);
|
EXPORT_SYMBOL(areleasef);
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
#ifdef HAVE_SET_FS_PWD_WITH_CONST
|
|
||||||
vn_set_fs_pwd(struct fs_struct *fs, const struct path *path)
|
|
||||||
#else
|
|
||||||
vn_set_fs_pwd(struct fs_struct *fs, struct path *path)
|
|
||||||
#endif /* HAVE_SET_FS_PWD_WITH_CONST */
|
|
||||||
{
|
|
||||||
struct path old_pwd;
|
|
||||||
|
|
||||||
#ifdef HAVE_FS_STRUCT_SPINLOCK
|
|
||||||
spin_lock(&fs->lock);
|
|
||||||
old_pwd = fs->pwd;
|
|
||||||
fs->pwd = *path;
|
|
||||||
path_get(path);
|
|
||||||
spin_unlock(&fs->lock);
|
|
||||||
#else
|
|
||||||
write_lock(&fs->lock);
|
|
||||||
old_pwd = fs->pwd;
|
|
||||||
fs->pwd = *path;
|
|
||||||
path_get(path);
|
|
||||||
write_unlock(&fs->lock);
|
|
||||||
#endif /* HAVE_FS_STRUCT_SPINLOCK */
|
|
||||||
|
|
||||||
if (old_pwd.dentry)
|
|
||||||
path_put(&old_pwd);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
vn_set_pwd(const char *filename)
|
|
||||||
{
|
|
||||||
struct path path;
|
|
||||||
mm_segment_t saved_fs;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* user_path_dir() and __user_walk() both expect 'filename' to be
|
|
||||||
* a user space address so we must briefly increase the data segment
|
|
||||||
* size to ensure strncpy_from_user() does not fail with -EFAULT.
|
|
||||||
*/
|
|
||||||
saved_fs = get_fs();
|
|
||||||
set_fs(KERNEL_DS);
|
|
||||||
|
|
||||||
rc = user_path_dir(filename, &path);
|
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
rc = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS);
|
|
||||||
if (rc)
|
|
||||||
goto dput_and_out;
|
|
||||||
|
|
||||||
vn_set_fs_pwd(current->fs, &path);
|
|
||||||
|
|
||||||
dput_and_out:
|
|
||||||
path_put(&path);
|
|
||||||
out:
|
|
||||||
set_fs(saved_fs);
|
|
||||||
|
|
||||||
return (-rc);
|
|
||||||
} /* vn_set_pwd() */
|
|
||||||
EXPORT_SYMBOL(vn_set_pwd);
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vn_cache_constructor(void *buf, void *cdrarg, int kmflags)
|
vn_cache_constructor(void *buf, void *cdrarg, int kmflags)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -592,8 +592,9 @@ fletcher_4_incremental_byteswap(void *buf, size_t size, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_KERNEL)
|
#if defined(_KERNEL)
|
||||||
/* Fletcher 4 kstats */
|
/*
|
||||||
|
* Fletcher 4 kstats
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
fletcher_4_kstat_headers(char *buf, size_t size)
|
fletcher_4_kstat_headers(char *buf, size_t size)
|
||||||
{
|
{
|
||||||
@@ -669,7 +670,6 @@ fletcher_4_benchmark_impl(boolean_t native, char *data, uint64_t data_size)
|
|||||||
zio_cksum_t zc;
|
zio_cksum_t zc;
|
||||||
uint32_t i, l, sel_save = IMPL_READ(fletcher_4_impl_chosen);
|
uint32_t i, l, sel_save = IMPL_READ(fletcher_4_impl_chosen);
|
||||||
|
|
||||||
|
|
||||||
fletcher_checksum_func_t *fletcher_4_test = native ?
|
fletcher_checksum_func_t *fletcher_4_test = native ?
|
||||||
fletcher_4_native : fletcher_4_byteswap;
|
fletcher_4_native : fletcher_4_byteswap;
|
||||||
|
|
||||||
|
|||||||
@@ -232,6 +232,27 @@ entity_namecheck(const char *path, namecheck_err_t *why, char *what)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*end == '\0' || *end == '/') {
|
||||||
|
int component_length = end - start;
|
||||||
|
/* Validate the contents of this component is not '.' */
|
||||||
|
if (component_length == 1) {
|
||||||
|
if (start[0] == '.') {
|
||||||
|
if (why)
|
||||||
|
*why = NAME_ERR_SELF_REF;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate the content of this component is not '..' */
|
||||||
|
if (component_length == 2) {
|
||||||
|
if (start[0] == '.' && start[1] == '.') {
|
||||||
|
if (why)
|
||||||
|
*why = NAME_ERR_PARENT_REF;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Snapshot or bookmark delimiter found */
|
/* Snapshot or bookmark delimiter found */
|
||||||
if (*end == '@' || *end == '#') {
|
if (*end == '@' || *end == '#') {
|
||||||
/* Multiple delimiters are not allowed */
|
/* Multiple delimiters are not allowed */
|
||||||
|
|||||||
@@ -1370,8 +1370,10 @@ abd_raidz_gen_iterate(abd_t **cabds, abd_t *dabd,
|
|||||||
switch (parity) {
|
switch (parity) {
|
||||||
case 3:
|
case 3:
|
||||||
len = MIN(caiters[2].iter_mapsize, len);
|
len = MIN(caiters[2].iter_mapsize, len);
|
||||||
|
/* falls through */
|
||||||
case 2:
|
case 2:
|
||||||
len = MIN(caiters[1].iter_mapsize, len);
|
len = MIN(caiters[1].iter_mapsize, len);
|
||||||
|
/* falls through */
|
||||||
case 1:
|
case 1:
|
||||||
len = MIN(caiters[0].iter_mapsize, len);
|
len = MIN(caiters[0].iter_mapsize, len);
|
||||||
}
|
}
|
||||||
@@ -1461,9 +1463,11 @@ abd_raidz_rec_iterate(abd_t **cabds, abd_t **tabds,
|
|||||||
case 3:
|
case 3:
|
||||||
len = MIN(xiters[2].iter_mapsize, len);
|
len = MIN(xiters[2].iter_mapsize, len);
|
||||||
len = MIN(citers[2].iter_mapsize, len);
|
len = MIN(citers[2].iter_mapsize, len);
|
||||||
|
/* falls through */
|
||||||
case 2:
|
case 2:
|
||||||
len = MIN(xiters[1].iter_mapsize, len);
|
len = MIN(xiters[1].iter_mapsize, len);
|
||||||
len = MIN(citers[1].iter_mapsize, len);
|
len = MIN(citers[1].iter_mapsize, len);
|
||||||
|
/* falls through */
|
||||||
case 1:
|
case 1:
|
||||||
len = MIN(xiters[0].iter_mapsize, len);
|
len = MIN(xiters[0].iter_mapsize, len);
|
||||||
len = MIN(citers[0].iter_mapsize, len);
|
len = MIN(citers[0].iter_mapsize, len);
|
||||||
|
|||||||
+22
-12
@@ -21,7 +21,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2018, Joyent, Inc.
|
* Copyright (c) 2018, Joyent, Inc.
|
||||||
* Copyright (c) 2011, 2018 by Delphix. All rights reserved.
|
* Copyright (c) 2011, 2019 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2014 by Saso Kiselkov. All rights reserved.
|
* Copyright (c) 2014 by Saso Kiselkov. All rights reserved.
|
||||||
* Copyright 2017 Nexenta Systems, Inc. All rights reserved.
|
* Copyright 2017 Nexenta Systems, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
@@ -1872,7 +1872,8 @@ arc_buf_try_copy_decompressed_data(arc_buf_t *buf)
|
|||||||
* There were no decompressed bufs, so there should not be a
|
* There were no decompressed bufs, so there should not be a
|
||||||
* checksum on the hdr either.
|
* checksum on the hdr either.
|
||||||
*/
|
*/
|
||||||
EQUIV(!copied, hdr->b_l1hdr.b_freeze_cksum == NULL);
|
if (zfs_flags & ZFS_DEBUG_MODIFY)
|
||||||
|
EQUIV(!copied, hdr->b_l1hdr.b_freeze_cksum == NULL);
|
||||||
|
|
||||||
return (copied);
|
return (copied);
|
||||||
}
|
}
|
||||||
@@ -2253,7 +2254,6 @@ arc_buf_fill(arc_buf_t *buf, spa_t *spa, const zbookmark_phys_t *zb,
|
|||||||
*/
|
*/
|
||||||
if (arc_buf_try_copy_decompressed_data(buf)) {
|
if (arc_buf_try_copy_decompressed_data(buf)) {
|
||||||
/* Skip byteswapping and checksumming (already done) */
|
/* Skip byteswapping and checksumming (already done) */
|
||||||
ASSERT3P(hdr->b_l1hdr.b_freeze_cksum, !=, NULL);
|
|
||||||
return (0);
|
return (0);
|
||||||
} else {
|
} else {
|
||||||
error = zio_decompress_data(HDR_GET_COMPRESS(hdr),
|
error = zio_decompress_data(HDR_GET_COMPRESS(hdr),
|
||||||
@@ -4801,8 +4801,6 @@ arc_reduce_target_size(int64_t to_free)
|
|||||||
if (c > to_free && c - to_free > arc_c_min) {
|
if (c > to_free && c - to_free > arc_c_min) {
|
||||||
arc_c = c - to_free;
|
arc_c = c - to_free;
|
||||||
atomic_add_64(&arc_p, -(arc_p >> arc_shrink_shift));
|
atomic_add_64(&arc_p, -(arc_p >> arc_shrink_shift));
|
||||||
if (asize < arc_c)
|
|
||||||
arc_c = MAX(asize, arc_c_min);
|
|
||||||
if (arc_p > arc_c)
|
if (arc_p > arc_c)
|
||||||
arc_p = (arc_c >> 1);
|
arc_p = (arc_c >> 1);
|
||||||
ASSERT(arc_c >= arc_c_min);
|
ASSERT(arc_c >= arc_c_min);
|
||||||
@@ -5081,6 +5079,9 @@ arc_kmem_reap_soon(void)
|
|||||||
static boolean_t
|
static boolean_t
|
||||||
arc_adjust_cb_check(void *arg, zthr_t *zthr)
|
arc_adjust_cb_check(void *arg, zthr_t *zthr)
|
||||||
{
|
{
|
||||||
|
if (!arc_initialized)
|
||||||
|
return (B_FALSE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is necessary so that any changes which may have been made to
|
* This is necessary so that any changes which may have been made to
|
||||||
* many of the zfs_arc_* module parameters will be propagated to
|
* many of the zfs_arc_* module parameters will be propagated to
|
||||||
@@ -5168,6 +5169,9 @@ arc_adjust_cb(void *arg, zthr_t *zthr)
|
|||||||
static boolean_t
|
static boolean_t
|
||||||
arc_reap_cb_check(void *arg, zthr_t *zthr)
|
arc_reap_cb_check(void *arg, zthr_t *zthr)
|
||||||
{
|
{
|
||||||
|
if (!arc_initialized)
|
||||||
|
return (B_FALSE);
|
||||||
|
|
||||||
int64_t free_memory = arc_available_memory();
|
int64_t free_memory = arc_available_memory();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -5480,7 +5484,7 @@ static boolean_t
|
|||||||
arc_is_overflowing(void)
|
arc_is_overflowing(void)
|
||||||
{
|
{
|
||||||
/* Always allow at least one block of overflow */
|
/* Always allow at least one block of overflow */
|
||||||
uint64_t overflow = MAX(SPA_MAXBLOCKSIZE,
|
int64_t overflow = MAX(SPA_MAXBLOCKSIZE,
|
||||||
arc_c >> zfs_arc_overflow_shift);
|
arc_c >> zfs_arc_overflow_shift);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -5492,7 +5496,7 @@ arc_is_overflowing(void)
|
|||||||
* in the ARC. In practice, that's in the tens of MB, which is low
|
* in the ARC. In practice, that's in the tens of MB, which is low
|
||||||
* enough to be safe.
|
* enough to be safe.
|
||||||
*/
|
*/
|
||||||
return (aggsum_lower_bound(&arc_size) >= arc_c + overflow);
|
return (aggsum_lower_bound(&arc_size) >= (int64_t)arc_c + overflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
static abd_t *
|
static abd_t *
|
||||||
@@ -5608,7 +5612,7 @@ arc_get_data_impl(arc_buf_hdr_t *hdr, uint64_t size, void *tag)
|
|||||||
* If we are growing the cache, and we are adding anonymous
|
* If we are growing the cache, and we are adding anonymous
|
||||||
* data, and we have outgrown arc_p, update arc_p
|
* data, and we have outgrown arc_p, update arc_p
|
||||||
*/
|
*/
|
||||||
if (aggsum_compare(&arc_size, arc_c) < 0 &&
|
if (aggsum_upper_bound(&arc_size) < arc_c &&
|
||||||
hdr->b_l1hdr.b_state == arc_anon &&
|
hdr->b_l1hdr.b_state == arc_anon &&
|
||||||
(zfs_refcount_count(&arc_anon->arcs_size) +
|
(zfs_refcount_count(&arc_anon->arcs_size) +
|
||||||
zfs_refcount_count(&arc_mru->arcs_size) > arc_p))
|
zfs_refcount_count(&arc_mru->arcs_size) > arc_p))
|
||||||
@@ -7926,11 +7930,9 @@ arc_fini(void)
|
|||||||
|
|
||||||
list_destroy(&arc_prune_list);
|
list_destroy(&arc_prune_list);
|
||||||
mutex_destroy(&arc_prune_mtx);
|
mutex_destroy(&arc_prune_mtx);
|
||||||
(void) zthr_cancel(arc_adjust_zthr);
|
|
||||||
zthr_destroy(arc_adjust_zthr);
|
|
||||||
|
|
||||||
|
(void) zthr_cancel(arc_adjust_zthr);
|
||||||
(void) zthr_cancel(arc_reap_zthr);
|
(void) zthr_cancel(arc_reap_zthr);
|
||||||
zthr_destroy(arc_reap_zthr);
|
|
||||||
|
|
||||||
mutex_destroy(&arc_adjust_lock);
|
mutex_destroy(&arc_adjust_lock);
|
||||||
cv_destroy(&arc_adjust_waiters_cv);
|
cv_destroy(&arc_adjust_waiters_cv);
|
||||||
@@ -7943,6 +7945,14 @@ arc_fini(void)
|
|||||||
buf_fini();
|
buf_fini();
|
||||||
arc_state_fini();
|
arc_state_fini();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We destroy the zthrs after all the ARC state has been
|
||||||
|
* torn down to avoid the case of them receiving any
|
||||||
|
* wakeup() signals after they are destroyed.
|
||||||
|
*/
|
||||||
|
zthr_destroy(arc_adjust_zthr);
|
||||||
|
zthr_destroy(arc_reap_zthr);
|
||||||
|
|
||||||
ASSERT0(arc_loaned_bytes);
|
ASSERT0(arc_loaned_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8760,7 +8770,7 @@ l2arc_apply_transforms(spa_t *spa, arc_buf_hdr_t *hdr, uint64_t asize,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If this data simply needs its own buffer, we simply allocate it
|
* If this data simply needs its own buffer, we simply allocate it
|
||||||
* and copy the data. This may be done to elimiate a depedency on a
|
* and copy the data. This may be done to eliminate a dependency on a
|
||||||
* shared buffer or to reallocate the buffer to match asize.
|
* shared buffer or to reallocate the buffer to match asize.
|
||||||
*/
|
*/
|
||||||
if (HDR_HAS_RABD(hdr) && asize != psize) {
|
if (HDR_HAS_RABD(hdr) && asize != psize) {
|
||||||
|
|||||||
+2
-2
@@ -73,7 +73,7 @@ bqueue_enqueue(bqueue_t *q, void *data, uint64_t item_size)
|
|||||||
mutex_enter(&q->bq_lock);
|
mutex_enter(&q->bq_lock);
|
||||||
obj2node(q, data)->bqn_size = item_size;
|
obj2node(q, data)->bqn_size = item_size;
|
||||||
while (q->bq_size + item_size > q->bq_maxsize) {
|
while (q->bq_size + item_size > q->bq_maxsize) {
|
||||||
cv_wait(&q->bq_add_cv, &q->bq_lock);
|
cv_wait_sig(&q->bq_add_cv, &q->bq_lock);
|
||||||
}
|
}
|
||||||
q->bq_size += item_size;
|
q->bq_size += item_size;
|
||||||
list_insert_tail(&q->bq_list, data);
|
list_insert_tail(&q->bq_list, data);
|
||||||
@@ -91,7 +91,7 @@ bqueue_dequeue(bqueue_t *q)
|
|||||||
uint64_t item_size;
|
uint64_t item_size;
|
||||||
mutex_enter(&q->bq_lock);
|
mutex_enter(&q->bq_lock);
|
||||||
while (q->bq_size == 0) {
|
while (q->bq_size == 0) {
|
||||||
cv_wait(&q->bq_pop_cv, &q->bq_lock);
|
cv_wait_sig(&q->bq_pop_cv, &q->bq_lock);
|
||||||
}
|
}
|
||||||
ret = list_remove_head(&q->bq_list);
|
ret = list_remove_head(&q->bq_list);
|
||||||
ASSERT3P(ret, !=, NULL);
|
ASSERT3P(ret, !=, NULL);
|
||||||
|
|||||||
+2
-1
@@ -2591,7 +2591,8 @@ dbuf_destroy(dmu_buf_impl_t *db)
|
|||||||
if (db->db_blkid != DMU_BONUS_BLKID) {
|
if (db->db_blkid != DMU_BONUS_BLKID) {
|
||||||
boolean_t needlock = !MUTEX_HELD(&dn->dn_dbufs_mtx);
|
boolean_t needlock = !MUTEX_HELD(&dn->dn_dbufs_mtx);
|
||||||
if (needlock)
|
if (needlock)
|
||||||
mutex_enter(&dn->dn_dbufs_mtx);
|
mutex_enter_nested(&dn->dn_dbufs_mtx,
|
||||||
|
NESTED_SINGLE);
|
||||||
avl_remove(&dn->dn_dbufs, db);
|
avl_remove(&dn->dn_dbufs, db);
|
||||||
atomic_dec_32(&dn->dn_dbufs_count);
|
atomic_dec_32(&dn->dn_dbufs_count);
|
||||||
membar_producer();
|
membar_producer();
|
||||||
|
|||||||
+13
-1
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2018 by Delphix. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/zfs_context.h>
|
#include <sys/zfs_context.h>
|
||||||
@@ -117,7 +118,18 @@ ddt_zap_walk(objset_t *os, uint64_t object, ddt_entry_t *dde, uint64_t *walk)
|
|||||||
zap_attribute_t za;
|
zap_attribute_t za;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
zap_cursor_init_serialized(&zc, os, object, *walk);
|
if (*walk == 0) {
|
||||||
|
/*
|
||||||
|
* We don't want to prefetch the entire ZAP object, because
|
||||||
|
* it can be enormous. Also the primary use of DDT iteration
|
||||||
|
* is for scrubbing, in which case we will be issuing many
|
||||||
|
* scrub I/Os for each ZAP block that we read in, so
|
||||||
|
* reading the ZAP is unlikely to be the bottleneck.
|
||||||
|
*/
|
||||||
|
zap_cursor_init_noprefetch(&zc, os, object);
|
||||||
|
} else {
|
||||||
|
zap_cursor_init_serialized(&zc, os, object, *walk);
|
||||||
|
}
|
||||||
if ((error = zap_cursor_retrieve(&zc, &za)) == 0) {
|
if ((error = zap_cursor_retrieve(&zc, &za)) == 0) {
|
||||||
uchar_t cbuf[sizeof (dde->dde_phys) + 1];
|
uchar_t cbuf[sizeof (dde->dde_phys) + 1];
|
||||||
uint64_t csize = za.za_num_integers;
|
uint64_t csize = za.za_num_integers;
|
||||||
|
|||||||
+21
-30
@@ -81,6 +81,13 @@ int zfs_dmu_offset_next_sync = 0;
|
|||||||
*/
|
*/
|
||||||
int zfs_object_remap_one_indirect_delay_ms = 0;
|
int zfs_object_remap_one_indirect_delay_ms = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Limit the amount we can prefetch with one call to this amount. This
|
||||||
|
* helps to limit the amount of memory that can be used by prefetching.
|
||||||
|
* Larger objects should be prefetched a bit at a time.
|
||||||
|
*/
|
||||||
|
int dmu_prefetch_max = 8 * SPA_MAXBLOCKSIZE;
|
||||||
|
|
||||||
const dmu_object_type_info_t dmu_ot[DMU_OT_NUMTYPES] = {
|
const dmu_object_type_info_t dmu_ot[DMU_OT_NUMTYPES] = {
|
||||||
{DMU_BSWAP_UINT8, TRUE, FALSE, FALSE, "unallocated" },
|
{DMU_BSWAP_UINT8, TRUE, FALSE, FALSE, "unallocated" },
|
||||||
{DMU_BSWAP_ZAP, TRUE, TRUE, FALSE, "object directory" },
|
{DMU_BSWAP_ZAP, TRUE, TRUE, FALSE, "object directory" },
|
||||||
@@ -667,6 +674,11 @@ dmu_prefetch(objset_t *os, uint64_t object, int64_t level, uint64_t offset,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See comment before the definition of dmu_prefetch_max.
|
||||||
|
*/
|
||||||
|
len = MIN(len, dmu_prefetch_max);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX - Note, if the dnode for the requested object is not
|
* XXX - Note, if the dnode for the requested object is not
|
||||||
* already cached, we will do a *synchronous* read in the
|
* already cached, we will do a *synchronous* read in the
|
||||||
@@ -719,8 +731,8 @@ get_next_chunk(dnode_t *dn, uint64_t *start, uint64_t minimum, uint64_t *l1blks)
|
|||||||
uint64_t blks;
|
uint64_t blks;
|
||||||
uint64_t maxblks = DMU_MAX_ACCESS >> (dn->dn_indblkshift + 1);
|
uint64_t maxblks = DMU_MAX_ACCESS >> (dn->dn_indblkshift + 1);
|
||||||
/* bytes of data covered by a level-1 indirect block */
|
/* bytes of data covered by a level-1 indirect block */
|
||||||
uint64_t iblkrange =
|
uint64_t iblkrange = (uint64_t)dn->dn_datablksz *
|
||||||
dn->dn_datablksz * EPB(dn->dn_indblkshift, SPA_BLKPTRSHIFT);
|
EPB(dn->dn_indblkshift, SPA_BLKPTRSHIFT);
|
||||||
|
|
||||||
ASSERT3U(minimum, <=, *start);
|
ASSERT3U(minimum, <=, *start);
|
||||||
|
|
||||||
@@ -2373,39 +2385,14 @@ dmu_offset_next(objset_t *os, uint64_t object, boolean_t hole, uint64_t *off)
|
|||||||
return (err);
|
return (err);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if there are dirty data blocks or frees which have not been
|
* Check if dnode is dirty
|
||||||
* synced. Dirty spill and bonus blocks which are external to the
|
|
||||||
* object can ignored when reporting holes.
|
|
||||||
*/
|
*/
|
||||||
mutex_enter(&dn->dn_mtx);
|
|
||||||
for (i = 0; i < TXG_SIZE; i++) {
|
for (i = 0; i < TXG_SIZE; i++) {
|
||||||
if (multilist_link_active(&dn->dn_dirty_link[i])) {
|
if (multilist_link_active(&dn->dn_dirty_link[i])) {
|
||||||
|
clean = B_FALSE;
|
||||||
if (dn->dn_free_ranges[i] != NULL) {
|
|
||||||
clean = B_FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_t *list = &dn->dn_dirty_records[i];
|
|
||||||
dbuf_dirty_record_t *dr;
|
|
||||||
|
|
||||||
for (dr = list_head(list); dr != NULL;
|
|
||||||
dr = list_next(list, dr)) {
|
|
||||||
dmu_buf_impl_t *db = dr->dr_dbuf;
|
|
||||||
|
|
||||||
if (db->db_blkid == DMU_SPILL_BLKID ||
|
|
||||||
db->db_blkid == DMU_BONUS_BLKID)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
clean = B_FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clean == B_FALSE)
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mutex_exit(&dn->dn_mtx);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If compatibility option is on, sync any current changes before
|
* If compatibility option is on, sync any current changes before
|
||||||
@@ -2654,6 +2641,10 @@ module_param(zfs_dmu_offset_next_sync, int, 0644);
|
|||||||
MODULE_PARM_DESC(zfs_dmu_offset_next_sync,
|
MODULE_PARM_DESC(zfs_dmu_offset_next_sync,
|
||||||
"Enable forcing txg sync to find holes");
|
"Enable forcing txg sync to find holes");
|
||||||
|
|
||||||
|
module_param(dmu_prefetch_max, int, 0644);
|
||||||
|
MODULE_PARM_DESC(dmu_prefetch_max,
|
||||||
|
"Limit one prefetch call to this size");
|
||||||
|
|
||||||
/* END CSTYLED */
|
/* END CSTYLED */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user