mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-23 19:04:45 +03:00
Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d2632f0cc1 | |||
| e23ba78bd8 | |||
| bf75263ace | |||
| 5e245ab21b | |||
| 3df7f11322 | |||
| ae64398819 | |||
| 3275147c71 | |||
| 230970d368 | |||
| 79291065fc | |||
| 10c7a12f3b | |||
| 2acca5ec70 | |||
| e8baad51e0 | |||
| df03f21b54 | |||
| e8e68905c9 | |||
| c161360dce | |||
| a72ae9bf3d | |||
| 3e268f4934 | |||
| df01daab13 | |||
| 62278325a5 | |||
| 43186f94f4 | |||
| 76a1232ee7 | |||
| 0801e4e5c9 | |||
| fa612dd1fd | |||
| f78b6dbd5b | |||
| 88533ec59a | |||
| d2acd3696f | |||
| f6e54ea4f5 | |||
| c33b623535 | |||
| 42e9450831 | |||
| 70719549f0 | |||
| 2d2ce04b99 | |||
| 638edf1d42 | |||
| 04837c8dcb | |||
| 7b98b55282 | |||
| 88451845af | |||
| 4f5dcc9dc1 |
@@ -83,6 +83,7 @@ CONTRIBUTORS:
|
||||
Christopher Voltz <cjunk@voltz.ws>
|
||||
Chunwei Chen <david.chen@nutanix.com>
|
||||
Clemens Fruhwirth <clemens@endorphin.org>
|
||||
Coleman Kane <ckane@colemankane.org>
|
||||
Colin Ian King <colin.king@canonical.com>
|
||||
Craig Loomis <cloomis@astro.princeton.edu>
|
||||
Craig Sanders <github@taz.net.au>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Meta: 1
|
||||
Name: zfs
|
||||
Branch: 1.0
|
||||
Version: 0.8.4
|
||||
Version: 0.8.5
|
||||
Release: 1
|
||||
Release-Tags: relext
|
||||
License: CDDL
|
||||
|
||||
@@ -347,9 +347,8 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
||||
zpool_vdev_offline(zhp, devname, B_TRUE);
|
||||
} else if (!fmd_prop_get_int32(hdl, "spare_on_remove") ||
|
||||
replace_with_spare(hdl, zhp, vdev) == B_FALSE) {
|
||||
/* Could not handle with spare: offline the device */
|
||||
fmd_hdl_debug(hdl, "zpool_vdev_offline '%s'", devname);
|
||||
zpool_vdev_offline(zhp, devname, B_TRUE);
|
||||
/* Could not handle with spare */
|
||||
fmd_hdl_debug(hdl, "no spare for '%s'", devname);
|
||||
}
|
||||
|
||||
free(devname);
|
||||
|
||||
@@ -8620,9 +8620,9 @@ zpool_do_events_short(nvlist_t *nvl, ev_opts_t *opts)
|
||||
verify(nvlist_lookup_int64_array(nvl, FM_EREPORT_TIME, &tv, &n) == 0);
|
||||
memset(str, ' ', 32);
|
||||
(void) ctime_r((const time_t *)&tv[0], ctime_str);
|
||||
(void) strncpy(str, ctime_str+4, 6); /* 'Jun 30' */
|
||||
(void) strncpy(str+7, ctime_str+20, 4); /* '1993' */
|
||||
(void) strncpy(str+12, ctime_str+11, 8); /* '21:49:08' */
|
||||
(void) memcpy(str, ctime_str+4, 6); /* 'Jun 30' */
|
||||
(void) memcpy(str+7, ctime_str+20, 4); /* '1993' */
|
||||
(void) memcpy(str+12, ctime_str+11, 8); /* '21:49:08' */
|
||||
(void) sprintf(str+20, ".%09lld", (longlong_t)tv[1]); /* '.123456789' */
|
||||
if (opts->scripted)
|
||||
(void) printf(gettext("%s\t"), str);
|
||||
|
||||
@@ -6,6 +6,7 @@ dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH], [
|
||||
ZFS_LINUX_TEST_SRC([blkdev_get_by_path], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
blkdev_get_by_path(NULL, 0, NULL);
|
||||
])
|
||||
|
||||
@@ -5,6 +5,7 @@ dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART], [
|
||||
ZFS_LINUX_TEST_SRC([blkdev_reread_part], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
struct block_device *bdev = NULL;
|
||||
int error;
|
||||
|
||||
@@ -91,7 +91,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_DEBUG_LOCK_ALLOC], [
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC], [
|
||||
AC_MSG_CHECKING([whether mutex_lock() is GPL-only])
|
||||
ZFS_LINUX_TEST_RESULT([config_debug_lock_alloc], [
|
||||
ZFS_LINUX_TEST_RESULT([config_debug_lock_alloc_license], [
|
||||
AC_MSG_RESULT(no)
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
@@ -94,7 +94,6 @@ AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE_SANITY], [
|
||||
ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_FILE_PAGES])
|
||||
ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_INACTIVE_ANON])
|
||||
ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_INACTIVE_FILE])
|
||||
ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_SLAB_RECLAIMABLE])
|
||||
|
||||
AC_MSG_RESULT(yes)
|
||||
])
|
||||
@@ -117,8 +116,6 @@ AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE], [
|
||||
[node_stat_item], [$LINUX/include/linux/mmzone.h])
|
||||
ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_FILE],
|
||||
[node_stat_item], [$LINUX/include/linux/mmzone.h])
|
||||
ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE],
|
||||
[node_stat_item], [$LINUX/include/linux/mmzone.h])
|
||||
|
||||
ZFS_AC_KERNEL_ENUM_MEMBER([NR_FILE_PAGES],
|
||||
[zone_stat_item], [$LINUX/include/linux/mmzone.h])
|
||||
@@ -126,8 +123,6 @@ AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE], [
|
||||
[zone_stat_item], [$LINUX/include/linux/mmzone.h])
|
||||
ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_FILE],
|
||||
[zone_stat_item], [$LINUX/include/linux/mmzone.h])
|
||||
ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE],
|
||||
[zone_stat_item], [$LINUX/include/linux/mmzone.h])
|
||||
|
||||
ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE_SANITY
|
||||
])
|
||||
|
||||
@@ -5,6 +5,7 @@ dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_INVALIDATE_BDEV], [
|
||||
ZFS_LINUX_TEST_SRC([invalidate_bdev], [
|
||||
#include <linux/buffer_head.h>
|
||||
#include <linux/blkdev.h>
|
||||
],[
|
||||
struct block_device *bdev = NULL;
|
||||
invalidate_bdev(bdev);
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
dnl #
|
||||
dnl # 5.8 API,
|
||||
dnl # __vmalloc PAGE_KERNEL removal
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_VMALLOC_PAGE_KERNEL], [
|
||||
ZFS_LINUX_TEST_SRC([__vmalloc], [
|
||||
#include <linux/mm.h>
|
||||
#include <linux/vmalloc.h>
|
||||
],[
|
||||
void *p __attribute__ ((unused));
|
||||
|
||||
p = __vmalloc(0, GFP_KERNEL, PAGE_KERNEL);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_VMALLOC_PAGE_KERNEL], [
|
||||
AC_MSG_CHECKING([whether __vmalloc(ptr, flags, pageflags) is available])
|
||||
ZFS_LINUX_TEST_RESULT([__vmalloc], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_VMALLOC_PAGE_KERNEL, 1, [__vmalloc page flags exists])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
@@ -5,6 +5,7 @@ dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_LOOKUP_BDEV], [
|
||||
ZFS_LINUX_TEST_SRC([lookup_bdev_1arg], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
lookup_bdev(NULL);
|
||||
])
|
||||
|
||||
@@ -34,75 +34,96 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN], [
|
||||
struct request_queue *q __attribute__ ((unused));
|
||||
q = blk_alloc_queue(make_request, NUMA_NO_NODE);
|
||||
])
|
||||
|
||||
ZFS_LINUX_TEST_SRC([block_device_operations_submit_bio], [
|
||||
#include <linux/blkdev.h>
|
||||
],[
|
||||
struct block_device_operations o;
|
||||
o.submit_bio = NULL;
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
|
||||
dnl # Checked as part of the blk_alloc_queue_request_fn test
|
||||
dnl #
|
||||
dnl # Linux 5.7 API Change
|
||||
dnl # blk_alloc_queue() expects request function.
|
||||
dnl # Linux 5.9 API Change
|
||||
dnl # make_request_fn was moved into block_device_operations->submit_bio
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether blk_alloc_queue() expects request function])
|
||||
ZFS_LINUX_TEST_RESULT([blk_alloc_queue_request_fn], [
|
||||
AC_MSG_CHECKING([whether submit_bio is member of struct block_device_operations])
|
||||
ZFS_LINUX_TEST_RESULT([block_device_operations_submit_bio], [
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
AC_DEFINE(HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS, 1,
|
||||
[submit_bio is member of struct block_device_operations])
|
||||
],[
|
||||
dnl # Checked as part of the blk_alloc_queue_request_fn test
|
||||
AC_MSG_CHECKING([whether make_request_fn() returns blk_qc_t])
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
AC_DEFINE(HAVE_BLK_ALLOC_QUEUE_REQUEST_FN, 1,
|
||||
[blk_alloc_queue() expects request function])
|
||||
AC_DEFINE(MAKE_REQUEST_FN_RET, blk_qc_t,
|
||||
[make_request_fn() return type])
|
||||
AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_QC, 1,
|
||||
[Noting that make_request_fn() returns blk_qc_t])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
|
||||
dnl #
|
||||
dnl # Linux 3.2 API Change
|
||||
dnl # make_request_fn returns void.
|
||||
dnl # Linux 5.7 API Change
|
||||
dnl # blk_alloc_queue() expects request function.
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether make_request_fn() returns void])
|
||||
ZFS_LINUX_TEST_RESULT([make_request_fn_void], [
|
||||
AC_MSG_CHECKING([whether blk_alloc_queue() expects request function])
|
||||
ZFS_LINUX_TEST_RESULT([blk_alloc_queue_request_fn], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(MAKE_REQUEST_FN_RET, void,
|
||||
[make_request_fn() return type])
|
||||
AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_VOID, 1,
|
||||
[Noting that make_request_fn() returns void])
|
||||
|
||||
dnl # Checked as part of the blk_alloc_queue_request_fn test
|
||||
AC_MSG_CHECKING([whether make_request_fn() returns blk_qc_t])
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
AC_DEFINE(HAVE_BLK_ALLOC_QUEUE_REQUEST_FN, 1,
|
||||
[blk_alloc_queue() expects request function])
|
||||
AC_DEFINE(MAKE_REQUEST_FN_RET, blk_qc_t,
|
||||
[make_request_fn() return type])
|
||||
AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_QC, 1,
|
||||
[Noting that make_request_fn() returns blk_qc_t])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
|
||||
dnl #
|
||||
dnl # Linux 4.4 API Change
|
||||
dnl # make_request_fn returns blk_qc_t.
|
||||
dnl # Linux 3.2 API Change
|
||||
dnl # make_request_fn returns void.
|
||||
dnl #
|
||||
AC_MSG_CHECKING(
|
||||
[whether make_request_fn() returns blk_qc_t])
|
||||
ZFS_LINUX_TEST_RESULT([make_request_fn_blk_qc_t], [
|
||||
AC_MSG_CHECKING([whether make_request_fn() returns void])
|
||||
ZFS_LINUX_TEST_RESULT([make_request_fn_void], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(MAKE_REQUEST_FN_RET, blk_qc_t,
|
||||
[make_request_fn() return type])
|
||||
AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_QC, 1,
|
||||
[Noting that make_request_fn() ]
|
||||
[returns blk_qc_t])
|
||||
AC_DEFINE(MAKE_REQUEST_FN_RET, void,
|
||||
[make_request_fn() return type])
|
||||
AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_VOID, 1,
|
||||
[Noting that make_request_fn() returns void])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
|
||||
dnl #
|
||||
dnl # Legacy API
|
||||
dnl # make_request_fn returns int.
|
||||
dnl # Linux 4.4 API Change
|
||||
dnl # make_request_fn returns blk_qc_t.
|
||||
dnl #
|
||||
AC_MSG_CHECKING(
|
||||
[whether make_request_fn() returns int])
|
||||
ZFS_LINUX_TEST_RESULT([make_request_fn_int], [
|
||||
[whether make_request_fn() returns blk_qc_t])
|
||||
ZFS_LINUX_TEST_RESULT([make_request_fn_blk_qc_t], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(MAKE_REQUEST_FN_RET, int,
|
||||
[make_request_fn() return type])
|
||||
AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_INT,
|
||||
1, [Noting that make_request_fn() ]
|
||||
[returns int])
|
||||
AC_DEFINE(MAKE_REQUEST_FN_RET, blk_qc_t,
|
||||
[make_request_fn() return type])
|
||||
AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_QC, 1,
|
||||
[Noting that make_request_fn() ]
|
||||
[returns blk_qc_t])
|
||||
],[
|
||||
ZFS_LINUX_TEST_ERROR([make_request_fn])
|
||||
AC_MSG_RESULT(no)
|
||||
|
||||
dnl #
|
||||
dnl # Legacy API
|
||||
dnl # make_request_fn returns int.
|
||||
dnl #
|
||||
AC_MSG_CHECKING(
|
||||
[whether make_request_fn() returns int])
|
||||
ZFS_LINUX_TEST_RESULT([make_request_fn_int], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(MAKE_REQUEST_FN_RET, int,
|
||||
[make_request_fn() return type])
|
||||
AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_INT,
|
||||
1, [Noting that make_request_fn() ]
|
||||
[returns int])
|
||||
],[
|
||||
ZFS_LINUX_TEST_ERROR([make_request_fn])
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
@@ -6,10 +6,11 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_OBJTOOL], [
|
||||
dnl # 4.6 API for compile-time stack validation
|
||||
ZFS_LINUX_TEST_SRC([objtool], [
|
||||
#undef __ASSEMBLY__
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/frame.h>
|
||||
],[
|
||||
#if !defined(FRAME_BEGIN)
|
||||
CTASSERT(1);
|
||||
#error "FRAME_BEGIN is not defined"
|
||||
#endif
|
||||
])
|
||||
|
||||
@@ -18,7 +19,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_OBJTOOL], [
|
||||
#include <linux/frame.h>
|
||||
],[
|
||||
#if !defined(STACK_FRAME_NON_STANDARD)
|
||||
CTASSERT(1);
|
||||
#error "STACK_FRAME_NON_STANDARD is not defined."
|
||||
#endif
|
||||
])
|
||||
])
|
||||
|
||||
@@ -45,6 +45,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
|
||||
ZFS_AC_KERNEL_SRC_SCHED
|
||||
ZFS_AC_KERNEL_SRC_USLEEP_RANGE
|
||||
ZFS_AC_KERNEL_SRC_KMEM_CACHE
|
||||
ZFS_AC_KERNEL_SRC_VMALLOC_PAGE_KERNEL
|
||||
ZFS_AC_KERNEL_SRC_WAIT
|
||||
ZFS_AC_KERNEL_SRC_INODE_TIMES
|
||||
ZFS_AC_KERNEL_SRC_INODE_LOCK
|
||||
@@ -163,6 +164,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
|
||||
ZFS_AC_KERNEL_SCHED
|
||||
ZFS_AC_KERNEL_USLEEP_RANGE
|
||||
ZFS_AC_KERNEL_KMEM_CACHE
|
||||
ZFS_AC_KERNEL_VMALLOC_PAGE_KERNEL
|
||||
ZFS_AC_KERNEL_WAIT
|
||||
ZFS_AC_KERNEL_INODE_TIMES
|
||||
ZFS_AC_KERNEL_INODE_LOCK
|
||||
|
||||
@@ -38,8 +38,6 @@ do_fail() {
|
||||
is_known() {
|
||||
query="$1"
|
||||
IFS=' '
|
||||
# protect against special characters
|
||||
set -f
|
||||
for element in $2 ; do
|
||||
if [ "$query" = "$element" ] ; then
|
||||
return 0
|
||||
@@ -54,8 +52,7 @@ is_known() {
|
||||
create_dependencies() {
|
||||
unitfile="$1"
|
||||
suffix="$2"
|
||||
# protect against special characters
|
||||
set -f
|
||||
IFS=' '
|
||||
for target in $3 ; do
|
||||
target_dir="${dest_norm}/${target}.${suffix}/"
|
||||
mkdir -p "${target_dir}"
|
||||
@@ -72,6 +69,7 @@ else
|
||||
do_fail "zero or three arguments required"
|
||||
fi
|
||||
|
||||
pools=$(zpool list -H -o name || true)
|
||||
|
||||
# All needed information about each ZFS is available from
|
||||
# zfs list -H -t filesystem -o <properties>
|
||||
@@ -83,11 +81,11 @@ process_line() {
|
||||
# zfs list -H -o name,...
|
||||
# fields are tab separated
|
||||
IFS="$(printf '\t')"
|
||||
# protect against special characters in, e.g., mountpoints
|
||||
set -f
|
||||
# shellcheck disable=SC2086
|
||||
set -- $1
|
||||
|
||||
dataset="${1}"
|
||||
pool="${dataset%%/*}"
|
||||
p_mountpoint="${2}"
|
||||
p_canmount="${3}"
|
||||
p_atime="${4}"
|
||||
@@ -115,10 +113,30 @@ process_line() {
|
||||
wants="zfs-import.target"
|
||||
requires=""
|
||||
requiredmounts=""
|
||||
bindsto=""
|
||||
wantedby=""
|
||||
requiredby=""
|
||||
noauto="off"
|
||||
|
||||
# If the pool is already imported, zfs-import.target is not needed. This
|
||||
# avoids a dependency loop on root-on-ZFS systems:
|
||||
# systemd-random-seed.service After (via RequiresMountsFor) var-lib.mount
|
||||
# After zfs-import.target After zfs-import-{cache,scan}.service After
|
||||
# cryptsetup.service After systemd-random-seed.service.
|
||||
#
|
||||
# Pools are newline-separated and may contain spaces in their names.
|
||||
# There is no better portable way to set IFS to just a newline. Using
|
||||
# $(printf '\n') doesn't work because $(...) strips trailing newlines.
|
||||
IFS="
|
||||
"
|
||||
for p in $pools ; do
|
||||
if [ "$p" = "$pool" ] ; then
|
||||
after=""
|
||||
wants=""
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "${p_systemd_after}" ] && \
|
||||
[ "${p_systemd_after}" != "-" ] ; then
|
||||
after="${p_systemd_after} ${after}"
|
||||
@@ -172,6 +190,12 @@ set -eu;\
|
||||
keystatus=\"\$\$(@sbindir@/zfs get -H -o value keystatus \"${dataset}\")\";\
|
||||
[ \"\$\$keystatus\" = \"unavailable\" ] || exit 0;\
|
||||
${keyloadscript}'"
|
||||
keyunloadcmd="\
|
||||
/bin/sh -c '\
|
||||
set -eu;\
|
||||
keystatus=\"\$\$(@sbindir@/zfs get -H -o value keystatus \"${dataset}\")\";\
|
||||
[ \"\$\$keystatus\" = \"available\" ] || exit 0;\
|
||||
@sbindir@/zfs unload-key \"${dataset}\"'"
|
||||
|
||||
|
||||
|
||||
@@ -191,19 +215,23 @@ Documentation=man:zfs-mount-generator(8)
|
||||
DefaultDependencies=no
|
||||
Wants=${wants}
|
||||
After=${after}
|
||||
Before=${before}
|
||||
${requires}
|
||||
${keymountdep}
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
# This avoids a dependency loop involving systemd-journald.socket if this
|
||||
# dataset is a parent of the root filesystem.
|
||||
StandardOutput=null
|
||||
StandardError=null
|
||||
ExecStart=${keyloadcmd}
|
||||
ExecStop=@sbindir@/zfs unload-key '${dataset}'" > "${dest_norm}/${keyloadunit}"
|
||||
ExecStop=${keyunloadcmd}" > "${dest_norm}/${keyloadunit}"
|
||||
fi
|
||||
# Update the dependencies for the mount file to want the
|
||||
# key-loading unit.
|
||||
wants="${wants} ${keyloadunit}"
|
||||
wants="${wants}"
|
||||
bindsto="BindsTo=${keyloadunit}"
|
||||
after="${after} ${keyloadunit}"
|
||||
fi
|
||||
|
||||
@@ -414,6 +442,7 @@ Documentation=man:zfs-mount-generator(8)
|
||||
Before=${before}
|
||||
After=${after}
|
||||
Wants=${wants}
|
||||
${bindsto}
|
||||
${requires}
|
||||
${requiredmounts}
|
||||
|
||||
@@ -430,6 +459,8 @@ Options=defaults${opts},zfsutil" > "${dest_norm}/${mountfile}"
|
||||
}
|
||||
|
||||
for cachefile in "${FSLIST}/"* ; do
|
||||
# Disable glob expansion to protect against special characters when parsing.
|
||||
set -f
|
||||
# Sort cachefile's lines by canmount, "on" before "noauto"
|
||||
# and feed each line into process_line
|
||||
sort -t "$(printf '\t')" -k 3 -r "${cachefile}" | \
|
||||
|
||||
@@ -9,6 +9,7 @@ After=multipathd.target
|
||||
After=systemd-remount-fs.service
|
||||
Before=zfs-import.target
|
||||
ConditionPathExists=@sysconfdir@/zfs/zpool.cache
|
||||
ConditionPathIsDirectory=/sys/module/zfs
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
|
||||
@@ -8,6 +8,7 @@ After=cryptsetup.target
|
||||
After=multipathd.target
|
||||
Before=zfs-import.target
|
||||
ConditionPathExists=!@sysconfdir@/zfs/zpool.cache
|
||||
ConditionPathIsDirectory=/sys/module/zfs
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
|
||||
@@ -6,7 +6,7 @@ After=systemd-udev-settle.service
|
||||
After=zfs-import.target
|
||||
After=systemd-remount-fs.service
|
||||
Before=local-fs.target
|
||||
Before=systemd-random-seed.service
|
||||
ConditionPathIsDirectory=/sys/module/zfs
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
|
||||
@@ -669,6 +669,7 @@ blk_generic_end_io_acct(struct request_queue *q, int rw,
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS
|
||||
static inline struct request_queue *
|
||||
blk_generic_alloc_queue(make_request_fn make_request, int node_id)
|
||||
{
|
||||
@@ -682,5 +683,6 @@ blk_generic_alloc_queue(make_request_fn make_request, int node_id)
|
||||
return (q);
|
||||
#endif
|
||||
}
|
||||
#endif /* !HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS */
|
||||
|
||||
#endif /* _ZFS_BLKDEV_H */
|
||||
|
||||
@@ -35,11 +35,6 @@
|
||||
#else
|
||||
#define nr_inactive_file_pages() global_zone_page_state(NR_INACTIVE_FILE)
|
||||
#endif
|
||||
#if defined(ZFS_ENUM_NODE_STAT_ITEM_NR_SLAB_RECLAIMABLE)
|
||||
#define nr_slab_reclaimable_pages() global_node_page_state(NR_SLAB_RECLAIMABLE)
|
||||
#else
|
||||
#define nr_slab_reclaimable_pages() global_zone_page_state(NR_SLAB_RECLAIMABLE)
|
||||
#endif
|
||||
|
||||
#elif defined(ZFS_GLOBAL_NODE_PAGE_STATE)
|
||||
|
||||
@@ -59,11 +54,6 @@
|
||||
#else
|
||||
#define nr_inactive_file_pages() global_page_state(NR_INACTIVE_FILE)
|
||||
#endif
|
||||
#if defined(ZFS_ENUM_NODE_STAT_ITEM_NR_SLAB_RECLAIMABLE)
|
||||
#define nr_slab_reclaimable_pages() global_node_page_state(NR_SLAB_RECLAIMABLE)
|
||||
#else
|
||||
#define nr_slab_reclaimable_pages() global_page_state(NR_SLAB_RECLAIMABLE)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
@@ -71,7 +61,6 @@
|
||||
#define nr_file_pages() global_page_state(NR_FILE_PAGES)
|
||||
#define nr_inactive_anon_pages() global_page_state(NR_INACTIVE_ANON)
|
||||
#define nr_inactive_file_pages() global_page_state(NR_INACTIVE_FILE)
|
||||
#define nr_slab_reclaimable_pages() global_page_state(NR_SLAB_RECLAIMABLE)
|
||||
|
||||
#endif /* ZFS_GLOBAL_ZONE_PAGE_STATE */
|
||||
|
||||
|
||||
@@ -169,6 +169,15 @@ extern void *spl_kmem_alloc(size_t sz, int fl, const char *func, int line);
|
||||
extern void *spl_kmem_zalloc(size_t sz, int fl, const char *func, int line);
|
||||
extern void spl_kmem_free(const void *ptr, size_t sz);
|
||||
|
||||
/*
|
||||
* 5.8 API change, pgprot_t argument removed.
|
||||
*/
|
||||
#ifdef HAVE_VMALLOC_PAGE_KERNEL
|
||||
#define spl_vmalloc(size, flags) __vmalloc(size, flags, PAGE_KERNEL)
|
||||
#else
|
||||
#define spl_vmalloc(size, flags) __vmalloc(size, flags)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following functions are only available for internal use.
|
||||
*/
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define _SPL_MUTEX_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/lockdep.h>
|
||||
#include <linux/compiler_compat.h>
|
||||
|
||||
@@ -47,10 +47,6 @@
|
||||
|
||||
#define membar_producer() smp_wmb()
|
||||
#define physmem zfs_totalram_pages
|
||||
#define freemem (nr_free_pages() + \
|
||||
global_page_state(NR_INACTIVE_FILE) + \
|
||||
global_page_state(NR_INACTIVE_ANON) + \
|
||||
global_page_state(NR_SLAB_RECLAIMABLE))
|
||||
|
||||
#define xcopyin(from, to, size) copy_from_user(to, from, size)
|
||||
#define xcopyout(from, to, size) copy_to_user(to, from, size)
|
||||
|
||||
+1
-1
@@ -175,7 +175,7 @@ typedef struct ddt_ops {
|
||||
int (*ddt_op_count)(objset_t *os, uint64_t object, uint64_t *count);
|
||||
} ddt_ops_t;
|
||||
|
||||
#define DDT_NAMELEN 80
|
||||
#define DDT_NAMELEN 107
|
||||
|
||||
extern void ddt_object_name(ddt_t *ddt, enum ddt_type type,
|
||||
enum ddt_class class, char *name);
|
||||
|
||||
+2
-1
@@ -23,7 +23,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__KERNEL__) && defined(HAVE_STACK_FRAME_NON_STANDARD)
|
||||
#if defined(__KERNEL__) && defined(HAVE_KERNEL_OBJTOOL) && \
|
||||
defined(HAVE_STACK_FRAME_NON_STANDARD)
|
||||
#include <linux/frame.h>
|
||||
#else
|
||||
#define STACK_FRAME_NON_STANDARD(func)
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#endif /* MNTTAB */
|
||||
|
||||
#define MNTTAB "/proc/self/mounts"
|
||||
#define MNT_LINE_MAX 4096
|
||||
#define MNT_LINE_MAX 4108
|
||||
|
||||
#define MNT_TOOLONG 1 /* entry exceeds MNT_LINE_MAX */
|
||||
#define MNT_TOOMANY 2 /* too many fields in line */
|
||||
|
||||
@@ -8,7 +8,7 @@ VPATH = \
|
||||
# Suppress unused but set variable warnings often due to ASSERTs
|
||||
AM_CFLAGS += $(NO_UNUSED_BUT_SET_VARIABLE)
|
||||
|
||||
libzfs_pcdir = $(datarootdir)/pkgconfig
|
||||
libzfs_pcdir = $(libdir)/pkgconfig
|
||||
libzfs_pc_DATA = libzfs.pc libzfs_core.pc
|
||||
|
||||
DEFAULT_INCLUDES += \
|
||||
|
||||
@@ -330,7 +330,7 @@ aes_impl_init(void)
|
||||
sizeof (aes_fastest_impl));
|
||||
#endif
|
||||
|
||||
strcpy(aes_fastest_impl.name, "fastest");
|
||||
strlcpy(aes_fastest_impl.name, "fastest", AES_IMPL_NAME_MAX);
|
||||
|
||||
/* Finish initialization */
|
||||
atomic_swap_32(&icp_aes_impl, user_sel_impl);
|
||||
@@ -405,7 +405,7 @@ aes_impl_set(const char *val)
|
||||
return (err);
|
||||
}
|
||||
|
||||
#if defined(_KERNEL)
|
||||
#if defined(_KERNEL) && defined(__linux__)
|
||||
#include <linux/mod_compat.h>
|
||||
|
||||
static int
|
||||
|
||||
@@ -857,7 +857,7 @@ gcm_impl_init(void)
|
||||
sizeof (gcm_fastest_impl));
|
||||
}
|
||||
|
||||
strcpy(gcm_fastest_impl.name, "fastest");
|
||||
strlcpy(gcm_fastest_impl.name, "fastest", GCM_IMPL_NAME_MAX);
|
||||
|
||||
#ifdef CAN_USE_GCM_ASM
|
||||
/*
|
||||
@@ -969,7 +969,7 @@ gcm_impl_set(const char *val)
|
||||
return (err);
|
||||
}
|
||||
|
||||
#if defined(_KERNEL)
|
||||
#if defined(_KERNEL) && defined(__linux__)
|
||||
#include <linux/mod_compat.h>
|
||||
|
||||
static int
|
||||
|
||||
@@ -453,17 +453,19 @@ mod_hash_create_extended(
|
||||
int sleep) /* whether to sleep for mem */
|
||||
{
|
||||
mod_hash_t *mod_hash;
|
||||
size_t size;
|
||||
ASSERT(hname && keycmp && hash_alg && vdtor && kdtor);
|
||||
|
||||
if ((mod_hash = kmem_zalloc(MH_SIZE(nchains), sleep)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
mod_hash->mh_name = kmem_alloc(strlen(hname) + 1, sleep);
|
||||
size = strlen(hname) + 1;
|
||||
mod_hash->mh_name = kmem_alloc(size, sleep);
|
||||
if (mod_hash->mh_name == NULL) {
|
||||
kmem_free(mod_hash, MH_SIZE(nchains));
|
||||
return (NULL);
|
||||
}
|
||||
(void) strcpy(mod_hash->mh_name, hname);
|
||||
(void) strlcpy(mod_hash->mh_name, hname, size);
|
||||
|
||||
rw_init(&mod_hash->mh_contents, NULL, RW_DEFAULT, NULL);
|
||||
mod_hash->mh_sleep = sleep;
|
||||
|
||||
@@ -598,10 +598,12 @@ l_noret luaG_errormsg (lua_State *L) {
|
||||
|
||||
|
||||
l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
|
||||
L->runerror++;
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
addinfo(L, luaO_pushvfstring(L, fmt, argp));
|
||||
va_end(argp);
|
||||
luaG_errormsg(L);
|
||||
L->runerror--;
|
||||
}
|
||||
/* END CSTYLED */
|
||||
|
||||
+24
-1
@@ -29,6 +29,24 @@
|
||||
|
||||
|
||||
|
||||
/* Return the number of bytes available on the stack. */
|
||||
#if defined (_KERNEL) && defined(__linux__)
|
||||
#include <asm/current.h>
|
||||
static intptr_t stack_remaining(void) {
|
||||
char local;
|
||||
return (intptr_t)(&local - (char *)current->stack);
|
||||
}
|
||||
#elif defined (_KERNEL) && defined(__FreeBSD__)
|
||||
#include <sys/pcpu.h>
|
||||
static intptr_t stack_remaining(void) {
|
||||
char local;
|
||||
return (intptr_t)(&local - (char *)curthread->td_kstack);
|
||||
}
|
||||
#else
|
||||
static intptr_t stack_remaining(void) {
|
||||
return INTPTR_MAX;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
@@ -437,8 +455,13 @@ void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) {
|
||||
if (L->nCcalls == LUAI_MAXCCALLS)
|
||||
luaG_runerror(L, "C stack overflow");
|
||||
else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
|
||||
luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
|
||||
luaD_throw(L, LUA_ERRERR); /* error while handling stack error */
|
||||
}
|
||||
intptr_t remaining = stack_remaining();
|
||||
if (L->runerror == 0 && remaining < LUAI_MINCSTACK)
|
||||
luaG_runerror(L, "C stack overflow");
|
||||
if (L->runerror != 0 && remaining < LUAI_MINCSTACK / 2)
|
||||
luaD_throw(L, LUA_ERRERR); /* error while handling stack error */
|
||||
if (!allowyield) L->nny++;
|
||||
if (!luaD_precall(L, func, nResults)) /* is a Lua function? */
|
||||
luaV_execute(L); /* call it */
|
||||
|
||||
@@ -122,6 +122,12 @@ typedef LUAI_UACNUMBER l_uacNumber;
|
||||
#define LUAI_MAXCCALLS 20
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Minimum amount of available stack space (in bytes) to make a C call. With
|
||||
* gsub() recursion, the stack space between each luaD_call() is 1256 bytes.
|
||||
*/
|
||||
#define LUAI_MINCSTACK 4096
|
||||
|
||||
/*
|
||||
** maximum number of upvalues in a closure (both C and Lua). (Value
|
||||
** must fit in an unsigned char.)
|
||||
|
||||
@@ -214,6 +214,7 @@ static void preinit_state (lua_State *L, global_State *g) {
|
||||
L->nny = 1;
|
||||
L->status = LUA_OK;
|
||||
L->errfunc = 0;
|
||||
L->runerror = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -166,6 +166,7 @@ struct lua_State {
|
||||
unsigned short nCcalls; /* number of nested C calls */
|
||||
lu_byte hookmask;
|
||||
lu_byte allowhook;
|
||||
lu_byte runerror; /* handling a runtime error */
|
||||
int basehookcount;
|
||||
int hookcount;
|
||||
lua_Hook hook;
|
||||
|
||||
@@ -853,9 +853,9 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
|
||||
else if (*s == '\0' || iscntrl(uchar(*s))) {
|
||||
char buff[10];
|
||||
if (!isdigit(uchar(*(s+1))))
|
||||
sprintf(buff, "\\%d", (int)uchar(*s));
|
||||
snprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s));
|
||||
else
|
||||
sprintf(buff, "\\%03d", (int)uchar(*s));
|
||||
snprintf(buff, sizeof(buff), "\\%03d", (int)uchar(*s));
|
||||
luaL_addstring(b, buff);
|
||||
}
|
||||
else
|
||||
@@ -890,11 +890,11 @@ static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
|
||||
/*
|
||||
** add length modifier into formats
|
||||
*/
|
||||
static void addlenmod (char *form, const char *lenmod) {
|
||||
static void addlenmod (char *form, const char *lenmod, size_t size) {
|
||||
size_t l = strlen(form);
|
||||
size_t lm = strlen(lenmod);
|
||||
char spec = form[l - 1];
|
||||
strcpy(form + l - 1, lenmod);
|
||||
strlcpy(form + l - 1, lenmod, size - (l - 1));
|
||||
form[l + lm - 1] = spec;
|
||||
form[l + lm] = '\0';
|
||||
}
|
||||
@@ -931,7 +931,7 @@ static int str_format (lua_State *L) {
|
||||
lua_Number diff = n - (lua_Number)ni;
|
||||
luaL_argcheck(L, -1 < diff && diff < 1, arg,
|
||||
"not a number in proper range");
|
||||
addlenmod(form, LUA_INTFRMLEN);
|
||||
addlenmod(form, LUA_INTFRMLEN, MAX_FORMAT);
|
||||
nb = str_sprintf(buff, form, ni);
|
||||
break;
|
||||
}
|
||||
@@ -941,7 +941,7 @@ static int str_format (lua_State *L) {
|
||||
lua_Number diff = n - (lua_Number)ni;
|
||||
luaL_argcheck(L, -1 < diff && diff < 1, arg,
|
||||
"not a non-negative number in proper range");
|
||||
addlenmod(form, LUA_INTFRMLEN);
|
||||
addlenmod(form, LUA_INTFRMLEN, MAX_FORMAT);
|
||||
nb = str_sprintf(buff, form, ni);
|
||||
break;
|
||||
}
|
||||
@@ -951,7 +951,7 @@ static int str_format (lua_State *L) {
|
||||
case 'a': case 'A':
|
||||
#endif
|
||||
case 'g': case 'G': {
|
||||
addlenmod(form, LUA_FLTFRMLEN);
|
||||
addlenmod(form, LUA_FLTFRMLEN, MAX_FORMAT);
|
||||
nb = str_sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -929,32 +929,4 @@ void luaV_execute (lua_State *L) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* this can live in SPL
|
||||
*/
|
||||
#if BITS_PER_LONG == 32
|
||||
#if defined(_KERNEL) && !defined(SPL_HAS_MODDI3)
|
||||
extern uint64_t __umoddi3(uint64_t dividend, uint64_t divisor);
|
||||
|
||||
/* 64-bit signed modulo for 32-bit machines. */
|
||||
int64_t
|
||||
__moddi3(int64_t n, int64_t d)
|
||||
{
|
||||
int64_t q;
|
||||
boolean_t nn = B_FALSE;
|
||||
|
||||
if (n < 0) {
|
||||
nn = B_TRUE;
|
||||
n = -n;
|
||||
}
|
||||
if (d < 0)
|
||||
d = -d;
|
||||
|
||||
q = __umoddi3(n, d);
|
||||
|
||||
return (nn ? -q : q);
|
||||
}
|
||||
EXPORT_SYMBOL(__moddi3);
|
||||
#endif
|
||||
#endif
|
||||
/* END CSTYLED */
|
||||
|
||||
@@ -31,12 +31,19 @@
|
||||
|
||||
#if defined(__arm__) && !defined(__aarch64__)
|
||||
|
||||
#if defined(__thumb2__)
|
||||
#define _FUNC_MODE .code 16; .thumb_func
|
||||
#else
|
||||
#define _FUNC_MODE .code 32
|
||||
#endif
|
||||
|
||||
#define ENTRY(x) \
|
||||
.text; \
|
||||
.syntax unified; \
|
||||
.align 2; \
|
||||
.global x; \
|
||||
.type x,#function; \
|
||||
.code 32; \
|
||||
_FUNC_MODE; \
|
||||
x:
|
||||
|
||||
#define END(x) \
|
||||
@@ -49,13 +56,23 @@ x:
|
||||
* setjump + longjmp
|
||||
*/
|
||||
ENTRY(setjmp)
|
||||
#if defined(__thumb2__)
|
||||
mov ip, sp
|
||||
stmia r0, {r4-r12,r14}
|
||||
#else
|
||||
stmia r0, {r4-r14}
|
||||
#endif
|
||||
mov r0, #0x00000000
|
||||
RET
|
||||
END(setjmp)
|
||||
|
||||
ENTRY(longjmp)
|
||||
#if defined(__thumb2__)
|
||||
ldmia r0, {r4-r12,r14}
|
||||
mov sp, ip
|
||||
#else
|
||||
ldmia r0, {r4-r14}
|
||||
#endif
|
||||
mov r0, #0x00000001
|
||||
RET
|
||||
END(longjmp)
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
#define ENTRY(name) \
|
||||
.align 2 ; \
|
||||
.type name,@function; \
|
||||
.globl name; \
|
||||
.weak name; \
|
||||
name:
|
||||
|
||||
#else /* PPC64_ELF_ABI_v1 */
|
||||
@@ -65,8 +65,8 @@ name:
|
||||
#define GLUE(a,b) XGLUE(a,b)
|
||||
#define ENTRY(name) \
|
||||
.align 2 ; \
|
||||
.globl name; \
|
||||
.globl GLUE(.,name); \
|
||||
.weak name; \
|
||||
.weak GLUE(.,name); \
|
||||
.pushsection ".opd","aw"; \
|
||||
name: \
|
||||
.quad GLUE(.,name); \
|
||||
@@ -83,8 +83,8 @@ GLUE(.,name):
|
||||
#define ENTRY(name) \
|
||||
.text; \
|
||||
.p2align 4; \
|
||||
.globl name; \
|
||||
.type name,@function; \
|
||||
.weak name; \
|
||||
.type name,@function; \
|
||||
name:
|
||||
|
||||
#endif /* __powerpc64__ */
|
||||
|
||||
@@ -170,6 +170,7 @@ random_get_pseudo_bytes(uint8_t *ptr, size_t len)
|
||||
EXPORT_SYMBOL(random_get_pseudo_bytes);
|
||||
|
||||
#if BITS_PER_LONG == 32
|
||||
|
||||
/*
|
||||
* Support 64/64 => 64 division on a 32-bit platform. While the kernel
|
||||
* provides a div64_u64() function for this we do not use it because the
|
||||
@@ -216,6 +217,14 @@ __div_u64(uint64_t u, uint32_t v)
|
||||
return (u);
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn off missing prototypes warning for these functions. They are
|
||||
* replacements for libgcc-provided functions and will never be called
|
||||
* directly.
|
||||
*/
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
/*
|
||||
* Implementation of 64-bit unsigned division for 32-bit machines.
|
||||
*
|
||||
@@ -291,6 +300,26 @@ __umoddi3(uint64_t dividend, uint64_t divisor)
|
||||
}
|
||||
EXPORT_SYMBOL(__umoddi3);
|
||||
|
||||
/* 64-bit signed modulo for 32-bit machines. */
|
||||
int64_t
|
||||
__moddi3(int64_t n, int64_t d)
|
||||
{
|
||||
int64_t q;
|
||||
boolean_t nn = B_FALSE;
|
||||
|
||||
if (n < 0) {
|
||||
nn = B_TRUE;
|
||||
n = -n;
|
||||
}
|
||||
if (d < 0)
|
||||
d = -d;
|
||||
|
||||
q = __umoddi3(n, d);
|
||||
|
||||
return (nn ? -q : q);
|
||||
}
|
||||
EXPORT_SYMBOL(__moddi3);
|
||||
|
||||
/*
|
||||
* Implementation of 64-bit unsigned division/modulo for 32-bit machines.
|
||||
*/
|
||||
@@ -394,6 +423,9 @@ __aeabi_ldivmod(int64_t u, int64_t v)
|
||||
}
|
||||
EXPORT_SYMBOL(__aeabi_ldivmod);
|
||||
#endif /* __arm || __arm__ */
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#endif /* BITS_PER_LONG */
|
||||
|
||||
/*
|
||||
|
||||
@@ -203,7 +203,7 @@ kv_alloc(spl_kmem_cache_t *skc, int size, int flags)
|
||||
ASSERT(ISP2(size));
|
||||
ptr = (void *)__get_free_pages(lflags, get_order(size));
|
||||
} else {
|
||||
ptr = __vmalloc(size, lflags | __GFP_HIGHMEM, PAGE_KERNEL);
|
||||
ptr = spl_vmalloc(size, lflags | __GFP_HIGHMEM);
|
||||
}
|
||||
|
||||
/* Resulting allocated memory will be page aligned */
|
||||
@@ -1242,7 +1242,7 @@ spl_cache_grow(spl_kmem_cache_t *skc, int flags, void **obj)
|
||||
* allocation.
|
||||
*
|
||||
* However, this can't be applied to KVM_VMEM due to a bug that
|
||||
* __vmalloc() doesn't honor gfp flags in page table allocation.
|
||||
* spl_vmalloc() doesn't honor gfp flags in page table allocation.
|
||||
*/
|
||||
if (!(skc->skc_flags & KMC_VMEM)) {
|
||||
rc = __spl_cache_grow(skc, flags | KM_NOSLEEP);
|
||||
|
||||
@@ -172,16 +172,15 @@ spl_kmem_alloc_impl(size_t size, int flags, int node)
|
||||
* kmem_zalloc() callers.
|
||||
*
|
||||
* For vmem_alloc() and vmem_zalloc() callers it is permissible
|
||||
* to use __vmalloc(). However, in general use of __vmalloc()
|
||||
* is strongly discouraged because a global lock must be
|
||||
* acquired. Contention on this lock can significantly
|
||||
* to use spl_vmalloc(). However, in general use of
|
||||
* spl_vmalloc() is strongly discouraged because a global lock
|
||||
* must be acquired. Contention on this lock can significantly
|
||||
* impact performance so frequently manipulating the virtual
|
||||
* address space is strongly discouraged.
|
||||
*/
|
||||
if ((size > spl_kmem_alloc_max) || use_vmem) {
|
||||
if (flags & KM_VMEM) {
|
||||
ptr = __vmalloc(size, lflags | __GFP_HIGHMEM,
|
||||
PAGE_KERNEL);
|
||||
ptr = spl_vmalloc(size, lflags | __GFP_HIGHMEM);
|
||||
} else {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,17 @@ procfs_list_next_node(procfs_list_cursor_t *cursor, loff_t *pos)
|
||||
cursor->cached_node = next_node;
|
||||
cursor->cached_pos = NODE_ID(procfs_list, cursor->cached_node);
|
||||
*pos = cursor->cached_pos;
|
||||
} else {
|
||||
/*
|
||||
* seq_read() expects ->next() to update the position even
|
||||
* when there are no more entries. Advance the position to
|
||||
* prevent a warning from being logged.
|
||||
*/
|
||||
cursor->cached_node = NULL;
|
||||
cursor->cached_pos++;
|
||||
*pos = cursor->cached_pos;
|
||||
}
|
||||
|
||||
return (next_node);
|
||||
}
|
||||
|
||||
@@ -105,6 +115,8 @@ procfs_list_seq_start(struct seq_file *f, loff_t *pos)
|
||||
cursor->cached_node = SEQ_START_TOKEN;
|
||||
cursor->cached_pos = 0;
|
||||
return (SEQ_START_TOKEN);
|
||||
} else if (cursor->cached_node == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+3
-4
@@ -4859,8 +4859,7 @@ arc_free_memory(void)
|
||||
#else
|
||||
return (ptob(nr_free_pages() +
|
||||
nr_inactive_file_pages() +
|
||||
nr_inactive_anon_pages() +
|
||||
nr_slab_reclaimable_pages()));
|
||||
nr_inactive_anon_pages()));
|
||||
|
||||
#endif /* CONFIG_HIGHMEM */
|
||||
#else
|
||||
@@ -7879,8 +7878,8 @@ arc_init(void)
|
||||
offsetof(arc_prune_t, p_node));
|
||||
mutex_init(&arc_prune_mtx, NULL, MUTEX_DEFAULT, NULL);
|
||||
|
||||
arc_prune_taskq = taskq_create("arc_prune", max_ncpus, defclsyspri,
|
||||
max_ncpus, INT_MAX, TASKQ_PREPOPULATE | TASKQ_DYNAMIC);
|
||||
arc_prune_taskq = taskq_create("arc_prune", boot_ncpus, defclsyspri,
|
||||
boot_ncpus, INT_MAX, TASKQ_PREPOPULATE | TASKQ_DYNAMIC);
|
||||
|
||||
arc_ksp = kstat_create("zfs", 0, "arcstats", "misc", KSTAT_TYPE_NAMED,
|
||||
sizeof (arc_stats) / sizeof (kstat_named_t), KSTAT_FLAG_VIRTUAL);
|
||||
|
||||
+1
-1
@@ -253,7 +253,7 @@ void
|
||||
ddt_object_name(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
|
||||
char *name)
|
||||
{
|
||||
(void) sprintf(name, DMU_POOL_DDT,
|
||||
(void) snprintf(name, DDT_NAMELEN, DMU_POOL_DDT,
|
||||
zio_checksum_table[ddt->ddt_checksum].ci_name,
|
||||
ddt_ops[type]->ddt_op_name, ddt_class_name[class]);
|
||||
}
|
||||
|
||||
@@ -2623,6 +2623,7 @@ EXPORT_SYMBOL(dmu_object_set_blocksize);
|
||||
EXPORT_SYMBOL(dmu_object_set_maxblkid);
|
||||
EXPORT_SYMBOL(dmu_object_set_checksum);
|
||||
EXPORT_SYMBOL(dmu_object_set_compress);
|
||||
EXPORT_SYMBOL(dmu_offset_next);
|
||||
EXPORT_SYMBOL(dmu_write_policy);
|
||||
EXPORT_SYMBOL(dmu_sync);
|
||||
EXPORT_SYMBOL(dmu_request_arcbuf);
|
||||
|
||||
@@ -1967,14 +1967,15 @@ do_userquota_update(objset_t *os, userquota_cache_t *cache, uint64_t used,
|
||||
if (subtract)
|
||||
delta = -delta;
|
||||
|
||||
(void) sprintf(name, "%llx", (longlong_t)user);
|
||||
(void) snprintf(name, sizeof (name), "%llx", (longlong_t)user);
|
||||
userquota_update_cache(&cache->uqc_user_deltas, name, delta);
|
||||
|
||||
(void) sprintf(name, "%llx", (longlong_t)group);
|
||||
(void) snprintf(name, sizeof (name), "%llx", (longlong_t)group);
|
||||
userquota_update_cache(&cache->uqc_group_deltas, name, delta);
|
||||
|
||||
if (dmu_objset_projectquota_enabled(os)) {
|
||||
(void) sprintf(name, "%llx", (longlong_t)project);
|
||||
(void) snprintf(name, sizeof (name), "%llx",
|
||||
(longlong_t)project);
|
||||
userquota_update_cache(&cache->uqc_project_deltas,
|
||||
name, delta);
|
||||
}
|
||||
@@ -2537,7 +2538,7 @@ dmu_snapshot_list_next(objset_t *os, int namelen, char *name,
|
||||
return (SET_ERROR(ENAMETOOLONG));
|
||||
}
|
||||
|
||||
(void) strcpy(name, attr.za_name);
|
||||
(void) strlcpy(name, attr.za_name, namelen);
|
||||
if (idp)
|
||||
*idp = attr.za_first_integer;
|
||||
if (case_conflict)
|
||||
@@ -2582,7 +2583,7 @@ dmu_dir_list_next(objset_t *os, int namelen, char *name,
|
||||
return (SET_ERROR(ENAMETOOLONG));
|
||||
}
|
||||
|
||||
(void) strcpy(name, attr.za_name);
|
||||
(void) strlcpy(name, attr.za_name, namelen);
|
||||
if (idp)
|
||||
*idp = attr.za_first_integer;
|
||||
zap_cursor_advance(&cursor);
|
||||
|
||||
@@ -846,7 +846,7 @@ void
|
||||
dsl_dataset_name(dsl_dataset_t *ds, char *name)
|
||||
{
|
||||
if (ds == NULL) {
|
||||
(void) strcpy(name, "mos");
|
||||
(void) strlcpy(name, "mos", ZFS_MAX_DATASET_NAME_LEN);
|
||||
} else {
|
||||
dsl_dir_name(ds->ds_dir, name);
|
||||
VERIFY0(dsl_dataset_get_snapname(ds));
|
||||
@@ -2161,9 +2161,12 @@ get_receive_resume_stats_impl(dsl_dataset_t *ds)
|
||||
zio_cksum_t cksum;
|
||||
fletcher_4_native_varsize(compressed, compressed_size, &cksum);
|
||||
|
||||
str = kmem_alloc(compressed_size * 2 + 1, KM_SLEEP);
|
||||
size_t alloc_size = compressed_size * 2 + 1;
|
||||
str = kmem_alloc(alloc_size, KM_SLEEP);
|
||||
for (int i = 0; i < compressed_size; i++) {
|
||||
(void) sprintf(str + i * 2, "%02x", compressed[i]);
|
||||
size_t offset = i * 2;
|
||||
(void) snprintf(str + offset, alloc_size - offset,
|
||||
"%02x", compressed[i]);
|
||||
}
|
||||
str[compressed_size * 2] = '\0';
|
||||
char *propval = kmem_asprintf("%u-%llx-%llx-%s",
|
||||
@@ -2171,7 +2174,7 @@ get_receive_resume_stats_impl(dsl_dataset_t *ds)
|
||||
(longlong_t)cksum.zc_word[0],
|
||||
(longlong_t)packed_size, str);
|
||||
kmem_free(packed, packed_size);
|
||||
kmem_free(str, compressed_size * 2 + 1);
|
||||
kmem_free(str, alloc_size);
|
||||
kmem_free(compressed, packed_size);
|
||||
return (propval);
|
||||
}
|
||||
@@ -3573,7 +3576,8 @@ dsl_dataset_promote(const char *name, char *conflsnap)
|
||||
*/
|
||||
snap_pair = nvlist_next_nvpair(ddpa.err_ds, NULL);
|
||||
if (snap_pair != NULL && conflsnap != NULL)
|
||||
(void) strcpy(conflsnap, nvpair_name(snap_pair));
|
||||
(void) strlcpy(conflsnap, nvpair_name(snap_pair),
|
||||
ZFS_MAX_DATASET_NAME_LEN);
|
||||
|
||||
fnvlist_free(ddpa.err_ds);
|
||||
return (error);
|
||||
|
||||
@@ -234,7 +234,8 @@ dsl_dir_hold_obj(dsl_pool_t *dp, uint64_t ddobj,
|
||||
if (err != 0)
|
||||
goto errout;
|
||||
} else {
|
||||
(void) strcpy(dd->dd_myname, spa_name(dp->dp_spa));
|
||||
(void) strlcpy(dd->dd_myname, spa_name(dp->dp_spa),
|
||||
sizeof (dd->dd_myname));
|
||||
}
|
||||
|
||||
if (dsl_dir_is_clone(dd)) {
|
||||
@@ -394,7 +395,7 @@ getcomponent(const char *path, char *component, const char **nextp)
|
||||
return (SET_ERROR(EINVAL));
|
||||
if (strlen(path) >= ZFS_MAX_DATASET_NAME_LEN)
|
||||
return (SET_ERROR(ENAMETOOLONG));
|
||||
(void) strcpy(component, path);
|
||||
(void) strlcpy(component, path, ZFS_MAX_DATASET_NAME_LEN);
|
||||
p = NULL;
|
||||
} else if (p[0] == '/') {
|
||||
if (p - path >= ZFS_MAX_DATASET_NAME_LEN)
|
||||
|
||||
@@ -222,9 +222,9 @@ dsl_pool_open_impl(spa_t *spa, uint64_t txg)
|
||||
cv_init(&dp->dp_spaceavail_cv, NULL, CV_DEFAULT, NULL);
|
||||
|
||||
dp->dp_iput_taskq = taskq_create("z_iput", max_ncpus, defclsyspri,
|
||||
max_ncpus * 8, INT_MAX, TASKQ_PREPOPULATE | TASKQ_DYNAMIC);
|
||||
boot_ncpus * 8, INT_MAX, TASKQ_PREPOPULATE | TASKQ_DYNAMIC);
|
||||
dp->dp_unlinked_drain_taskq = taskq_create("z_unlinked_drain",
|
||||
max_ncpus, defclsyspri, max_ncpus, INT_MAX,
|
||||
boot_ncpus, defclsyspri, boot_ncpus, INT_MAX,
|
||||
TASKQ_PREPOPULATE | TASKQ_DYNAMIC);
|
||||
|
||||
return (dp);
|
||||
|
||||
@@ -130,8 +130,9 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
|
||||
if (inheriting) {
|
||||
dsl_dir_name(dd, setpoint);
|
||||
} else {
|
||||
(void) strcpy(setpoint,
|
||||
ZPROP_SOURCE_VAL_RECVD);
|
||||
(void) strlcpy(setpoint,
|
||||
ZPROP_SOURCE_VAL_RECVD,
|
||||
MAXNAMELEN);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -204,8 +205,9 @@ dsl_prop_get_ds(dsl_dataset_t *ds, const char *propname,
|
||||
strfree(recvdstr);
|
||||
if (err != ENOENT) {
|
||||
if (setpoint != NULL && err == 0)
|
||||
(void) strcpy(setpoint,
|
||||
ZPROP_SOURCE_VAL_RECVD);
|
||||
(void) strlcpy(setpoint,
|
||||
ZPROP_SOURCE_VAL_RECVD,
|
||||
MAXNAMELEN);
|
||||
return (err);
|
||||
}
|
||||
}
|
||||
|
||||
+23
-2
@@ -358,7 +358,7 @@ scan_init(void)
|
||||
for (int i = 0; i < SPA_DVAS_PER_BP; i++) {
|
||||
char name[36];
|
||||
|
||||
(void) sprintf(name, "sio_cache_%d", i);
|
||||
(void) snprintf(name, sizeof (name), "sio_cache_%d", i);
|
||||
sio_cache[i] = kmem_cache_create(name,
|
||||
(sizeof (scan_io_t) + ((i + 1) * sizeof (dva_t))),
|
||||
0, NULL, NULL, NULL, NULL, NULL, 0);
|
||||
@@ -540,6 +540,22 @@ dsl_scan_init(dsl_pool_t *dp, uint64_t txg)
|
||||
zfs_dbgmsg("new-style scrub was modified "
|
||||
"by old software; restarting in txg %llu",
|
||||
(longlong_t)scn->scn_restart_txg);
|
||||
} else if (dsl_scan_resilvering(dp)) {
|
||||
/*
|
||||
* If a resilver is in progress and there are already
|
||||
* errors, restart it instead of finishing this scan and
|
||||
* then restarting it. If there haven't been any errors
|
||||
* then remember that the incore DTL is valid.
|
||||
*/
|
||||
if (scn->scn_phys.scn_errors > 0) {
|
||||
scn->scn_restart_txg = txg;
|
||||
zfs_dbgmsg("resilver can't excise DTL_MISSING "
|
||||
"when finished; restarting in txg %llu",
|
||||
(u_longlong_t)scn->scn_restart_txg);
|
||||
} else {
|
||||
/* it's safe to excise DTL when finished */
|
||||
spa->spa_scrub_started = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -881,7 +897,6 @@ dsl_scan_done(dsl_scan_t *scn, boolean_t complete, dmu_tx_t *tx)
|
||||
"errors=%llu", spa_get_errlog_size(spa));
|
||||
|
||||
if (DSL_SCAN_IS_SCRUB_RESILVER(scn)) {
|
||||
spa->spa_scrub_started = B_FALSE;
|
||||
spa->spa_scrub_active = B_FALSE;
|
||||
|
||||
/*
|
||||
@@ -908,6 +923,12 @@ dsl_scan_done(dsl_scan_t *scn, boolean_t complete, dmu_tx_t *tx)
|
||||
}
|
||||
spa_errlog_rotate(spa);
|
||||
|
||||
/*
|
||||
* Don't clear flag until after vdev_dtl_reassess to ensure that
|
||||
* DTL_MISSING will get updated when possible.
|
||||
*/
|
||||
spa->spa_scrub_started = B_FALSE;
|
||||
|
||||
/*
|
||||
* We may have finished replacing a device.
|
||||
* Let the async thread assess this and handle the detach.
|
||||
|
||||
@@ -101,9 +101,9 @@ dsl_dataset_user_hold_check(void *arg, dmu_tx_t *tx)
|
||||
size_t len = strlen(nvpair_name(pair)) +
|
||||
strlen(fnvpair_value_string(pair));
|
||||
char *nameval = kmem_zalloc(len + 2, KM_SLEEP);
|
||||
(void) strcpy(nameval, nvpair_name(pair));
|
||||
(void) strcat(nameval, "@");
|
||||
(void) strcat(nameval, fnvpair_value_string(pair));
|
||||
(void) strlcpy(nameval, nvpair_name(pair), len + 2);
|
||||
(void) strlcat(nameval, "@", len + 2);
|
||||
(void) strlcat(nameval, fnvpair_value_string(pair), len + 2);
|
||||
fnvlist_add_string(tmp_holds, nameval, "");
|
||||
kmem_free(nameval, len + 2);
|
||||
}
|
||||
|
||||
+12
-8
@@ -198,14 +198,6 @@ mmp_init(spa_t *spa)
|
||||
cv_init(&mmp->mmp_thread_cv, NULL, CV_DEFAULT, NULL);
|
||||
mutex_init(&mmp->mmp_io_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||
mmp->mmp_kstat_id = 1;
|
||||
|
||||
/*
|
||||
* mmp_write_done() calculates mmp_delay based on prior mmp_delay and
|
||||
* the elapsed time since the last write. For the first mmp write,
|
||||
* there is no "last write", so we start with fake non-zero values.
|
||||
*/
|
||||
mmp->mmp_last_write = gethrtime();
|
||||
mmp->mmp_delay = MSEC2NSEC(MMP_INTERVAL_OK(zfs_multihost_interval));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -557,6 +549,18 @@ mmp_thread(void *arg)
|
||||
|
||||
mmp_thread_enter(mmp, &cpr);
|
||||
|
||||
/*
|
||||
* There have been no MMP writes yet. Setting mmp_last_write here gives
|
||||
* us one mmp_fail_ns period, which is consistent with the activity
|
||||
* check duration, to try to land an MMP write before MMP suspends the
|
||||
* pool (if so configured).
|
||||
*/
|
||||
|
||||
mutex_enter(&mmp->mmp_io_lock);
|
||||
mmp->mmp_last_write = gethrtime();
|
||||
mmp->mmp_delay = MSEC2NSEC(MMP_INTERVAL_OK(zfs_multihost_interval));
|
||||
mutex_exit(&mmp->mmp_io_lock);
|
||||
|
||||
while (!mmp->mmp_thread_exiting) {
|
||||
hrtime_t next_time = gethrtime() +
|
||||
MSEC2NSEC(MMP_DEFAULT_INTERVAL);
|
||||
|
||||
+2
-2
@@ -6169,8 +6169,8 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing)
|
||||
spa_strfree(oldvd->vdev_path);
|
||||
oldvd->vdev_path = kmem_alloc(strlen(newvd->vdev_path) + 5,
|
||||
KM_SLEEP);
|
||||
(void) sprintf(oldvd->vdev_path, "%s/%s",
|
||||
newvd->vdev_path, "old");
|
||||
(void) snprintf(oldvd->vdev_path, strlen(newvd->vdev_path) + 5,
|
||||
"%s/%s", newvd->vdev_path, "old");
|
||||
if (oldvd->vdev_devid != NULL) {
|
||||
spa_strfree(oldvd->vdev_devid);
|
||||
oldvd->vdev_devid = NULL;
|
||||
|
||||
+1
-1
@@ -453,7 +453,7 @@ txg_dispatch_callbacks(dsl_pool_t *dp, uint64_t txg)
|
||||
* Commit callback taskq hasn't been created yet.
|
||||
*/
|
||||
tx->tx_commit_cb_taskq = taskq_create("tx_commit_cb",
|
||||
max_ncpus, defclsyspri, max_ncpus, max_ncpus * 2,
|
||||
boot_ncpus, defclsyspri, boot_ncpus, boot_ncpus * 2,
|
||||
TASKQ_PREPOPULATE | TASKQ_DYNAMIC);
|
||||
}
|
||||
|
||||
|
||||
+21
-1
@@ -2566,7 +2566,6 @@ vdev_dtl_should_excise(vdev_t *vd)
|
||||
spa_t *spa = vd->vdev_spa;
|
||||
dsl_scan_t *scn = spa->spa_dsl_pool->dp_scan;
|
||||
|
||||
ASSERT0(scn->scn_phys.scn_errors);
|
||||
ASSERT0(vd->vdev_children);
|
||||
|
||||
if (vd->vdev_state < VDEV_STATE_DEGRADED)
|
||||
@@ -2617,6 +2616,7 @@ vdev_dtl_reassess(vdev_t *vd, uint64_t txg, uint64_t scrub_txg, int scrub_done)
|
||||
|
||||
if (vd->vdev_ops->vdev_op_leaf) {
|
||||
dsl_scan_t *scn = spa->spa_dsl_pool->dp_scan;
|
||||
boolean_t wasempty = B_TRUE;
|
||||
|
||||
mutex_enter(&vd->vdev_dtl_lock);
|
||||
|
||||
@@ -2626,6 +2626,18 @@ vdev_dtl_reassess(vdev_t *vd, uint64_t txg, uint64_t scrub_txg, int scrub_done)
|
||||
if (zfs_scan_ignore_errors && scn)
|
||||
scn->scn_phys.scn_errors = 0;
|
||||
|
||||
if (scrub_txg != 0 &&
|
||||
!range_tree_is_empty(vd->vdev_dtl[DTL_MISSING])) {
|
||||
wasempty = B_FALSE;
|
||||
zfs_dbgmsg("guid:%llu txg:%llu scrub:%llu started:%d "
|
||||
"dtl:%llu/%llu errors:%llu",
|
||||
(u_longlong_t)vd->vdev_guid, (u_longlong_t)txg,
|
||||
(u_longlong_t)scrub_txg, spa->spa_scrub_started,
|
||||
(u_longlong_t)vdev_dtl_min(vd),
|
||||
(u_longlong_t)vdev_dtl_max(vd),
|
||||
(u_longlong_t)(scn ? scn->scn_phys.scn_errors : 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* If we've completed a scan cleanly then determine
|
||||
* if this vdev should remove any DTLs. We only want to
|
||||
@@ -2662,6 +2674,14 @@ vdev_dtl_reassess(vdev_t *vd, uint64_t txg, uint64_t scrub_txg, int scrub_done)
|
||||
space_reftree_generate_map(&reftree,
|
||||
vd->vdev_dtl[DTL_MISSING], 1);
|
||||
space_reftree_destroy(&reftree);
|
||||
|
||||
if (!range_tree_is_empty(vd->vdev_dtl[DTL_MISSING])) {
|
||||
zfs_dbgmsg("update DTL_MISSING:%llu/%llu",
|
||||
(u_longlong_t)vdev_dtl_min(vd),
|
||||
(u_longlong_t)vdev_dtl_max(vd));
|
||||
} else if (!wasempty) {
|
||||
zfs_dbgmsg("DTL_MISSING is now empty");
|
||||
}
|
||||
}
|
||||
range_tree_vacate(vd->vdev_dtl[DTL_PARTIAL], NULL, NULL);
|
||||
range_tree_walk(vd->vdev_dtl[DTL_MISSING],
|
||||
|
||||
@@ -471,6 +471,16 @@ vdev_submit_bio_impl(struct bio *bio)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* preempt_schedule_notrace is GPL-only which breaks the ZFS build, so
|
||||
* replace it with preempt_schedule under the following condition:
|
||||
*/
|
||||
#if defined(CONFIG_ARM64) && \
|
||||
defined(CONFIG_PREEMPTION) && \
|
||||
defined(CONFIG_BLK_CGROUP)
|
||||
#define preempt_schedule_notrace(x) preempt_schedule(x)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BIO_SET_DEV
|
||||
#if defined(CONFIG_BLK_CGROUP) && defined(HAVE_BIO_SET_DEV_GPL_ONLY)
|
||||
/*
|
||||
|
||||
+1
-1
@@ -1030,7 +1030,7 @@ zap_value_search(objset_t *os, uint64_t zapobj, uint64_t value, uint64_t mask,
|
||||
(err = zap_cursor_retrieve(&zc, za)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
if ((za->za_first_integer & mask) == (value & mask)) {
|
||||
(void) strcpy(name, za->za_name);
|
||||
(void) strlcpy(name, za->za_name, MAXNAMELEN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1602,7 +1602,8 @@ zap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za)
|
||||
za->za_integer_length = 8;
|
||||
za->za_num_integers = 1;
|
||||
za->za_first_integer = mzep->mze_value;
|
||||
(void) strcpy(za->za_name, mzep->mze_name);
|
||||
(void) strlcpy(za->za_name, mzep->mze_name,
|
||||
sizeof (za->za_name));
|
||||
zc->zc_hash = mze->mze_hash;
|
||||
zc->zc_cd = mze->mze_cd;
|
||||
err = 0;
|
||||
|
||||
+10
-8
@@ -81,13 +81,13 @@ get_objset_type_name(dsl_dataset_t *ds, char *str)
|
||||
return (error);
|
||||
switch (type) {
|
||||
case ZFS_TYPE_SNAPSHOT:
|
||||
(void) strcpy(str, "snapshot");
|
||||
(void) strlcpy(str, "snapshot", ZAP_MAXVALUELEN);
|
||||
break;
|
||||
case ZFS_TYPE_FILESYSTEM:
|
||||
(void) strcpy(str, "filesystem");
|
||||
(void) strlcpy(str, "filesystem", ZAP_MAXVALUELEN);
|
||||
break;
|
||||
case ZFS_TYPE_VOLUME:
|
||||
(void) strcpy(str, "volume");
|
||||
(void) strlcpy(str, "volume", ZAP_MAXVALUELEN);
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
@@ -399,11 +399,11 @@ get_special_prop(lua_State *state, dsl_dataset_t *ds, const char *dsname,
|
||||
break;
|
||||
case ZFS_PROP_FILESYSTEM_COUNT:
|
||||
error = dsl_dir_get_filesystem_count(ds->ds_dir, &numval);
|
||||
(void) strcpy(setpoint, "");
|
||||
(void) strlcpy(setpoint, "", ZFS_MAX_DATASET_NAME_LEN);
|
||||
break;
|
||||
case ZFS_PROP_SNAPSHOT_COUNT:
|
||||
error = dsl_dir_get_snapshot_count(ds->ds_dir, &numval);
|
||||
(void) strcpy(setpoint, "");
|
||||
(void) strlcpy(setpoint, "", ZFS_MAX_DATASET_NAME_LEN);
|
||||
break;
|
||||
case ZFS_PROP_NUMCLONES:
|
||||
numval = dsl_get_numclones(ds);
|
||||
@@ -445,7 +445,8 @@ get_special_prop(lua_State *state, dsl_dataset_t *ds, const char *dsname,
|
||||
sizeof (numval), 1, &numval);
|
||||
}
|
||||
if (error == 0)
|
||||
(void) strcpy(setpoint, dsname);
|
||||
(void) strlcpy(setpoint, dsname,
|
||||
ZFS_MAX_DATASET_NAME_LEN);
|
||||
|
||||
break;
|
||||
case ZFS_PROP_VOLBLOCKSIZE: {
|
||||
@@ -766,9 +767,10 @@ parse_written_prop(const char *dataset_name, const char *prop_name,
|
||||
ASSERT(zfs_prop_written(prop_name));
|
||||
const char *name = prop_name + ZFS_WRITTEN_PROP_PREFIX_LEN;
|
||||
if (strchr(name, '@') == NULL) {
|
||||
(void) sprintf(snap_name, "%s@%s", dataset_name, name);
|
||||
(void) snprintf(snap_name, ZFS_MAX_DATASET_NAME_LEN, "%s@%s",
|
||||
dataset_name, name);
|
||||
} else {
|
||||
(void) strcpy(snap_name, name);
|
||||
(void) strlcpy(snap_name, name, ZFS_MAX_DATASET_NAME_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
* Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
|
||||
* Copyright (c) 2018 George Melikov. All Rights Reserved.
|
||||
* Copyright (c) 2019 Datto, Inc. All rights reserved.
|
||||
* Copyright (c) 2020 The MathWorks, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -977,6 +978,22 @@ out:
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush everything out of the kernel's export table and such.
|
||||
* This is needed as once the snapshot is used over NFS, its
|
||||
* entries in svc_export and svc_expkey caches hold reference
|
||||
* to the snapshot mount point. There is no known way of flushing
|
||||
* only the entries related to the snapshot.
|
||||
*/
|
||||
static void
|
||||
exportfs_flush(void)
|
||||
{
|
||||
char *argv[] = { "/usr/sbin/exportfs", "-f", NULL };
|
||||
char *envp[] = { NULL };
|
||||
|
||||
(void) call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to unmount a snapshot by making a call to user space.
|
||||
* There is no assurance that this can or will succeed, is just a
|
||||
@@ -999,6 +1016,8 @@ zfsctl_snapshot_unmount(char *snapname, int flags)
|
||||
}
|
||||
rw_exit(&zfs_snapshot_lock);
|
||||
|
||||
exportfs_flush();
|
||||
|
||||
if (flags & MNT_FORCE)
|
||||
argv[4] = "-fn";
|
||||
argv[5] = se->se_path;
|
||||
|
||||
@@ -2557,7 +2557,8 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source,
|
||||
zfs_cmd_t *zc;
|
||||
|
||||
zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
|
||||
(void) strcpy(zc->zc_name, dsname);
|
||||
(void) strlcpy(zc->zc_name, dsname,
|
||||
sizeof (zc->zc_name));
|
||||
(void) zfs_ioc_userspace_upgrade(zc);
|
||||
(void) zfs_ioc_id_quota_upgrade(zc);
|
||||
kmem_free(zc, sizeof (zfs_cmd_t));
|
||||
@@ -5069,7 +5070,7 @@ zfs_ioc_recv_new(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
|
||||
strchr(snapname, '%'))
|
||||
return (SET_ERROR(EINVAL));
|
||||
|
||||
(void) strcpy(tofs, snapname);
|
||||
(void) strlcpy(tofs, snapname, sizeof (tofs));
|
||||
tosnap = strchr(tofs, '@');
|
||||
*tosnap++ = '\0';
|
||||
|
||||
|
||||
+4
-2
@@ -203,11 +203,13 @@ zio_init(void)
|
||||
|
||||
if (align != 0) {
|
||||
char name[36];
|
||||
(void) sprintf(name, "zio_buf_%lu", (ulong_t)size);
|
||||
(void) snprintf(name, sizeof (name), "zio_buf_%lu",
|
||||
(ulong_t)size);
|
||||
zio_buf_cache[c] = kmem_cache_create(name, size,
|
||||
align, NULL, NULL, NULL, NULL, NULL, cflags);
|
||||
|
||||
(void) sprintf(name, "zio_data_buf_%lu", (ulong_t)size);
|
||||
(void) snprintf(name, sizeof (name), "zio_data_buf_%lu",
|
||||
(ulong_t)size);
|
||||
zio_data_buf_cache[c] = kmem_cache_create(name, size,
|
||||
align, NULL, NULL, NULL, NULL,
|
||||
data_alloc_arena, data_cflags);
|
||||
|
||||
+17
-1
@@ -1017,9 +1017,17 @@ zvol_get_data(void *arg, lr_write_t *lr, char *buf, struct lwb *lwb, zio_t *zio)
|
||||
return (SET_ERROR(error));
|
||||
}
|
||||
|
||||
#ifdef HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS
|
||||
static blk_qc_t
|
||||
zvol_submit_bio(struct bio *bio)
|
||||
#else
|
||||
static MAKE_REQUEST_FN_RET
|
||||
zvol_request(struct request_queue *q, struct bio *bio)
|
||||
#endif
|
||||
{
|
||||
#ifdef HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS
|
||||
struct request_queue *q = bio->bi_disk->queue;
|
||||
#endif
|
||||
zvol_state_t *zv = q->queuedata;
|
||||
fstrans_cookie_t cookie = spl_fstrans_mark();
|
||||
uint64_t offset = BIO_BI_SECTOR(bio) << 9;
|
||||
@@ -1139,7 +1147,8 @@ out:
|
||||
spl_fstrans_unmark(cookie);
|
||||
#ifdef HAVE_MAKE_REQUEST_FN_RET_INT
|
||||
return (0);
|
||||
#elif defined(HAVE_MAKE_REQUEST_FN_RET_QC)
|
||||
#elif defined(HAVE_MAKE_REQUEST_FN_RET_QC) || \
|
||||
defined(HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS)
|
||||
return (BLK_QC_T_NONE);
|
||||
#endif
|
||||
}
|
||||
@@ -1676,6 +1685,9 @@ static struct block_device_operations zvol_ops = {
|
||||
.revalidate_disk = zvol_revalidate_disk,
|
||||
.getgeo = zvol_getgeo,
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS
|
||||
.submit_bio = zvol_submit_bio,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1703,7 +1715,11 @@ zvol_alloc(dev_t dev, const char *name)
|
||||
|
||||
mutex_init(&zv->zv_state_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||
|
||||
#ifdef HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS
|
||||
zv->zv_queue = blk_alloc_queue(NUMA_NO_NODE);
|
||||
#else
|
||||
zv->zv_queue = blk_generic_alloc_queue(zvol_request, NUMA_NO_NODE);
|
||||
#endif
|
||||
if (zv->zv_queue == NULL)
|
||||
goto out_kmem;
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ fi
|
||||
CONFIG_H="/var/lib/dkms/%{module}/%{version}/*/*/%{module}_config.h"
|
||||
SPEC_META_ALIAS="@PACKAGE@-@VERSION@-@RELEASE@"
|
||||
DKMS_META_ALIAS=`cat $CONFIG_H 2>/dev/null |
|
||||
awk -F'"' '/META_ALIAS/ { print $2; exit 0 }'`
|
||||
awk -F'"' '/META_ALIAS\s+"/ { print $2; exit 0 }'`
|
||||
if [ "$SPEC_META_ALIAS" = "$DKMS_META_ALIAS" ]; then
|
||||
echo -e
|
||||
echo -e "Uninstall of %{module} module ($SPEC_META_ALIAS) beginning:"
|
||||
|
||||
@@ -471,8 +471,8 @@ systemctl --system daemon-reload >/dev/null || true
|
||||
%{_libdir}/libzfs*.so.*
|
||||
|
||||
%files -n libzfs2-devel
|
||||
%{_datarootdir}/pkgconfig/libzfs.pc
|
||||
%{_datarootdir}/pkgconfig/libzfs_core.pc
|
||||
%{_libdir}/pkgconfig/libzfs.pc
|
||||
%{_libdir}/pkgconfig/libzfs_core.pc
|
||||
%{_libdir}/*.so
|
||||
%{_includedir}/*
|
||||
%doc AUTHORS COPYRIGHT LICENSE NOTICE README.md
|
||||
|
||||
@@ -76,7 +76,7 @@ tests = ['tst.args_to_lua', 'tst.divide_by_zero', 'tst.exists',
|
||||
'tst.memory_limit', 'tst.nested_neg', 'tst.nested_pos', 'tst.nvlist_to_lua',
|
||||
'tst.recursive_neg', 'tst.recursive_pos', 'tst.return_large',
|
||||
'tst.return_nvlist_neg', 'tst.return_nvlist_pos',
|
||||
'tst.return_recursive_table', 'tst.timeout']
|
||||
'tst.return_recursive_table', 'tst.stack_gsub', 'tst.timeout']
|
||||
tags = ['functional', 'channel_program', 'lua_core']
|
||||
|
||||
[tests/functional/channel_program/synctask_core]
|
||||
@@ -797,7 +797,7 @@ tests = ['reservation_001_pos', 'reservation_002_pos', 'reservation_003_pos',
|
||||
tags = ['functional', 'reservation']
|
||||
|
||||
[tests/functional/resilver]
|
||||
tests = ['resilver_restart_001']
|
||||
tests = ['resilver_restart_001', 'resilver_restart_002']
|
||||
tags = ['functional', 'resilver']
|
||||
|
||||
[tests/functional/rootpool]
|
||||
|
||||
@@ -274,8 +274,19 @@ maybe = {
|
||||
'vdev_zaps/vdev_zaps_004_pos': ['FAIL', '6935'],
|
||||
'write_dirs/setup': ['SKIP', disk_reason],
|
||||
'zvol/zvol_ENOSPC/zvol_ENOSPC_001_pos': ['FAIL', '5848'],
|
||||
}
|
||||
'alloc_class/alloc_class_009_pos': ['FAIL', known_reason],
|
||||
'alloc_class/alloc_class_010_pos': ['FAIL', known_reason],
|
||||
'cli_root/zfs_rename/zfs_rename_002_pos': ['FAIL', known_reason],
|
||||
'cli_root/zpool_expand/zpool_expand_001_pos': ['FAIL', known_reason],
|
||||
'cli_root/zpool_expand/zpool_expand_005_pos': ['FAIL', known_reason],
|
||||
'cli_root/zpool_reopen/zpool_reopen_003_pos': ['FAIL', known_reason],
|
||||
'refreserv/refreserv_raidz': ['FAIL', known_reason],
|
||||
'rsend/rsend_007_pos': ['FAIL', known_reason],
|
||||
'rsend/rsend_010_pos': ['FAIL', known_reason],
|
||||
'rsend/rsend_011_pos': ['FAIL', known_reason],
|
||||
'snapshot/rollback_003_pos': ['FAIL', known_reason],
|
||||
|
||||
}
|
||||
|
||||
def usage(s):
|
||||
print(s)
|
||||
|
||||
@@ -21,6 +21,7 @@ dist_pkgdata_SCRIPTS = \
|
||||
tst.return_nvlist_neg.ksh \
|
||||
tst.return_nvlist_pos.ksh \
|
||||
tst.return_recursive_table.ksh \
|
||||
tst.stack_gsub.ksh \
|
||||
tst.timeout.ksh
|
||||
|
||||
dist_pkgdata_DATA = \
|
||||
@@ -40,4 +41,6 @@ dist_pkgdata_DATA = \
|
||||
tst.recursive.zcp \
|
||||
tst.return_large.zcp \
|
||||
tst.return_recursive_table.zcp \
|
||||
tst.stack_gsub.err \
|
||||
tst.stack_gsub.zcp \
|
||||
tst.timeout.zcp
|
||||
|
||||
@@ -61,6 +61,9 @@ log_mustnot_checkerror_program "Memory limit exhausted" -m 1 $TESTPOOL - <<-EOF
|
||||
return s
|
||||
EOF
|
||||
|
||||
# Set the memlimit, in case it is a non-default value
|
||||
log_must set_tunable32 zfs_lua_max_memlimit 100000000
|
||||
|
||||
log_mustnot_checkerror_program "Invalid instruction or memory limit" \
|
||||
-m 200000000 $TESTPOOL - <<-EOF
|
||||
return 1;
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
Channel program execution failed:
|
||||
C stack overflow
|
||||
stack traceback:
|
||||
[C]: in function 'gsub'
|
||||
[string "channel program"]:17: in function <[string "channel program"]:16>
|
||||
[C]: in function 'gsub'
|
||||
[string "channel program"]:17: in function <[string "channel program"]:16>
|
||||
[C]: in function 'gsub'
|
||||
[string "channel program"]:17: in function <[string "channel program"]:16>
|
||||
[C]: in function 'gsub'
|
||||
[string "channel program"]:17: in function <[string "channel program"]:16>
|
||||
[C]: in function 'gsub'
|
||||
[string "channel program"]:17: in function <[string "channel program"]:16>
|
||||
[C]: in function 'gsub'
|
||||
[string "channel program"]:17: in function <[string "channel program"]:16>
|
||||
[C]: in function 'gsub'
|
||||
[string "channel program"]:17: in function <[string "channel program"]:16>
|
||||
(...tail calls...)
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
#!/bin/ksh -p
|
||||
#
|
||||
# This file and its contents are supplied under the terms of the
|
||||
# Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
# You may only use this file in accordance with the terms of version
|
||||
# 1.0 of the CDDL.
|
||||
#
|
||||
# A full copy of the text of the CDDL should have accompanied this
|
||||
# source. A copy of the CDDL is also available via the Internet at
|
||||
# http://www.illumos.org/license/CDDL.
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2020 by Delphix. All rights reserved.
|
||||
#
|
||||
|
||||
. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Overflowing the C stack using recursive gsub() should be handled
|
||||
# gracefully. gsub() uses more stack space than typical, so it relies
|
||||
# on LUAI_MINCSTACK to ensure that we don't overflow the Linux kernel's
|
||||
# stack.
|
||||
#
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
log_assert "recursive gsub() should be handled gracefully"
|
||||
|
||||
log_mustnot_program $TESTPOOL $ZCP_ROOT/lua_core/tst.stack_gsub.zcp
|
||||
|
||||
log_pass "recursive gsub() should be handled gracefully"
|
||||
@@ -0,0 +1,20 @@
|
||||
--
|
||||
-- This file and its contents are supplied under the terms of the
|
||||
-- Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
-- You may only use this file in accordance with the terms of version
|
||||
-- 1.0 of the CDDL.
|
||||
--
|
||||
-- A full copy of the text of the CDDL should have accompanied this
|
||||
-- source. A copy of the CDDL is also available via the Internet at
|
||||
-- http://www.illumos.org/license/CDDL.
|
||||
--
|
||||
|
||||
--
|
||||
-- Copyright (c) 2020 by Delphix. All rights reserved.
|
||||
--
|
||||
|
||||
function f(s)
|
||||
return string.gsub(s, ".", f)
|
||||
end
|
||||
|
||||
return f("foo")
|
||||
@@ -25,23 +25,29 @@
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Testing Fault Management Agent ZED Logic - Physically removed device is
|
||||
# offlined and onlined when reattached
|
||||
# made unavail and onlined when reattached
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create a pool
|
||||
# 2. Simulate physical removal of one device
|
||||
# 3. Verify the device is offlined
|
||||
# 3. Verify the device is unvailable
|
||||
# 4. Reattach the device
|
||||
# 5. Verify the device is onlined
|
||||
# 6. Repeat the same tests with a spare device: zed will use the spare to handle
|
||||
# the removed data device
|
||||
# 7. Repeat the same tests again with a faulted spare device: zed should offline
|
||||
# the removed data device if no spare is available
|
||||
# 6. Repeat the same tests with a spare device:
|
||||
# zed will use the spare to handle the removed data device
|
||||
# 7. Repeat the same tests again with a faulted spare device:
|
||||
# the removed data device should be unavailable
|
||||
#
|
||||
# NOTE: the use of 'block_device_wait' throughout the test helps avoid race
|
||||
# conditions caused by mixing creation/removal events from partitioning the
|
||||
# disk (zpool create) and events from physically removing it (remove_disk).
|
||||
#
|
||||
# NOTE: the test relies on 'zpool sync' to prompt the kmods to transition a
|
||||
# vdev to the unavailable state. The ZED does receive a removal notification
|
||||
# but only relies on it to activate a hot spare. Additional work is planned
|
||||
# to extend an existing ioctl interface to allow the ZED to transition the
|
||||
# vdev in to a removed state.
|
||||
#
|
||||
verify_runnable "both"
|
||||
|
||||
if is_linux; then
|
||||
@@ -73,13 +79,10 @@ filedev3="$TEST_BASE_DIR/file-vdev-3"
|
||||
sparedev="$TEST_BASE_DIR/file-vdev-spare"
|
||||
removedev=$(get_debug_device)
|
||||
|
||||
typeset poolconfs=("mirror $filedev1 $removedev"
|
||||
"raidz $filedev1 $removedev"
|
||||
"raidz2 $filedev1 $filedev2 $removedev"
|
||||
typeset poolconfs=(
|
||||
"mirror $filedev1 $removedev"
|
||||
"raidz3 $filedev1 $filedev2 $filedev3 $removedev"
|
||||
"$filedev1 cache $removedev"
|
||||
"mirror $filedev1 $filedev2 cache $removedev"
|
||||
"raidz $filedev1 $filedev2 $filedev3 cache $removedev"
|
||||
"mirror $filedev1 $filedev2 special mirror $filedev3 $removedev"
|
||||
)
|
||||
|
||||
log_must truncate -s $SPA_MINDEVSIZE $filedev1
|
||||
@@ -91,13 +94,18 @@ for conf in "${poolconfs[@]}"
|
||||
do
|
||||
# 1. Create a pool
|
||||
log_must zpool create -f $TESTPOOL $conf
|
||||
block_device_wait
|
||||
block_device_wait ${DEV_DSKDIR}/${removedev}
|
||||
|
||||
mntpnt=$(get_prop mountpoint /$TESTPOOL) ||
|
||||
log_fail "get_prop mountpoint /$TESTPOOL"
|
||||
|
||||
# 2. Simulate physical removal of one device
|
||||
remove_disk $removedev
|
||||
log_must mkfile 1m $mntpnt/file
|
||||
log_must zpool sync $TESTPOOL
|
||||
|
||||
# 3. Verify the device is offlined
|
||||
log_must wait_vdev_state $TESTPOOL $removedev "OFFLINE"
|
||||
# 3. Verify the device is unvailable.
|
||||
log_must wait_vdev_state $TESTPOOL $removedev "UNAVAIL"
|
||||
|
||||
# 4. Reattach the device
|
||||
insert_disk $removedev
|
||||
@@ -107,8 +115,8 @@ do
|
||||
|
||||
# cleanup
|
||||
destroy_pool $TESTPOOL
|
||||
log_must parted "/dev/${removedev}" -s -- mklabel msdos
|
||||
block_device_wait
|
||||
log_must parted "${DEV_DSKDIR}/${removedev}" -s -- mklabel msdos
|
||||
block_device_wait ${DEV_DSKDIR}/${removedev}
|
||||
done
|
||||
|
||||
# 6. Repeat the same tests with a spare device: zed will use the spare to handle
|
||||
@@ -117,30 +125,31 @@ for conf in "${poolconfs[@]}"
|
||||
do
|
||||
# 1. Create a pool with a spare
|
||||
log_must zpool create -f $TESTPOOL $conf
|
||||
block_device_wait
|
||||
block_device_wait ${DEV_DSKDIR}/${removedev}
|
||||
log_must zpool add $TESTPOOL spare $sparedev
|
||||
|
||||
# 3. Simulate physical removal of one device
|
||||
mntpnt=$(get_prop mountpoint /$TESTPOOL) ||
|
||||
log_fail "get_prop mountpoint /$TESTPOOL"
|
||||
|
||||
# 2. Simulate physical removal of one device
|
||||
remove_disk $removedev
|
||||
log_must mkfile 1m $mntpnt/file
|
||||
log_must zpool sync $TESTPOOL
|
||||
|
||||
# 4. Verify the device is handled by the spare unless is a l2arc disk
|
||||
# which can only be offlined
|
||||
if [[ $(echo "$conf" | grep -c 'cache') -eq 0 ]]; then
|
||||
log_must wait_hotspare_state $TESTPOOL $sparedev "INUSE"
|
||||
else
|
||||
log_must wait_vdev_state $TESTPOOL $removedev "OFFLINE"
|
||||
fi
|
||||
# 3. Verify the device is handled by the spare.
|
||||
log_must wait_hotspare_state $TESTPOOL $sparedev "INUSE"
|
||||
log_must wait_vdev_state $TESTPOOL $removedev "UNAVAIL"
|
||||
|
||||
# 5. Reattach the device
|
||||
# 4. Reattach the device
|
||||
insert_disk $removedev
|
||||
|
||||
# 6. Verify the device is onlined
|
||||
# 5. Verify the device is onlined
|
||||
log_must wait_vdev_state $TESTPOOL $removedev "ONLINE"
|
||||
|
||||
# cleanup
|
||||
destroy_pool $TESTPOOL
|
||||
log_must parted "/dev/${removedev}" -s -- mklabel msdos
|
||||
block_device_wait
|
||||
log_must parted "${DEV_DSKDIR}/${removedev}" -s -- mklabel msdos
|
||||
block_device_wait ${DEV_DSKDIR}/${removedev}
|
||||
done
|
||||
|
||||
# 7. Repeat the same tests again with a faulted spare device: zed should offline
|
||||
@@ -149,18 +158,23 @@ for conf in "${poolconfs[@]}"
|
||||
do
|
||||
# 1. Create a pool with a spare
|
||||
log_must zpool create -f $TESTPOOL $conf
|
||||
block_device_wait
|
||||
block_device_wait ${DEV_DSKDIR}/${removedev}
|
||||
log_must zpool add $TESTPOOL spare $sparedev
|
||||
|
||||
mntpnt=$(get_prop mountpoint /$TESTPOOL) ||
|
||||
log_fail "get_prop mountpoint /$TESTPOOL"
|
||||
|
||||
# 2. Fault the spare device making it unavailable
|
||||
log_must zpool offline -f $TESTPOOL $sparedev
|
||||
log_must wait_hotspare_state $TESTPOOL $sparedev "FAULTED"
|
||||
|
||||
# 3. Simulate physical removal of one device
|
||||
remove_disk $removedev
|
||||
log_must mkfile 1m $mntpnt/file
|
||||
log_must zpool sync $TESTPOOL
|
||||
|
||||
# 4. Verify the device is offlined
|
||||
log_must wait_vdev_state $TESTPOOL $removedev "OFFLINE"
|
||||
# 4. Verify the device is unavailable
|
||||
log_must wait_vdev_state $TESTPOOL $removedev "UNAVAIL"
|
||||
|
||||
# 5. Reattach the device
|
||||
insert_disk $removedev
|
||||
@@ -170,8 +184,8 @@ do
|
||||
|
||||
# cleanup
|
||||
destroy_pool $TESTPOOL
|
||||
log_must parted "/dev/${removedev}" -s -- mklabel msdos
|
||||
block_device_wait
|
||||
log_must parted "${DEV_DSKDIR}/${removedev}" -s -- mklabel msdos
|
||||
block_device_wait ${DEV_DSKDIR}/${removedev}
|
||||
done
|
||||
|
||||
log_pass "ZED detects physically removed devices"
|
||||
|
||||
@@ -2,7 +2,8 @@ pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/resilver
|
||||
dist_pkgdata_SCRIPTS = \
|
||||
setup.ksh \
|
||||
cleanup.ksh \
|
||||
resilver_restart_001.ksh
|
||||
resilver_restart_001.ksh \
|
||||
resilver_restart_002.ksh
|
||||
|
||||
dist_pkgdata_DATA = \
|
||||
resilver.cfg
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
#!/bin/ksh -p
|
||||
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# This file and its contents are supplied under the terms of the
|
||||
# Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
# You may only use this file in accordance with the terms of version
|
||||
# 1.0 of the CDDL.
|
||||
#
|
||||
# A full copy of the text of the CDDL should have accompanied this
|
||||
# source. A copy of the CDDL is also available via the Internet at
|
||||
# http://www.illumos.org/license/CDDL.
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2020, Datto Inc. All rights reserved.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/resilver/resilver.cfg
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Testing resilver completes when scan errors are encountered, but relevant
|
||||
# DTL's have not been lost.
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create a pool (1k recordsize)
|
||||
# 2. Create a 32m file (32k records)
|
||||
# 3. Inject an error halfway through the file
|
||||
# 4. Start a resilver, ensure the error is triggered and that the resilver
|
||||
# does not restart after finishing
|
||||
#
|
||||
# NB: use legacy scanning to ensure scan of specific block causes error
|
||||
#
|
||||
|
||||
function cleanup
|
||||
{
|
||||
log_must zinject -c all
|
||||
destroy_pool $TESTPOOL
|
||||
rm -f ${VDEV_FILES[@]} $SPARE_VDEV_FILE
|
||||
log_must set_tunable32 zfs_scan_legacy $ORIG_SCAN_LEGACY
|
||||
}
|
||||
|
||||
log_assert "Check for resilver restarts caused by scan errors"
|
||||
|
||||
ORIG_SCAN_LEGACY=$(get_tunable zfs_scan_legacy)
|
||||
|
||||
log_onexit cleanup
|
||||
|
||||
# use legacy scan to ensure injected error will be triggered
|
||||
log_must set_tunable32 zfs_scan_legacy 1
|
||||
|
||||
# create the pool and a 32M file (32k blocks)
|
||||
log_must truncate -s $VDEV_FILE_SIZE ${VDEV_FILES[0]} $SPARE_VDEV_FILE
|
||||
log_must zpool create -f -O recordsize=1k $TESTPOOL ${VDEV_FILES[0]}
|
||||
log_must dd if=/dev/urandom of=/$TESTPOOL/file bs=1M count=32 > /dev/null 2>&1
|
||||
|
||||
# determine objset/object
|
||||
objset=$(zdb -d $TESTPOOL/ | sed -ne 's/.*ID \([0-9]*\).*/\1/p')
|
||||
object=$(ls -i /$TESTPOOL/file | awk '{print $1}')
|
||||
|
||||
# inject event to cause error during resilver
|
||||
log_must zinject -b `printf "%x:%x:0:3fff" $objset $object` $TESTPOOL
|
||||
|
||||
# clear events and start resilver
|
||||
log_must zpool events -c
|
||||
log_must zpool attach $TESTPOOL ${VDEV_FILES[0]} $SPARE_VDEV_FILE
|
||||
|
||||
log_note "waiting for read errors to start showing up"
|
||||
for iter in {0..59}
|
||||
do
|
||||
zpool sync $TESTPOOL
|
||||
err=$(zpool status $TESTPOOL | grep ${VDEV_FILES[0]} | awk '{print $3}')
|
||||
(( $err > 0 )) && break
|
||||
sleep 1
|
||||
done
|
||||
|
||||
(( $err == 0 )) && log_fail "Unable to induce errors in resilver"
|
||||
|
||||
log_note "waiting for resilver to finish"
|
||||
for iter in {0..59}
|
||||
do
|
||||
finish=$(zpool events | grep "sysevent.fs.zfs.resilver_finish" | wc -l)
|
||||
(( $finish > 0 )) && break
|
||||
sleep 1
|
||||
done
|
||||
|
||||
(( $finish == 0 )) && log_fail "resilver took too long to finish"
|
||||
|
||||
# wait a few syncs to ensure that zfs does not restart the resilver
|
||||
log_must zpool sync $TESTPOOL
|
||||
log_must zpool sync $TESTPOOL
|
||||
|
||||
# check if resilver was restarted
|
||||
start=$(zpool events | grep "sysevent.fs.zfs.resilver_start" | wc -l)
|
||||
(( $start != 1 )) && log_fail "resilver restarted unnecessarily"
|
||||
|
||||
log_pass "Resilver did not restart unnecessarily from scan errors"
|
||||
Reference in New Issue
Block a user