MFV 2.0-rc2

- Fixes divide by zero for unusual hz
- remove cryptodev dependency
This commit is contained in:
Matt Macy 2020-09-18 23:21:24 +00:00
commit 2c48331d28
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=365894
135 changed files with 2674 additions and 526 deletions

View File

@ -234,6 +234,7 @@ CFLAGS+= \
-DHAVE_ISSETUGID \
-include ${SRCTOP}/sys/modules/zfs/zfs_config.h \
-I${SRCTOP}/sys/modules/zfs \
-I${ZFSTOP}/include/os/freebsd/zfs \
-DLIB_ZPOOL_BUILD -DZFS_DEBUG \
# XXX: pthread doesn't have mutex_owned() equivalent, so we need to look

View File

@ -2,7 +2,7 @@ Meta: 1
Name: zfs
Branch: 1.0
Version: 2.0.0
Release: rc1
Release: rc2
Release-Tags: relext
License: CDDL
Author: OpenZFS

View File

@ -182,6 +182,7 @@ main(int argc, char **argv)
int error, c;
(void) setlocale(LC_ALL, "");
(void) setlocale(LC_NUMERIC, "C");
(void) textdomain(TEXT_DOMAIN);
opterr = 0;

View File

@ -5340,11 +5340,6 @@ load_unflushed_svr_segs_cb(spa_t *spa, space_map_entry_t *sme,
if (txg < metaslab_unflushed_txg(ms))
return (0);
vdev_indirect_mapping_t *vim = vd->vdev_indirect_mapping;
ASSERT(vim != NULL);
if (offset >= vdev_indirect_mapping_max_offset(vim))
return (0);
if (sme->sme_type == SM_ALLOC)
range_tree_add(svr->svr_allocd_segs, offset, size);
else
@ -5407,9 +5402,6 @@ zdb_claim_removing(spa_t *spa, zdb_cb_t *zcb)
for (uint64_t msi = 0; msi < vd->vdev_ms_count; msi++) {
metaslab_t *msp = vd->vdev_ms[msi];
if (msp->ms_start >= vdev_indirect_mapping_max_offset(vim))
break;
ASSERT0(range_tree_space(allocs));
if (msp->ms_sm != NULL)
VERIFY0(space_map_load(msp->ms_sm, allocs, SM_ALLOC));

View File

@ -8468,6 +8468,7 @@ main(int argc, char **argv)
char **newargv;
(void) setlocale(LC_ALL, "");
(void) setlocale(LC_NUMERIC, "C");
(void) textdomain(TEXT_DOMAIN);
opterr = 0;

View File

@ -0,0 +1 @@
/zgenhostid

View File

@ -1 +1,5 @@
dist_bin_SCRIPTS = zgenhostid
include $(top_srcdir)/config/Rules.am
bin_PROGRAMS = zgenhostid
zgenhostid_SOURCES = zgenhostid.c

View File

@ -1,61 +0,0 @@
#!/usr/bin/env bash
# Emulate genhostid(1) available on RHEL/CENTOS, for use on distros
# which do not provide that utility.
#
# Usage:
# zgenhostid
# zgenhostid <value>
#
# If /etc/hostid already exists and is size > 0, the script exits immediately
# and changes nothing. Unlike genhostid, this generates an error message.
#
# The first form generates a random hostid and stores it in /etc/hostid.
# The second form checks that the provided value is between 0x1 and 0xFFFFFFFF
# and if so, stores it in /etc/hostid. This form is not supported by
# genhostid(1).
hostid_file=/etc/hostid
function usage {
echo "$0 [value]"
echo "If $hostid_file is not present, store a hostid in it." >&2
echo "The optional value must be an 8-digit hex number between" >&2
echo "1 and 2^32-1. If no value is provided, a random one will" >&2
echo "be generated. The value must be unique among your systems." >&2
}
# hostid(1) ignores contents of /etc/hostid if size < 4 bytes. It would
# be better if this checked size >= 4 bytes but it the method must be
# widely portable.
if [ -s $hostid_file ]; then
echo "$hostid_file already exists. No change made." >&2
exit 1
fi
if [ -n "$1" ]; then
host_id=$1
else
# $RANDOM goes from 0..32k-1
number=$((((RANDOM % 4) * 32768 + RANDOM) * 32768 + RANDOM))
host_id=$(printf "%08x" $number)
fi
if egrep -o '^0{8}$' <<< $host_id >/dev/null 2>&1; then
usage
exit 2
fi
if ! egrep -o '^[a-fA-F0-9]{8}$' <<< $host_id >/dev/null 2>&1; then
usage
exit 3
fi
a=${host_id:6:2}
b=${host_id:4:2}
c=${host_id:2:2}
d=${host_id:0:2}
echo -ne \\x$a\\x$b\\x$c\\x$d > $hostid_file
exit 0

View File

@ -0,0 +1,152 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2020, Georgy Yakovlev. All rights reserved.
*/
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <inttypes.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
static void usage(void);
static void
usage(void)
{
(void) fprintf(stderr,
"usage: zgenhostid [-fh] [-o path] [value]\n\n"
" -f\t\t force hostid file write\n"
" -h\t\t print this usage and exit\n"
" -o <filename>\t write hostid to this file\n\n"
"If hostid file is not present, store a hostid in it.\n"
"The optional value must be an 8-digit hex number between"
"1 and 2^32-1.\n"
"If no value is provided, a random one will"
"be generated.\n"
"The value must be unique among your systems.\n");
exit(EXIT_FAILURE);
/* NOTREACHED */
}
int
main(int argc, char **argv)
{
/* default file path, can be optionally set by user */
char path[PATH_MAX] = "/etc/hostid";
/* holds converted user input or lrand48() generated value */
unsigned long input_i = 0;
int opt;
int pathlen;
int force_fwrite = 0;
while ((opt = getopt_long(argc, argv, "fo:h?", 0, 0)) != -1) {
switch (opt) {
case 'f':
force_fwrite = 1;
break;
case 'o':
pathlen = snprintf(path, sizeof (path), "%s", optarg);
if (pathlen >= sizeof (path)) {
fprintf(stderr, "%s\n", strerror(EOVERFLOW));
exit(EXIT_FAILURE);
} else if (pathlen < 1) {
fprintf(stderr, "%s\n", strerror(EINVAL));
exit(EXIT_FAILURE);
}
break;
case 'h':
case '?':
usage();
}
}
char *in_s = argv[optind];
if (in_s != NULL) {
/* increment pointer by 2 if string is 0x prefixed */
if (strncasecmp("0x", in_s, 2) == 0) {
in_s += 2;
}
/* need to be exactly 8 characters */
const char *hex = "0123456789abcdefABCDEF";
if (strlen(in_s) != 8 || strspn(in_s, hex) != 8) {
fprintf(stderr, "%s\n", strerror(ERANGE));
usage();
}
input_i = strtoul(in_s, NULL, 16);
if (errno != 0) {
perror("strtoul");
exit(EXIT_FAILURE);
}
if (input_i < 0x1 || input_i > UINT32_MAX) {
fprintf(stderr, "%s\n", strerror(ERANGE));
usage();
}
}
struct stat fstat;
if (force_fwrite == 0 && stat(path, &fstat) == 0 &&
S_ISREG(fstat.st_mode)) {
fprintf(stderr, "%s: %s\n", path, strerror(EEXIST));
exit(EXIT_FAILURE);
}
/*
* generate if not provided by user
* also handle unlikely zero return from lrand48()
*/
while (input_i == 0) {
srand48(getpid() ^ time(NULL));
input_i = lrand48();
}
FILE *fp = fopen(path, "wb");
if (!fp) {
perror("fopen");
exit(EXIT_FAILURE);
}
/*
* we need just 4 bytes in native endianess
* not using sethostid() because it may be missing or just a stub
*/
uint32_t hostid = input_i;
int written = fwrite(&hostid, 1, 4, fp);
if (written != 4) {
perror("fwrite");
exit(EXIT_FAILURE);
}
fclose(fp);
exit(EXIT_SUCCESS);
}

View File

@ -2654,6 +2654,13 @@ show_import(nvlist_t *config)
errata);
break;
case ZPOOL_STATUS_NON_NATIVE_ASHIFT:
printf_color(ANSI_BOLD, gettext("status: "));
printf_color(ANSI_YELLOW, gettext("One or more devices are "
"configured to use a non-native block size.\n"
"\tExpect reduced performance.\n"));
break;
default:
/*
* No other status can be seen when importing pools.
@ -10229,6 +10236,7 @@ main(int argc, char **argv)
char **newargv;
(void) setlocale(LC_ALL, "");
(void) setlocale(LC_NUMERIC, "C");
(void) textdomain(TEXT_DOMAIN);
srand(time(NULL));

View File

@ -35,7 +35,7 @@ deb-dkms: deb-local rpm-dkms
fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch $$pkg1 || exit 1; \
$(RM) $$pkg1
deb-utils: deb-local rpm-utils
deb-utils: deb-local rpm-utils-initramfs
name=${PACKAGE}; \
version=${VERSION}-${RELEASE}; \
arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \

View File

@ -11,10 +11,12 @@ AC_DEFUN([ZFS_AC_FIND_SYSTEM_LIBRARY], [
_header_found=
_library_found=
_pc_found=
AS_IF([test -n "$2"], [PKG_CHECK_MODULES([$1], [$2], [
_header_found=1
_library_found=1
_pc_found=1
], [:])])
# set _header_found/_library_found if the user passed in CFLAGS/LIBS
@ -82,6 +84,9 @@ AC_DEFUN([ZFS_AC_FIND_SYSTEM_LIBRARY], [
AS_IF([test "x$_header_found" = "x1" && test "x$_library_found" = "x1"], [
AC_SUBST([$1]_CFLAGS)
AC_SUBST([$1]_LIBS)
AS_IF([test "x$_pc_found" = "x1"], [
AC_SUBST([$1]_PC, [$2])
])
AC_DEFINE([HAVE_][$1], [1], [Define if you have [$5]])
$7
],[dnl ELSE

View File

@ -7,7 +7,7 @@
###############################################################################
PHONY += srpm srpms srpm-kmod srpm-dkms srpm-utils
PHONY += rpm rpms rpm-kmod rpm-dkms rpm-utils
PHONY += rpm rpms rpm-kmod rpm-dkms rpm-utils rpm-utils-initramfs
PHONY += srpm-common rpm-common rpm-local
srpm-kmod srpm-dkms srpm-utils: dist
@ -35,10 +35,22 @@ rpm-dkms: srpm-dkms
$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-dkms" \
def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_DKMS}' rpm-common
# The rpm-utils and rpm-utils-initramfs targets are identical except for the
# zfs-initramfs package: rpm-utils never includes it, rpm-utils-initramfs
# includes it if detected at configure time. The zfs-initramfs package does
# not work on any known RPM-based distribution and the resulting RPM is only
# used to create a Debian package. The rpm-utils-initramfs target is not
# intended to be specified by the user directly, it is provided as a
# dependency of the deb-utils target.
rpm-utils: srpm-utils
$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}" \
def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_UTIL}' rpm-common
rpm-utils-initramfs: srpm-utils
$(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}" \
def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_UTIL} ${RPM_DEFINE_INITRAMFS}' rpm-common
rpm: rpm-kmod rpm-dkms rpm-utils
rpms: rpm-kmod rpm-dkms rpm-utils

View File

@ -282,7 +282,6 @@ AC_DEFUN([ZFS_AC_RPM], [
AS_IF([test -n "$udevruledir" ], [
RPM_DEFINE_UTIL=${RPM_DEFINE_UTIL}' --define "_udevruledir $(udevruledir)"'
])
RPM_DEFINE_UTIL=${RPM_DEFINE_UTIL}' $(DEFINE_INITRAMFS)'
RPM_DEFINE_UTIL=${RPM_DEFINE_UTIL}' $(DEFINE_SYSTEMD)'
RPM_DEFINE_UTIL=${RPM_DEFINE_UTIL}' $(DEFINE_PYZFS)'
RPM_DEFINE_UTIL=${RPM_DEFINE_UTIL}' $(DEFINE_PAM)'
@ -542,13 +541,13 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [
AC_MSG_CHECKING([whether initramfs-tools is available])
if test -d /usr/share/initramfs-tools ; then
DEFINE_INITRAMFS='--define "_initramfs 1"'
RPM_DEFINE_INITRAMFS='--define "_initramfs 1"'
AC_MSG_RESULT([yes])
else
DEFINE_INITRAMFS=''
RPM_DEFINE_INITRAMFS=''
AC_MSG_RESULT([no])
fi
AC_SUBST(DEFINE_INITRAMFS)
AC_SUBST(RPM_DEFINE_INITRAMFS)
])
dnl #

View File

@ -161,6 +161,8 @@ AC_CONFIG_FILES([
lib/libuutil/Makefile
lib/libzfs/Makefile
lib/libzfs/libzfs.pc
lib/libzfsbootenv/Makefile
lib/libzfsbootenv/libzfsbootenv.pc
lib/libzfs_core/Makefile
lib/libzfs_core/libzfs_core.pc
lib/libzpool/Makefile

View File

@ -5,7 +5,7 @@ check() {
[ "${1}" = "-d" ] && return 0
# Verify the zfs tool chain
for tool in "@sbindir@/zpool" "@sbindir@/zfs" "@mounthelperdir@/mount.zfs" ; do
for tool in "@bindir@/zgenhostid" "@sbindir@/zpool" "@sbindir@/zfs" "@mounthelperdir@/mount.zfs" ; do
test -x "$tool" || return 1
done
# Verify grep exists
@ -38,6 +38,7 @@ install() {
inst_rules @udevruledir@/60-zvol.rules
dracut_install hostid
dracut_install grep
dracut_install @bindir@/zgenhostid
dracut_install @sbindir@/zfs
dracut_install @sbindir@/zpool
# Workaround for zfsonlinux/zfs#4749 by ensuring libgcc_s.so(.1) is included
@ -83,11 +84,7 @@ install() {
fi
# Synchronize initramfs and system hostid
AA=`hostid | cut -b 1,2`
BB=`hostid | cut -b 3,4`
CC=`hostid | cut -b 5,6`
DD=`hostid | cut -b 7,8`
echo -ne "\\x${DD}\\x${CC}\\x${BB}\\x${AA}" > "${initdir}/etc/hostid"
zgenhostid -o "${initdir}/etc/hostid" "$(hostid)"
if dracut_module_included "systemd"; then
mkdir -p "${initdir}/$systemdsystemunitdir/zfs-import.target.wants"

View File

@ -6,11 +6,7 @@
spl_hostid=$(getarg spl_hostid=)
if [ -n "${spl_hostid}" ] ; then
info "ZFS: Using hostid from command line: ${spl_hostid}"
AA=$(echo "${spl_hostid}" | cut -b 1,2)
BB=$(echo "${spl_hostid}" | cut -b 3,4)
CC=$(echo "${spl_hostid}" | cut -b 5,6)
DD=$(echo "${spl_hostid}" | cut -b 7,8)
echo -ne "\\x${DD}\\x${CC}\\x${BB}\\x${AA}" >/etc/hostid
zgenhostid -f "${spl_hostid}"
elif [ -f "/etc/hostid" ] ; then
info "ZFS: Using hostid from /etc/hostid: $(hostid)"
else

View File

@ -15,6 +15,7 @@ USER_H = \
libuutil.h \
libuutil_impl.h \
libzfs.h \
libzfsbootenv.h \
libzfs_core.h \
libzfs_impl.h \
libzutil.h \

View File

@ -892,8 +892,8 @@ extern int zpool_in_use(libzfs_handle_t *, int, pool_state_t *, char **,
* Label manipulation.
*/
extern int zpool_clear_label(int);
extern int zpool_set_bootenv(zpool_handle_t *, const char *);
extern int zpool_get_bootenv(zpool_handle_t *, char *, size_t, off_t);
extern int zpool_set_bootenv(zpool_handle_t *, const nvlist_t *);
extern int zpool_get_bootenv(zpool_handle_t *, nvlist_t **);
/*
* Management interfaces for SMB ACL files

View File

@ -135,7 +135,7 @@ int lzc_wait(const char *, zpool_wait_activity_t, boolean_t *);
int lzc_wait_tag(const char *, zpool_wait_activity_t, uint64_t, boolean_t *);
int lzc_wait_fs(const char *, zfs_wait_activity_t, boolean_t *);
int lzc_set_bootenv(const char *, const char *);
int lzc_set_bootenv(const char *, const nvlist_t *);
int lzc_get_bootenv(const char *, nvlist_t **);
#ifdef __cplusplus
}

View File

@ -0,0 +1,41 @@
/*
* 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 2020 Toomas Soome <tsoome@me.com>
*/
#ifndef _LIBZFSBOOTENV_H
#define _LIBZFSBOOTENV_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum lzbe_flags {
lzbe_add, /* add data to existing nvlist */
lzbe_replace /* replace current nvlist */
} lzbe_flags_t;
extern int lzbe_nvlist_get(const char *, const char *, void **);
extern int lzbe_nvlist_set(const char *, const char *, void *);
extern void lzbe_nvlist_free(void *);
extern int lzbe_add_pair(void *, const char *, const char *, void *, size_t);
extern int lzbe_remove_pair(void *, const char *);
extern int lzbe_set_boot_device(const char *, lzbe_flags_t, const char *);
extern int lzbe_get_boot_device(const char *, char **);
extern int lzbe_bootenv_print(const char *, const char *, FILE *);
#ifdef __cplusplus
}
#endif
#endif /* _LIBZFSBOOTENV_H */

View File

@ -206,8 +206,10 @@ typedef int enum_t;
#define __XSI_VISIBLE 1000
#endif
#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a[0]))
#define open64 open
#define mmap64 mmap
/* Note: this file can be used on linux/macOS when bootstrapping tools. */
#if defined(__FreeBSD__)
#define open64 open
#define pwrite64 pwrite
#define ftruncate64 ftruncate
#define lseek64 lseek
@ -217,6 +219,7 @@ typedef int enum_t;
#define statfs64 statfs
#define readdir64 readdir
#define dirent64 dirent
#endif
#define P2ALIGN(x, align) ((x) & -(align))
#define P2CROSS(x, y, align) (((x) ^ (y)) > (align) - 1)
#define P2ROUNDUP(x, align) ((((x) - 1) | ((align) - 1)) + 1)

View File

@ -142,8 +142,14 @@ cv_timedwait_sig(kcondvar_t *cvp, kmutex_t *mp, clock_t timo)
return (1);
}
#define cv_timedwait_io cv_timedwait
#define cv_timedwait_sig_io cv_timedwait_sig
#define cv_timedwait_io cv_timedwait
#define cv_timedwait_idle cv_timedwait
#define cv_timedwait_sig_io cv_timedwait_sig
#define cv_wait_io cv_wait
#define cv_wait_io_sig cv_wait_sig
#define cv_wait_idle cv_wait
#define cv_timedwait_io_hires cv_timedwait_hires
#define cv_timedwait_idle_hires cv_timedwait_hires
static inline int
cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim, hrtime_t res,

View File

@ -2,6 +2,7 @@ KERNEL_H = \
freebsd_crypto.h \
sha2.h \
vdev_os.h \
zfs_bootenv_os.h \
zfs_context_os.h \
zfs_ctldir.h \
zfs_dir.h \

View File

@ -0,0 +1,29 @@
/*
* 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 2020 Toomas Soome <tsoome@me.com>
*/
#ifndef _ZFS_BOOTENV_OS_H
#define _ZFS_BOOTENV_OS_H
#ifdef __cplusplus
extern "C" {
#endif
#define BOOTENV_OS BE_FREEBSD_VENDOR
#ifdef __cplusplus
}
#endif
#endif /* _ZFS_BOOTENV_OS_H */

View File

@ -41,9 +41,6 @@
#include <sys/ccompat.h>
#include <linux/types.h>
#define cv_wait_io(cv, mp) cv_wait(cv, mp)
#define cv_wait_io_sig(cv, mp) cv_wait_sig(cv, mp)
#define cond_resched() kern_yield(PRI_USER)
#define taskq_create_sysdc(a, b, d, e, p, dc, f) \
@ -75,7 +72,7 @@ extern struct mtx zfs_debug_mtx;
} \
} while (0)
#define MSEC_TO_TICK(msec) ((msec) / (MILLISEC / hz))
#define MSEC_TO_TICK(msec) (howmany((hrtime_t)(msec) * hz, MILLISEC))
extern int hz;
extern int tick;
typedef int fstrans_cookie_t;
@ -84,7 +81,6 @@ typedef int fstrans_cookie_t;
#define signal_pending(x) SIGPENDING(x)
#define current curthread
#define thread_join(x)
#define cv_wait_io(cv, mp) cv_wait(cv, mp)
typedef struct opensolaris_utsname utsname_t;
extern utsname_t *utsname(void);
extern int spa_import_rootpool(const char *name, bool checkpointrewind);

View File

@ -27,18 +27,31 @@
#ifndef _SYS_FS_ZFS_VFSOPS_H
#define _SYS_FS_ZFS_VFSOPS_H
#if __FreeBSD_version >= 1300109
#define TEARDOWN_INACTIVE_RMS
#endif
#include <sys/dataset_kstats.h>
#include <sys/list.h>
#include <sys/vfs.h>
#include <sys/zil.h>
#include <sys/sa.h>
#include <sys/rrwlock.h>
#ifdef TEARDOWN_INACTIVE_RMS
#include <sys/rmlock.h>
#endif
#include <sys/zfs_ioctl.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef TEARDOWN_INACTIVE_RMS
typedef struct rmslock zfs_teardown_lock_t;
#else
#define zfs_teardown_lock_t krwlock_t
#endif
typedef struct zfsvfs zfsvfs_t;
struct znode;
@ -67,7 +80,7 @@ struct zfsvfs {
boolean_t z_atime; /* enable atimes mount option */
boolean_t z_unmounted; /* unmounted */
rrmlock_t z_teardown_lock;
krwlock_t z_teardown_inactive_lock;
zfs_teardown_lock_t z_teardown_inactive_lock;
list_t z_all_znodes; /* all vnodes in the fs */
uint64_t z_nr_znodes; /* number of znodes in the fs */
kmutex_t z_znodes_lock; /* lock for z_all_znodes */
@ -98,6 +111,56 @@ struct zfsvfs {
struct task z_unlinked_drain_task;
};
#ifdef TEARDOWN_INACTIVE_RMS
#define ZFS_INIT_TEARDOWN_INACTIVE(zfsvfs) \
rms_init(&(zfsvfs)->z_teardown_inactive_lock, "zfs teardown inactive")
#define ZFS_DESTROY_TEARDOWN_INACTIVE(zfsvfs) \
rms_destroy(&(zfsvfs)->z_teardown_inactive_lock)
#define ZFS_TRYRLOCK_TEARDOWN_INACTIVE(zfsvfs) \
rms_try_rlock(&(zfsvfs)->z_teardown_inactive_lock)
#define ZFS_RLOCK_TEARDOWN_INACTIVE(zfsvfs) \
rms_rlock(&(zfsvfs)->z_teardown_inactive_lock)
#define ZFS_RUNLOCK_TEARDOWN_INACTIVE(zfsvfs) \
rms_runlock(&(zfsvfs)->z_teardown_inactive_lock)
#define ZFS_WLOCK_TEARDOWN_INACTIVE(zfsvfs) \
rms_wlock(&(zfsvfs)->z_teardown_inactive_lock)
#define ZFS_WUNLOCK_TEARDOWN_INACTIVE(zfsvfs) \
rms_wunlock(&(zfsvfs)->z_teardown_inactive_lock)
#define ZFS_TEARDOWN_INACTIVE_WLOCKED(zfsvfs) \
rms_wowned(&(zfsvfs)->z_teardown_inactive_lock)
#else
#define ZFS_INIT_TEARDOWN_INACTIVE(zfsvfs) \
rw_init(&(zfsvfs)->z_teardown_inactive_lock, NULL, RW_DEFAULT, NULL)
#define ZFS_DESTROY_TEARDOWN_INACTIVE(zfsvfs) \
rw_destroy(&(zfsvfs)->z_teardown_inactive_lock)
#define ZFS_TRYRLOCK_TEARDOWN_INACTIVE(zfsvfs) \
rw_tryenter(&(zfsvfs)->z_teardown_inactive_lock, RW_READER)
#define ZFS_RLOCK_TEARDOWN_INACTIVE(zfsvfs) \
rw_enter(&(zfsvfs)->z_teardown_inactive_lock, RW_READER)
#define ZFS_RUNLOCK_TEARDOWN_INACTIVE(zfsvfs) \
rw_exit(&(zfsvfs)->z_teardown_inactive_lock)
#define ZFS_WLOCK_TEARDOWN_INACTIVE(zfsvfs) \
rw_enter(&(zfsvfs)->z_teardown_inactive_lock, RW_WRITER)
#define ZFS_WUNLOCK_TEARDOWN_INACTIVE(zfsvfs) \
rw_exit(&(zfsvfs)->z_teardown_inactive_lock)
#define ZFS_TEARDOWN_INACTIVE_WLOCKED(zfsvfs) \
RW_WRITE_HELD(&(zfsvfs)->z_teardown_inactive_lock)
#endif
#define ZSB_XATTR 0x0001 /* Enable user xattrs */
/*
* Normal filesystems (those not under .zfs/snapshot) have a total

View File

@ -21,6 +21,7 @@
/*
* Copyright (C) 2016 Gvozden Neskovic <neskovic@gmail.com>.
* Copyright (c) 2020 by Delphix. All rights reserved.
*/
#ifndef _MOD_COMPAT_H
@ -71,6 +72,7 @@ enum scope_prefix_types {
zfs_txg,
zfs_vdev,
zfs_vdev_cache,
zfs_vdev_file,
zfs_vdev_mirror,
zfs_zevent,
zfs_zio,

View File

@ -80,15 +80,19 @@ extern void __cv_init(kcondvar_t *, char *, kcv_type_t, void *);
extern void __cv_destroy(kcondvar_t *);
extern void __cv_wait(kcondvar_t *, kmutex_t *);
extern void __cv_wait_io(kcondvar_t *, kmutex_t *);
extern void __cv_wait_idle(kcondvar_t *, kmutex_t *);
extern int __cv_wait_io_sig(kcondvar_t *, kmutex_t *);
extern int __cv_wait_sig(kcondvar_t *, kmutex_t *);
extern int __cv_timedwait(kcondvar_t *, kmutex_t *, clock_t);
extern int __cv_timedwait_io(kcondvar_t *, kmutex_t *, clock_t);
extern int __cv_timedwait_sig(kcondvar_t *, kmutex_t *, clock_t);
extern int __cv_timedwait_idle(kcondvar_t *, kmutex_t *, clock_t);
extern int cv_timedwait_hires(kcondvar_t *, kmutex_t *, hrtime_t,
hrtime_t res, int flag);
extern int cv_timedwait_sig_hires(kcondvar_t *, kmutex_t *, hrtime_t,
hrtime_t res, int flag);
extern int cv_timedwait_idle_hires(kcondvar_t *, kmutex_t *, hrtime_t,
hrtime_t res, int flag);
extern void __cv_signal(kcondvar_t *);
extern void __cv_broadcast(kcondvar_t *c);
@ -96,6 +100,7 @@ extern void __cv_broadcast(kcondvar_t *c);
#define cv_destroy(cvp) __cv_destroy(cvp)
#define cv_wait(cvp, mp) __cv_wait(cvp, mp)
#define cv_wait_io(cvp, mp) __cv_wait_io(cvp, mp)
#define cv_wait_idle(cvp, mp) __cv_wait_idle(cvp, mp)
#define cv_wait_io_sig(cvp, mp) __cv_wait_io_sig(cvp, mp)
#define cv_wait_sig(cvp, mp) __cv_wait_sig(cvp, mp)
#define cv_signal(cvp) __cv_signal(cvp)
@ -109,5 +114,7 @@ extern void __cv_broadcast(kcondvar_t *c);
#define cv_timedwait(cvp, mp, t) __cv_timedwait(cvp, mp, t)
#define cv_timedwait_io(cvp, mp, t) __cv_timedwait_io(cvp, mp, t)
#define cv_timedwait_sig(cvp, mp, t) __cv_timedwait_sig(cvp, mp, t)
#define cv_timedwait_idle(cvp, mp, t) __cv_timedwait_idle(cvp, mp, t)
#endif /* _SPL_CONDVAR_H */

View File

@ -16,6 +16,7 @@ KERNEL_H = \
trace_zil.h \
trace_zio.h \
trace_zrlock.h \
zfs_bootenv_os.h \
zfs_context_os.h \
zfs_ctldir.h \
zfs_dir.h \

View File

@ -0,0 +1,29 @@
/*
* 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 2020 Toomas Soome <tsoome@me.com>
*/
#ifndef _ZFS_BOOTENV_OS_H
#define _ZFS_BOOTENV_OS_H
#ifdef __cplusplus
extern "C" {
#endif
#define BOOTENV_OS BE_LINUX_VENDOR
#ifdef __cplusplus
}
#endif
#endif /* _ZFS_BOOTENV_OS_H */

View File

@ -102,6 +102,7 @@ COMMON_H = \
zcp_set.h \
zfeature.h \
zfs_acl.h \
zfs_bootenv.h \
zfs_context.h \
zfs_debug.h \
zfs_delay.h \

View File

@ -112,11 +112,11 @@ void dsl_sync_task_sync(dsl_sync_task_t *, dmu_tx_t *);
int dsl_sync_task(const char *, dsl_checkfunc_t *,
dsl_syncfunc_t *, void *, int, zfs_space_check_t);
void dsl_sync_task_nowait(struct dsl_pool *, dsl_syncfunc_t *,
void *, int, zfs_space_check_t, dmu_tx_t *);
void *, dmu_tx_t *);
int dsl_early_sync_task(const char *, dsl_checkfunc_t *,
dsl_syncfunc_t *, void *, int, zfs_space_check_t);
void dsl_early_sync_task_nowait(struct dsl_pool *, dsl_syncfunc_t *,
void *, int, zfs_space_check_t, dmu_tx_t *);
void *, dmu_tx_t *);
int dsl_sync_task_sig(const char *, dsl_checkfunc_t *, dsl_syncfunc_t *,
dsl_sigfunc_t *, void *, int, zfs_space_check_t);

View File

@ -23,6 +23,10 @@
* Use is subject to license terms.
*/
/*
* Copyright (c) 2020 by Delphix. All rights reserved.
*/
#ifndef _SYS_FM_FS_ZFS_H
#define _SYS_FM_FS_ZFS_H
@ -88,6 +92,7 @@ extern "C" {
#define FM_EREPORT_PAYLOAD_ZFS_ZIO_SIZE "zio_size"
#define FM_EREPORT_PAYLOAD_ZFS_ZIO_FLAGS "zio_flags"
#define FM_EREPORT_PAYLOAD_ZFS_ZIO_STAGE "zio_stage"
#define FM_EREPORT_PAYLOAD_ZFS_ZIO_PRIORITY "zio_priority"
#define FM_EREPORT_PAYLOAD_ZFS_ZIO_PIPELINE "zio_pipeline"
#define FM_EREPORT_PAYLOAD_ZFS_ZIO_DELAY "zio_delay"
#define FM_EREPORT_PAYLOAD_ZFS_ZIO_TIMESTAMP "zio_timestamp"

View File

@ -104,6 +104,9 @@ extern int zfs_zevent_seek(zfs_zevent_t *, uint64_t);
extern void zfs_zevent_init(zfs_zevent_t **);
extern void zfs_zevent_destroy(zfs_zevent_t *);
extern void zfs_zevent_track_duplicate(void);
extern void zfs_ereport_init(void);
extern void zfs_ereport_fini(void);
#else
static inline void fm_init(void) { }

View File

@ -1336,8 +1336,8 @@ typedef enum zfs_ioc {
ZFS_IOC_NEXTBOOT, /* 0x84 (FreeBSD) */
ZFS_IOC_JAIL, /* 0x85 (FreeBSD) */
ZFS_IOC_UNJAIL, /* 0x86 (FreeBSD) */
ZFS_IOC_SET_BOOTENV, /* 0x87 (Linux) */
ZFS_IOC_GET_BOOTENV, /* 0x88 (Linux) */
ZFS_IOC_SET_BOOTENV, /* 0x87 */
ZFS_IOC_GET_BOOTENV, /* 0x88 */
ZFS_IOC_LAST
} zfs_ioc_t;

View File

@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2019 by Delphix. All rights reserved.
* Copyright (c) 2011, 2020 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
* Copyright 2013 Saso Kiselkov. All rights reserved.
@ -1145,10 +1145,10 @@ extern const char *spa_state_to_name(spa_t *spa);
struct zbookmark_phys;
extern void spa_log_error(spa_t *spa, const zbookmark_phys_t *zb);
extern int zfs_ereport_post(const char *clazz, spa_t *spa, vdev_t *vd,
const zbookmark_phys_t *zb, zio_t *zio, uint64_t stateoroffset,
uint64_t length);
const zbookmark_phys_t *zb, zio_t *zio, uint64_t state);
extern boolean_t zfs_ereport_is_valid(const char *clazz, spa_t *spa, vdev_t *vd,
zio_t *zio);
extern void zfs_ereport_taskq_fini(void);
extern nvlist_t *zfs_event_create(spa_t *spa, vdev_t *vd, const char *type,
const char *name, nvlist_t *aux);
extern void zfs_post_remove(spa_t *spa, vdev_t *vd);

View File

@ -94,7 +94,6 @@ extern void vdev_rele(vdev_t *);
extern int vdev_metaslab_init(vdev_t *vd, uint64_t txg);
extern void vdev_metaslab_fini(vdev_t *vd);
extern void vdev_metaslab_set_size(vdev_t *);
extern void vdev_ashift_optimize(vdev_t *);
extern void vdev_expand(vdev_t *vd, uint64_t txg);
extern void vdev_split(vdev_t *vd);
extern void vdev_deadman(vdev_t *vd, char *tag);
@ -181,7 +180,7 @@ extern void vdev_config_generate_stats(vdev_t *vd, nvlist_t *nv);
extern void vdev_label_write(zio_t *zio, vdev_t *vd, int l, abd_t *buf, uint64_t
offset, uint64_t size, zio_done_func_t *done, void *priv, int flags);
extern int vdev_label_read_bootenv(vdev_t *, nvlist_t *);
extern int vdev_label_write_bootenv(vdev_t *, char *);
extern int vdev_label_write_bootenv(vdev_t *, nvlist_t *);
typedef enum {
VDEV_LABEL_CREATE, /* create/add a new device */

View File

@ -476,7 +476,16 @@ typedef struct vdev_phys {
} vdev_phys_t;
typedef enum vbe_vers {
/* The bootenv file is stored as ascii text in the envblock */
/*
* The bootenv file is stored as ascii text in the envblock.
* It is used by the GRUB bootloader used on Linux to store the
* contents of the grubenv file. The file is stored as raw ASCII,
* and is protected by an embedded checksum. By default, GRUB will
* check if the boot filesystem supports storing the environment data
* in a special location, and if so, will invoke filesystem specific
* logic to retrieve it. This can be overriden by a variable, should
* the user so desire.
*/
VB_RAW = 0,
/*

View File

@ -0,0 +1,53 @@
/*
* 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 2020 Toomas Soome <tsoome@me.com>
*/
#ifndef _ZFS_BOOTENV_H
#define _ZFS_BOOTENV_H
/*
* Define macros for label bootenv nvlist pair keys.
*/
#ifdef __cplusplus
extern "C" {
#endif
#define BOOTENV_VERSION "version"
#define BE_ILLUMOS_VENDOR "illumos"
#define BE_FREEBSD_VENDOR "freebsd"
#define BE_GRUB_VENDOR "grub"
#define BE_LINUX_VENDOR "linux"
#include <sys/zfs_bootenv_os.h>
#define GRUB_ENVMAP BE_GRUB_VENDOR ":" "envmap"
#define FREEBSD_BOOTONCE BE_FREEBSD_VENDOR ":" "bootonce"
#define FREEBSD_BOOTONCE_USED BE_FREEBSD_VENDOR ":" "bootonce-used"
#define FREEBSD_NVSTORE BE_FREEBSD_VENDOR ":" "nvstore"
#define ILLUMOS_BOOTONCE BE_ILLUMOS_VENDOR ":" "bootonce"
#define ILLUMOS_BOOTONCE_USED BE_ILLUMOS_VENDOR ":" "bootonce-used"
#define ILLUMOS_NVSTORE BE_ILLUMOS_VENDOR ":" "nvstore"
#define OS_BOOTONCE BOOTENV_OS ":" "bootonce"
#define OS_BOOTONCE_USED BOOTENV_OS ":" "bootonce-used"
#define OS_NVSTORE BOOTENV_OS ":" "nvstore"
#ifdef __cplusplus
}
#endif
#endif /* _ZFS_BOOTENV_H */

View File

@ -325,11 +325,15 @@ extern void cv_signal(kcondvar_t *cv);
extern void cv_broadcast(kcondvar_t *cv);
#define cv_timedwait_io(cv, mp, at) cv_timedwait(cv, mp, at)
#define cv_timedwait_idle(cv, mp, at) cv_timedwait(cv, mp, at)
#define cv_timedwait_sig(cv, mp, at) cv_timedwait(cv, mp, at)
#define cv_wait_io(cv, mp) cv_wait(cv, mp)
#define cv_wait_idle(cv, mp) cv_wait(cv, mp)
#define cv_wait_io_sig(cv, mp) cv_wait_sig(cv, mp)
#define cv_timedwait_sig_hires(cv, mp, t, r, f) \
cv_timedwait_hires(cv, mp, t, r, f)
#define cv_timedwait_idle_hires(cv, mp, t, r, f) \
cv_timedwait_hires(cv, mp, t, r, f)
/*
* Thread-specific data
@ -598,9 +602,9 @@ typedef struct vsecattr {
extern void delay(clock_t ticks);
#define SEC_TO_TICK(sec) ((sec) * hz)
#define MSEC_TO_TICK(msec) ((msec) / (MILLISEC / hz))
#define USEC_TO_TICK(usec) ((usec) / (MICROSEC / hz))
#define NSEC_TO_TICK(usec) ((usec) / (NANOSEC / hz))
#define MSEC_TO_TICK(msec) (howmany((hrtime_t)(msec) * hz, MILLISEC))
#define USEC_TO_TICK(usec) (howmany((hrtime_t)(usec) * hz, MICROSEC))
#define NSEC_TO_TICK(nsec) (howmany((hrtime_t)(nsec) * hz, NANOSEC))
#define max_ncpus 64
#define boot_ncpus (sysconf(_SC_NPROCESSORS_ONLN))

View File

@ -67,7 +67,7 @@ extern "C" {
* Property values for acltype
*/
#define ZFS_ACLTYPE_OFF 0
#define ZFS_ACLTYPE_POSIXACL 1
#define ZFS_ACLTYPE_POSIX 1
/*
* Field manipulation macros for the drr_versioninfo field of the

View File

@ -22,7 +22,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2012, 2020 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright 2016 Toomas Soome <tsoome@me.com>
@ -680,7 +680,7 @@ extern hrtime_t zio_handle_io_delay(zio_t *zio);
/*
* Checksum ereport functions
*/
extern void zfs_ereport_start_checksum(spa_t *spa, vdev_t *vd,
extern int zfs_ereport_start_checksum(spa_t *spa, vdev_t *vd,
const zbookmark_phys_t *zb, struct zio *zio, uint64_t offset,
uint64_t length, void *arg, struct zio_bad_cksum *info);
extern void zfs_ereport_finish_checksum(zio_cksum_report_t *report,

View File

@ -6,9 +6,13 @@ if BUILD_LINUX
SUBDIRS += libefi
endif
# libnvpair is installed as part of the final build product
# libzutil depends on it, so it must be compiled before libzutil
SUBDIRS += libnvpair
# libzutil depends on libefi if present
SUBDIRS += libzutil libunicode
# These five libraries, which are installed as the final build product,
# incorporate the eight convenience libraries given above.
SUBDIRS += libuutil libnvpair libzfs_core libzfs libzpool
SUBDIRS += libuutil libzfs_core libzfs libzpool libzfsbootenv

View File

@ -44,6 +44,7 @@
#include <sys/byteorder.h>
#include <sys/vdev_disk.h>
#include <linux/fs.h>
#include <linux/blkpg.h>
static struct uuid_to_ptag {
struct uuid uuid;
@ -209,19 +210,40 @@ read_disk_info(int fd, diskaddr_t *capacity, uint_t *lbsize)
return (0);
}
/*
* Return back the device name associated with the file descriptor. The
* caller is responsible for freeing the memory associated with the
* returned string.
*/
static char *
efi_get_devname(int fd)
{
char *path;
char *dev_name;
path = calloc(1, PATH_MAX);
if (path == NULL)
return (NULL);
/*
* The libefi API only provides the open fd and not the file path.
* To handle this realpath(3) is used to resolve the block device
* name from /proc/self/fd/<fd>.
*/
(void) sprintf(path, "/proc/self/fd/%d", fd);
dev_name = realpath(path, NULL);
free(path);
return (dev_name);
}
static int
efi_get_info(int fd, struct dk_cinfo *dki_info)
{
char *path;
char *dev_path;
int rval = 0;
memset(dki_info, 0, sizeof (*dki_info));
path = calloc(1, PATH_MAX);
if (path == NULL)
goto error;
/*
* The simplest way to get the partition number under linux is
* to parse it out of the /dev/<disk><partition> block device name.
@ -229,16 +251,10 @@ efi_get_info(int fd, struct dk_cinfo *dki_info)
* populates /dev/ so it may be trusted. The tricky bit here is
* that the naming convention is based on the block device type.
* So we need to take this in to account when parsing out the
* partition information. Another issue is that the libefi API
* API only provides the open fd and not the file path. To handle
* this realpath(3) is used to resolve the block device name from
* /proc/self/fd/<fd>. Aside from the partition number we collect
* partition information. Aside from the partition number we collect
* some additional device info.
*/
(void) sprintf(path, "/proc/self/fd/%d", fd);
dev_path = realpath(path, NULL);
free(path);
dev_path = efi_get_devname(fd);
if (dev_path == NULL)
goto error;
@ -1108,20 +1124,49 @@ check_input(struct dk_gpt *vtoc)
return (0);
}
static int
call_blkpg_ioctl(int fd, int command, diskaddr_t start,
diskaddr_t size, uint_t pno)
{
struct blkpg_ioctl_arg ioctl_arg;
struct blkpg_partition linux_part;
memset(&linux_part, 0, sizeof (linux_part));
char *path = efi_get_devname(fd);
if (path == NULL) {
(void) fprintf(stderr, "failed to retrieve device name\n");
return (VT_EINVAL);
}
linux_part.start = start;
linux_part.length = size;
linux_part.pno = pno;
snprintf(linux_part.devname, BLKPG_DEVNAMELTH - 1, "%s%u", path, pno);
linux_part.devname[BLKPG_DEVNAMELTH - 1] = '\0';
free(path);
ioctl_arg.op = command;
ioctl_arg.flags = 0;
ioctl_arg.datalen = sizeof (struct blkpg_partition);
ioctl_arg.data = &linux_part;
return (ioctl(fd, BLKPG, &ioctl_arg));
}
/*
* add all the unallocated space to the current label
*/
int
efi_use_whole_disk(int fd)
{
struct dk_gpt *efi_label = NULL;
int rval;
int i;
uint_t resv_index = 0, data_index = 0;
diskaddr_t resv_start = 0, data_start = 0;
diskaddr_t data_size, limit, difference;
boolean_t sync_needed = B_FALSE;
uint_t nblocks;
struct dk_gpt *efi_label = NULL;
int rval;
int i;
uint_t resv_index = 0, data_index = 0;
diskaddr_t resv_start = 0, data_start = 0;
diskaddr_t data_size, limit, difference;
boolean_t sync_needed = B_FALSE;
uint_t nblocks;
rval = efi_alloc_and_read(fd, &efi_label);
if (rval < 0) {
@ -1255,19 +1300,73 @@ efi_use_whole_disk(int fd)
efi_label->efi_parts[resv_index].p_start += difference;
efi_label->efi_last_u_lba = efi_label->efi_last_lba - nblocks;
rval = efi_write(fd, efi_label);
if (rval < 0) {
if (efi_debug) {
(void) fprintf(stderr,
"efi_use_whole_disk:fail to write label, rval=%d\n",
rval);
}
efi_free(efi_label);
return (rval);
/*
* Rescanning the partition table in the kernel can result
* in the device links to be removed (see comment in vdev_disk_open).
* If BLKPG_RESIZE_PARTITION is available, then we can resize
* the partition table online and avoid having to remove the device
* links used by the pool. This provides a very deterministic
* approach to resizing devices and does not require any
* loops waiting for devices to reappear.
*/
#ifdef BLKPG_RESIZE_PARTITION
/*
* Delete the reserved partition since we're about to expand
* the data partition and it would overlap with the reserved
* partition.
* NOTE: The starting index for the ioctl is 1 while for the
* EFI partitions it's 0. For that reason we have to add one
* whenever we make an ioctl call.
*/
rval = call_blkpg_ioctl(fd, BLKPG_DEL_PARTITION, 0, 0, resv_index + 1);
if (rval != 0)
goto out;
/*
* Expand the data partition
*/
rval = call_blkpg_ioctl(fd, BLKPG_RESIZE_PARTITION,
efi_label->efi_parts[data_index].p_start * efi_label->efi_lbasize,
efi_label->efi_parts[data_index].p_size * efi_label->efi_lbasize,
data_index + 1);
if (rval != 0) {
(void) fprintf(stderr, "Unable to resize data "
"partition: %d\n", rval);
/*
* Since we failed to resize, we need to reset the start
* of the reserve partition and re-create it.
*/
efi_label->efi_parts[resv_index].p_start -= difference;
}
/*
* Re-add the reserved partition. If we've expanded the data partition
* then we'll move the reserve partition to the end of the data
* partition. Otherwise, we'll recreate the partition in its original
* location. Note that we do this as best-effort and ignore any
* errors that may arise here. This will ensure that we finish writing
* the EFI label.
*/
(void) call_blkpg_ioctl(fd, BLKPG_ADD_PARTITION,
efi_label->efi_parts[resv_index].p_start * efi_label->efi_lbasize,
efi_label->efi_parts[resv_index].p_size * efi_label->efi_lbasize,
resv_index + 1);
#endif
/*
* We're now ready to write the EFI label.
*/
if (rval == 0) {
rval = efi_write(fd, efi_label);
if (rval < 0 && efi_debug) {
(void) fprintf(stderr, "efi_use_whole_disk:fail "
"to write label, rval=%d\n", rval);
}
}
out:
efi_free(efi_label);
return (0);
return (rval);
}
/*

View File

@ -31,6 +31,7 @@
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/types.h>

View File

@ -28,6 +28,8 @@
#include_next <sys/stat.h>
/* Note: this file can be used on linux/macOS when bootstrapping tools. */
#if defined(__FreeBSD__)
#include <sys/mount.h> /* for BLKGETSIZE64 */
#define stat64 stat
@ -68,4 +70,5 @@ fstat64_blk(int fd, struct stat64 *st)
return (0);
}
#endif /* defined(__FreeBSD__) */
#endif /* _LIBSPL_SYS_STAT_H */

View File

@ -6,9 +6,9 @@ includedir=@includedir@
Name: libzfs
Description: LibZFS library
Version: @VERSION@
URL: https://zfsonlinux.org
URL: https://github.com/openzfs/zfs
Requires: libzfs_core
Requires.private: libcrypto zlib
Requires.private: @LIBCRYPTO_PC@ @ZLIB_PC@
Cflags: -I${includedir}/libzfs -I${includedir}/libspl
Libs: -L${libdir} -lzfs -lnvpair
Libs.private: -luutil -lm -pthread

View File

@ -2893,11 +2893,12 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
case ZFS_PROP_GUID:
case ZFS_PROP_CREATETXG:
case ZFS_PROP_OBJSETID:
case ZFS_PROP_PBKDF2_ITERS:
/*
* These properties are stored as numbers, but they are
* identifiers.
* identifiers or counters.
* We don't want them to be pretty printed, because pretty
* printing mangles the ID into a truncated and useless value.
* printing truncates their values making them useless.
*/
if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
return (-1);

View File

@ -4495,7 +4495,7 @@ zpool_wait_status(zpool_handle_t *zhp, zpool_wait_activity_t activity,
}
int
zpool_set_bootenv(zpool_handle_t *zhp, const char *envmap)
zpool_set_bootenv(zpool_handle_t *zhp, const nvlist_t *envmap)
{
int error = lzc_set_bootenv(zhp->zpool_name, envmap);
if (error != 0) {
@ -4508,24 +4508,20 @@ zpool_set_bootenv(zpool_handle_t *zhp, const char *envmap)
}
int
zpool_get_bootenv(zpool_handle_t *zhp, char *outbuf, size_t size, off_t offset)
zpool_get_bootenv(zpool_handle_t *zhp, nvlist_t **nvlp)
{
nvlist_t *nvl = NULL;
int error = lzc_get_bootenv(zhp->zpool_name, &nvl);
nvlist_t *nvl;
int error;
nvl = NULL;
error = lzc_get_bootenv(zhp->zpool_name, &nvl);
if (error != 0) {
(void) zpool_standard_error_fmt(zhp->zpool_hdl, error,
dgettext(TEXT_DOMAIN,
"error getting bootenv in pool '%s'"), zhp->zpool_name);
return (-1);
}
char *envmap = fnvlist_lookup_string(nvl, "envmap");
if (offset >= strlen(envmap)) {
fnvlist_free(nvl);
return (0);
} else {
*nvlp = nvl;
}
strncpy(outbuf, envmap + offset, size);
int bytes = MIN(strlen(envmap + offset), size);
fnvlist_free(nvl);
return (bytes);
return (error);
}

View File

@ -2640,6 +2640,7 @@ recv_read_nvlist(libzfs_handle_t *hdl, int fd, int len, nvlist_t **nvp,
if (len > hdl->libzfs_max_nvlist) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "nvlist too large"));
free(buf);
return (ENOMEM);
}

View File

@ -1060,6 +1060,9 @@ libzfs_init(void)
if ((error = zfs_nicestrtonum(hdl, env,
&hdl->libzfs_max_nvlist))) {
errno = error;
(void) close(hdl->libzfs_fd);
(void) fclose(hdl->libzfs_mnttab);
free(hdl);
return (NULL);
}
} else {

View File

@ -72,9 +72,6 @@ zpool_relabel_disk(libzfs_handle_t *hdl, const char *path, const char *msg)
* It's possible that we might encounter an error if the device
* does not have any unallocated space left. If so, we simply
* ignore that error and continue on.
*
* Also, we don't call efi_rescan() - that would just return EBUSY.
* The module will do it for us in vdev_disk_open().
*/
error = efi_use_whole_disk(fd);

View File

@ -1625,13 +1625,9 @@ lzc_wait_fs(const char *fs, zfs_wait_activity_t activity, boolean_t *waited)
* Set the bootenv contents for the given pool.
*/
int
lzc_set_bootenv(const char *pool, const char *env)
lzc_set_bootenv(const char *pool, const nvlist_t *env)
{
nvlist_t *args = fnvlist_alloc();
fnvlist_add_string(args, "envmap", env);
int error = lzc_ioctl(ZFS_IOC_SET_BOOTENV, pool, args, NULL);
fnvlist_free(args);
return (error);
return (lzc_ioctl(ZFS_IOC_SET_BOOTENV, pool, (nvlist_t *)env, NULL));
}
/*

View File

@ -6,8 +6,8 @@ includedir=@includedir@
Name: libzfs_core
Description: LibZFS core library
Version: @VERSION@
URL: https://zfsonlinux.org
Requires.private: blkid uuid libtirpc zlib
URL: https://github.com/openzfs/zfs
Requires.private: @LIBBLKID_PC@ @LIBUUID_PC@ @LIBTIRPC_PC@ @ZLIB_PC@
Cflags: -I${includedir}/libzfs -I${includedir}/libspl
Libs: -L${libdir} -lzfs_core -lnvpair
Libs.private: @LIBCLOCK_GETTIME@ @LIBUDEV_LIBS@ -lm -pthread

View File

@ -0,0 +1 @@
/libzfsbootenv.pc

View File

@ -0,0 +1,32 @@
include $(top_srcdir)/config/Rules.am
pkgconfig_DATA = libzfsbootenv.pc
lib_LTLIBRARIES = libzfsbootenv.la
if BUILD_FREEBSD
DEFAULT_INCLUDES += -I$(top_srcdir)/include/os/freebsd/zfs
endif
if BUILD_LINUX
DEFAULT_INCLUDES += -I$(top_srcdir)/include/os/linux/zfs
endif
USER_C = \
lzbe_device.c \
lzbe_pair.c \
lzbe_util.c
dist_libzfsbootenv_la_SOURCES = \
$(USER_C)
libzfsbootenv_la_LIBADD = \
$(abs_top_builddir)/lib/libzfs/libzfs.la \
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
libzfsbootenv_la_LDFLAGS =
if !ASAN_ENABLED
libzfsbootenv_la_LDFLAGS += -Wl,-z,defs
endif
libzfsbootenv_la_LDFLAGS += -version-info 1:0:0

View File

@ -0,0 +1,12 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libzfsbootenv
Description: LibZFSBootENV library
Version: @VERSION@
URL: https://zfsonlinux.org
Requires: libzfs libnvpair
Cflags: -I${includedir}
Libs: -L${libdir} -lzfsbootenv

View File

@ -0,0 +1,164 @@
/*
* 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 2020 Toomas Soome <tsoome@me.com>
*/
#include <sys/types.h>
#include <string.h>
#include <libzfs.h>
#include <libzfsbootenv.h>
#include <sys/zfs_bootenv.h>
#include <sys/vdev_impl.h>
/*
* Store device name to zpool label bootenv area.
* This call will set bootenv version to VB_NVLIST, if bootenv currently
* does contain other version, then old data will be replaced.
*/
int
lzbe_set_boot_device(const char *pool, lzbe_flags_t flag, const char *device)
{
libzfs_handle_t *hdl;
zpool_handle_t *zphdl;
nvlist_t *nv;
char *descriptor;
uint64_t version;
int rv = -1;
if (pool == NULL || *pool == '\0')
return (rv);
if ((hdl = libzfs_init()) == NULL)
return (rv);
zphdl = zpool_open(hdl, pool);
if (zphdl == NULL) {
libzfs_fini(hdl);
return (rv);
}
switch (flag) {
case lzbe_add:
rv = zpool_get_bootenv(zphdl, &nv);
if (rv == 0) {
/*
* We got the nvlist, check for version.
* if version is missing or is not VB_NVLIST,
* create new list.
*/
rv = nvlist_lookup_uint64(nv, BOOTENV_VERSION,
&version);
if (rv == 0 && version == VB_NVLIST)
break;
/* Drop this nvlist */
fnvlist_free(nv);
}
/* FALLTHROUGH */
case lzbe_replace:
nv = fnvlist_alloc();
break;
default:
return (rv);
}
/* version is mandatory */
fnvlist_add_uint64(nv, BOOTENV_VERSION, VB_NVLIST);
/*
* If device name is empty, remove boot device configuration.
*/
if ((device == NULL || *device == '\0')) {
if (nvlist_exists(nv, OS_BOOTONCE))
fnvlist_remove(nv, OS_BOOTONCE);
} else {
/*
* Use device name directly if it does start with
* prefix "zfs:". Otherwise, add prefix and sufix.
*/
if (strncmp(device, "zfs:", 4) == 0) {
fnvlist_add_string(nv, OS_BOOTONCE, device);
} else {
descriptor = NULL;
if (asprintf(&descriptor, "zfs:%s:", device) > 0)
fnvlist_add_string(nv, OS_BOOTONCE, descriptor);
else
rv = ENOMEM;
free(descriptor);
}
}
rv = zpool_set_bootenv(zphdl, nv);
if (rv != 0)
fprintf(stderr, "%s\n", libzfs_error_description(hdl));
fnvlist_free(nv);
zpool_close(zphdl);
libzfs_fini(hdl);
return (rv);
}
/*
* Return boot device name from bootenv, if set.
*/
int
lzbe_get_boot_device(const char *pool, char **device)
{
libzfs_handle_t *hdl;
zpool_handle_t *zphdl;
nvlist_t *nv;
char *val;
int rv = -1;
if (pool == NULL || *pool == '\0' || device == NULL)
return (rv);
if ((hdl = libzfs_init()) == NULL)
return (rv);
zphdl = zpool_open(hdl, pool);
if (zphdl == NULL) {
libzfs_fini(hdl);
return (rv);
}
rv = zpool_get_bootenv(zphdl, &nv);
if (rv == 0) {
rv = nvlist_lookup_string(nv, OS_BOOTONCE, &val);
if (rv == 0) {
/*
* zfs device descriptor is in form of "zfs:dataset:",
* we only do need dataset name.
*/
if (strncmp(val, "zfs:", 4) == 0) {
val += 4;
val = strdup(val);
if (val != NULL) {
size_t len = strlen(val);
if (val[len - 1] == ':')
val[len - 1] = '\0';
*device = val;
} else {
rv = ENOMEM;
}
} else {
rv = EINVAL;
}
}
nvlist_free(nv);
}
zpool_close(zphdl);
libzfs_fini(hdl);
return (rv);
}

View File

@ -0,0 +1,347 @@
/*
* 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 2020 Toomas Soome <tsoome@me.com>
*/
#include <sys/types.h>
#include <string.h>
#include <libzfs.h>
#include <libzfsbootenv.h>
#include <sys/zfs_bootenv.h>
#include <sys/vdev_impl.h>
/*
* Get or create nvlist. If key is not NULL, get nvlist from bootenv,
* otherwise return bootenv.
*/
int
lzbe_nvlist_get(const char *pool, const char *key, void **ptr)
{
libzfs_handle_t *hdl;
zpool_handle_t *zphdl;
nvlist_t *nv;
int rv = -1;
if (pool == NULL || *pool == '\0')
return (rv);
if ((hdl = libzfs_init()) == NULL) {
return (rv);
}
zphdl = zpool_open(hdl, pool);
if (zphdl == NULL) {
libzfs_fini(hdl);
return (rv);
}
rv = zpool_get_bootenv(zphdl, &nv);
if (rv == 0) {
nvlist_t *nvl, *dup;
if (key != NULL) {
rv = nvlist_lookup_nvlist(nv, key, &nvl);
if (rv == 0) {
rv = nvlist_dup(nvl, &dup, 0);
nvlist_free(nv);
if (rv == 0)
nv = dup;
else
nv = NULL;
} else {
nvlist_free(nv);
rv = nvlist_alloc(&nv, NV_UNIQUE_NAME, 0);
}
}
*ptr = nv;
}
zpool_close(zphdl);
libzfs_fini(hdl);
return (rv);
}
int
lzbe_nvlist_set(const char *pool, const char *key, void *ptr)
{
libzfs_handle_t *hdl;
zpool_handle_t *zphdl;
nvlist_t *nv;
uint64_t version;
int rv = -1;
if (pool == NULL || *pool == '\0')
return (rv);
if ((hdl = libzfs_init()) == NULL) {
return (rv);
}
zphdl = zpool_open(hdl, pool);
if (zphdl == NULL) {
libzfs_fini(hdl);
return (rv);
}
if (key != NULL) {
rv = zpool_get_bootenv(zphdl, &nv);
if (rv == 0) {
/*
* We got the nvlist, check for version.
* if version is missing or is not VB_NVLIST,
* create new list.
*/
rv = nvlist_lookup_uint64(nv, BOOTENV_VERSION,
&version);
if (rv != 0 || version != VB_NVLIST) {
/* Drop this nvlist */
fnvlist_free(nv);
/* Create and prepare new nvlist */
nv = fnvlist_alloc();
fnvlist_add_uint64(nv, BOOTENV_VERSION,
VB_NVLIST);
}
rv = nvlist_add_nvlist(nv, key, ptr);
if (rv == 0)
rv = zpool_set_bootenv(zphdl, nv);
nvlist_free(nv);
}
} else {
rv = zpool_set_bootenv(zphdl, ptr);
}
zpool_close(zphdl);
libzfs_fini(hdl);
return (rv);
}
/*
* free nvlist we got via lzbe_nvlist_get()
*/
void
lzbe_nvlist_free(void *ptr)
{
nvlist_free(ptr);
}
static const char *typenames[] = {
"DATA_TYPE_UNKNOWN",
"DATA_TYPE_BOOLEAN",
"DATA_TYPE_BYTE",
"DATA_TYPE_INT16",
"DATA_TYPE_UINT16",
"DATA_TYPE_INT32",
"DATA_TYPE_UINT32",
"DATA_TYPE_INT64",
"DATA_TYPE_UINT64",
"DATA_TYPE_STRING",
"DATA_TYPE_BYTE_ARRAY",
"DATA_TYPE_INT16_ARRAY",
"DATA_TYPE_UINT16_ARRAY",
"DATA_TYPE_INT32_ARRAY",
"DATA_TYPE_UINT32_ARRAY",
"DATA_TYPE_INT64_ARRAY",
"DATA_TYPE_UINT64_ARRAY",
"DATA_TYPE_STRING_ARRAY",
"DATA_TYPE_HRTIME",
"DATA_TYPE_NVLIST",
"DATA_TYPE_NVLIST_ARRAY",
"DATA_TYPE_BOOLEAN_VALUE",
"DATA_TYPE_INT8",
"DATA_TYPE_UINT8",
"DATA_TYPE_BOOLEAN_ARRAY",
"DATA_TYPE_INT8_ARRAY",
"DATA_TYPE_UINT8_ARRAY"
};
static int
nvpair_type_from_name(const char *name)
{
unsigned i;
for (i = 0; i < ARRAY_SIZE(typenames); i++) {
if (strcmp(name, typenames[i]) == 0)
return (i);
}
return (0);
}
/*
* Add pair defined by key, type and value into nvlist.
*/
int
lzbe_add_pair(void *ptr, const char *key, const char *type, void *value,
size_t size)
{
nvlist_t *nv = ptr;
data_type_t dt;
int rv = 0;
if (ptr == NULL || key == NULL || value == NULL)
return (rv);
if (type == NULL)
type = "DATA_TYPE_STRING";
dt = nvpair_type_from_name(type);
if (dt == DATA_TYPE_UNKNOWN)
return (EINVAL);
switch (dt) {
case DATA_TYPE_BYTE:
if (size != sizeof (uint8_t)) {
rv = EINVAL;
break;
}
rv = nvlist_add_byte(nv, key, *(uint8_t *)value);
break;
case DATA_TYPE_INT16:
if (size != sizeof (int16_t)) {
rv = EINVAL;
break;
}
rv = nvlist_add_int16(nv, key, *(int16_t *)value);
break;
case DATA_TYPE_UINT16:
if (size != sizeof (uint16_t)) {
rv = EINVAL;
break;
}
rv = nvlist_add_uint16(nv, key, *(uint16_t *)value);
break;
case DATA_TYPE_INT32:
if (size != sizeof (int32_t)) {
rv = EINVAL;
break;
}
rv = nvlist_add_int32(nv, key, *(int32_t *)value);
break;
case DATA_TYPE_UINT32:
if (size != sizeof (uint32_t)) {
rv = EINVAL;
break;
}
rv = nvlist_add_uint32(nv, key, *(uint32_t *)value);
break;
case DATA_TYPE_INT64:
if (size != sizeof (int64_t)) {
rv = EINVAL;
break;
}
rv = nvlist_add_int64(nv, key, *(int64_t *)value);
break;
case DATA_TYPE_UINT64:
if (size != sizeof (uint64_t)) {
rv = EINVAL;
break;
}
rv = nvlist_add_uint64(nv, key, *(uint64_t *)value);
break;
case DATA_TYPE_STRING:
rv = nvlist_add_string(nv, key, value);
break;
case DATA_TYPE_BYTE_ARRAY:
rv = nvlist_add_byte_array(nv, key, value, size);
break;
case DATA_TYPE_INT16_ARRAY:
rv = nvlist_add_int16_array(nv, key, value, size);
break;
case DATA_TYPE_UINT16_ARRAY:
rv = nvlist_add_uint16_array(nv, key, value, size);
break;
case DATA_TYPE_INT32_ARRAY:
rv = nvlist_add_int32_array(nv, key, value, size);
break;
case DATA_TYPE_UINT32_ARRAY:
rv = nvlist_add_uint32_array(nv, key, value, size);
break;
case DATA_TYPE_INT64_ARRAY:
rv = nvlist_add_int64_array(nv, key, value, size);
break;
case DATA_TYPE_UINT64_ARRAY:
rv = nvlist_add_uint64_array(nv, key, value, size);
break;
case DATA_TYPE_STRING_ARRAY:
rv = nvlist_add_string_array(nv, key, value, size);
break;
case DATA_TYPE_NVLIST:
rv = nvlist_add_nvlist(nv, key, (nvlist_t *)value);
break;
case DATA_TYPE_NVLIST_ARRAY:
rv = nvlist_add_nvlist_array(nv, key, value, size);
break;
case DATA_TYPE_BOOLEAN_VALUE:
if (size != sizeof (boolean_t)) {
rv = EINVAL;
break;
}
rv = nvlist_add_boolean_value(nv, key, *(boolean_t *)value);
break;
case DATA_TYPE_INT8:
if (size != sizeof (int8_t)) {
rv = EINVAL;
break;
}
rv = nvlist_add_int8(nv, key, *(int8_t *)value);
break;
case DATA_TYPE_UINT8:
if (size != sizeof (uint8_t)) {
rv = EINVAL;
break;
}
rv = nvlist_add_uint8(nv, key, *(uint8_t *)value);
break;
case DATA_TYPE_BOOLEAN_ARRAY:
rv = nvlist_add_boolean_array(nv, key, value, size);
break;
case DATA_TYPE_INT8_ARRAY:
rv = nvlist_add_int8_array(nv, key, value, size);
break;
case DATA_TYPE_UINT8_ARRAY:
rv = nvlist_add_uint8_array(nv, key, value, size);
break;
default:
return (ENOTSUP);
}
return (rv);
}
int
lzbe_remove_pair(void *ptr, const char *key)
{
return (nvlist_remove_all(ptr, key));
}

View File

@ -0,0 +1,39 @@
/*
* 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 2020 Toomas Soome <tsoome@me.com>
*/
#include <sys/types.h>
#include <string.h>
#include <libzfs.h>
#include <libzfsbootenv.h>
/*
* Output bootenv information.
*/
int
lzbe_bootenv_print(const char *pool, const char *nvlist, FILE *of)
{
nvlist_t *nv;
int rv = -1;
if (pool == NULL || *pool == '\0' || of == NULL)
return (rv);
rv = lzbe_nvlist_get(pool, nvlist, (void **)&nv);
if (rv == 0) {
nvlist_print(of, nv);
nvlist_free(nv);
}
return (rv);
}

View File

@ -7,6 +7,13 @@ VPATH = \
$(top_srcdir)/module/os/linux/zfs \
$(top_srcdir)/lib/libzpool
if BUILD_FREEBSD
DEFAULT_INCLUDES += -I$(top_srcdir)/include/os/freebsd/zfs
endif
if BUILD_LINUX
DEFAULT_INCLUDES += -I$(top_srcdir)/include/os/linux/zfs
endif
# Unconditionally enable debugging for libzpool
AM_CPPFLAGS += -DDEBUG -UNDEBUG -DZFS_DEBUG

View File

@ -40,6 +40,7 @@ libzutil_la_SOURCES = $(USER_C)
libzutil_la_LIBADD = \
$(abs_top_builddir)/lib/libavl/libavl.la \
$(abs_top_builddir)/lib/libtpool/libtpool.la \
$(abs_top_builddir)/lib/libnvpair/libnvpair.la \
$(abs_top_builddir)/lib/libspl/libspl.la
if BUILD_LINUX

View File

@ -1,6 +1,6 @@
'\" te
.\" Copyright (c) 2013 by Turbo Fredriksson <turbo@bayour.com>. All rights reserved.
.\" Copyright (c) 2019 by Delphix. All rights reserved.
.\" Copyright (c) 2019, 2020 by Delphix. All rights reserved.
.\" Copyright (c) 2019 Datto Inc.
.\" The contents of this file are subject to the terms of the Common Development
.\" and Distribution License (the "License"). You may not use this file except
@ -198,6 +198,22 @@ feature.
Default value: \fB200\fR%.
.RE
.sp
.ne 2
.na
\fBl2arc_mfuonly\fR (int)
.ad
.RS 12n
Controls whether only MFU metadata and data are cached from ARC into L2ARC.
This may be desired to avoid wasting space on L2ARC when reading/writing large
amounts of data that are not expected to be accessed more than once. The
default is \fB0\fR, meaning both MRU and MFU data and metadata are cached.
When turning off (\fB0\fR) this feature some MRU buffers will still be present
in ARC and eventually cached on L2ARC.
.sp
Use \fB0\fR for no (default) and \fB1\fR for yes.
.RE
.sp
.ne 2
.na
@ -741,6 +757,28 @@ regular reads (but there's no reason it has to be the same).
Default value: \fB32,768\fR.
.RE
.sp
.ne 2
.na
\fBvdev_file_logical_ashift\fR (ulong)
.ad
.RS 12n
Logical ashift for file-based devices.
.sp
Default value: \fB9\fR.
.RE
.sp
.ne 2
.na
\fBvdev_file_physical_ashift\fR (ulong)
.ad
.RS 12n
Physical ashift for file-based devices.
.sp
Default value: \fB9\fR.
.RE
.sp
.ne 2
.na
@ -3656,6 +3694,27 @@ Default value: \fB0\fR.
.sp
.ne 2
.na
\fBzfs_zevent_retain_max\fR (int)
.ad
.RS 12n
Maximum recent zevent records to retain for duplicate checking. Setting
this value to zero disables duplicate detection.
.sp
Default value: \fB2000\fR.
.RE
.sp
.ne 2
.na
\fBzfs_zevent_retain_expire_secs\fR (int)
.ad
.RS 12n
Lifespan for a recent ereport that was retained for duplicate checking.
.sp
Default value: \fB900\fR.
.RE
.na
\fBzfs_zil_clean_taskq_maxalloc\fR (int)
.ad

View File

@ -30,7 +30,7 @@
.\" Copyright 2018 Nexenta Systems, Inc.
.\" Copyright 2019 Joyent, Inc.
.\"
.Dd June 30, 2019
.Dd September 1, 2020
.Dt ZFS-RENAME 8
.Os
.Sh NAME
@ -52,8 +52,11 @@
.Cm rename
.Fl u
.Op Fl f
.Ar filesystem
.Ar filesystem
.Ar filesystem Ar filesystem
.Nm
.Cm rename
.Fl r
.Ar snapshot Ar snapshot
.Sh DESCRIPTION
.Bl -tag -width ""
.It Xo

View File

@ -38,7 +38,7 @@
.\" Copyright 2019 Joyent, Inc.
.\" Copyright (c) 2019, Kjeld Schouten-Lebbing
.\"
.Dd January 30, 2020
.Dd September 1, 2020
.Dt ZFSPROPS 8
.Os
.Sh NAME
@ -651,7 +651,7 @@ you must first remove all
.Tn ACL
entries which do not represent the current mode.
.El
.It Sy acltype Ns = Ns Sy off Ns | Ns Sy noacl Ns | Ns Sy posixacl
.It Sy acltype Ns = Ns Sy off Ns | Ns Sy posix
Controls whether ACLs are enabled and if so what type of ACL to use.
This property is not visible on FreeBSD yet.
.Bl -tag -width "posixacl"
@ -662,15 +662,18 @@ property set to off then ACLs are disabled.
.It Sy noacl
an alias for
.Sy off
.It Sy posixacl
.It Sy posix
indicates POSIX ACLs should be used. POSIX ACLs are specific to Linux and are
not functional on other platforms. POSIX ACLs are stored as an extended
attribute and therefore will not overwrite any existing NFSv4 ACLs which
may be set.
.It Sy posixacl
an alias for
.Sy posix
.El
.Pp
To obtain the best performance when setting
.Sy posixacl
.Sy posix
users are strongly encouraged to set the
.Sy xattr=sa
property. This will result in the POSIX ACL being stored more efficiently on
@ -1049,8 +1052,9 @@ In order to provide consistent data protection, encryption must be specified at
dataset creation time and it cannot be changed afterwards.
.Pp
For more details and caveats about encryption see the
.Sy Encryption
section.
.Em Encryption
section of
.Xr zfs-load-key 8 .
.It Sy keyformat Ns = Ns Sy raw Ns | Ns Sy hex Ns | Ns Sy passphrase
Controls what format the user's encryption key will be provided as. This
property is only set when the dataset is encrypted.

View File

@ -21,7 +21,7 @@
.\"
.\" Copyright (c) 2017 by Lawrence Livermore National Security, LLC.
.\"
.Dd September 16, 2017
.Dd September 13, 2020
.Dt ZGENHOSTID 8 SMM
.Os
.Sh NAME
@ -30,42 +30,73 @@
.Em /etc/hostid
.Sh SYNOPSIS
.Nm
.Op Fl f
.Op Fl o Ar filename
.Op Ar hostid
.Sh DESCRIPTION
If
.Em /etc/hostid
does not exist, create it and store a hostid in it. If the user provides
.Op Ar hostid
on the command line, store that value. Otherwise, randomly generate a
value to store.
.Pp
This emulates the
.Xr genhostid 1
utility and is provided for use on systems which do not include the utility.
.Sh OPTIONS
Creates
.Pa /etc/hostid
file and stores hostid in it.
If the user provides
.Op Ar hostid
on the command line, validates and stores that value.
Otherwise, randomly generates a value to store.
.Bl -tag -width "hostid"
.It Fl h
Display a summary of the command-line options.
.It Fl f
Force file overwrite.
.It Fl o Ar filename
Write to
.Pa filename
instead of default
.Pa /etc/hostd
.It Ar hostid
Specifies the value to be placed in
.Em /etc/hostid .
It must be a number with a value between 1 and 2^32-1. This value
.Pa /etc/hostid .
It must be a number with a value between 1 and 2^32-1.
This value
.Sy must
be unique among your systems. It must be expressed in hexadecimal and be
exactly 8 digits long.
be unique among your systems.
It
.Sy must
be expressed in hexadecimal and be exactly
.Em 8
digits long, optionally prefixed by
.Em 0x .
.El
.Sh FILES
.Pa /etc/hostid
.Sh EXAMPLES
.Bl -tag -width Ds
.Bl -tag -width Bd
.It Generate a random hostid and store it
.Bd -literal
# zgenhostid
.Ed
.It Record the libc-generated hostid in Em /etc/hostid
.It Record the libc-generated hostid in Pa /etc/hostid
.Bd -literal
# zgenhostid $(hostid)
# zgenhostid "$(hostid)"
.Ed
.It Record a custom hostid (0xdeadbeef) in Em etc/hostid
.It Record a custom hostid (0xdeadbeef) in Pa /etc/hostid
.Bd -literal
# zgenhostid deadbeef
.Ed
.It Record a custom hostid (0x01234567) in Pa /tmp/hostid
and ovewrite the file if it exists
.Bd -literal
# zgenhostid -f -o /tmp/hostid 0x01234567
.Ed
.El
.Sh SEE ALSO
.Xr genhostid 1 ,
.Xr hostid 1 ,
.Xr sethostid 3 ,
.Xr spl-module-parameters 5
.Sh HISTORY
.Nm
emulates the
.Xr genhostid 1
utility and is provided for use on systems which
do not include the utility or do not provide
.Xr sethostid 3
call.

View File

@ -77,7 +77,7 @@ The zpool
.Sy free
property is not generally useful for this purpose, and can be substantially more than the zfs
.Sy available
space. This discrepancy is due to several factors, including raidz party; zfs
space. This discrepancy is due to several factors, including raidz parity; zfs
reservation, quota, refreservation, and refquota properties; and space set aside by
.Sy spa_slop_shift
(see

View File

@ -378,4 +378,3 @@ MODULE_DEPEND(zfsctrl, krpc, 1, 1, 1);
#endif
MODULE_DEPEND(zfsctrl, acl_nfs4, 1, 1, 1);
MODULE_DEPEND(zfsctrl, crypto, 1, 1, 1);
MODULE_DEPEND(zfsctrl, cryptodev, 1, 1, 1);

View File

@ -121,6 +121,7 @@ SYSCTL_NODE(_vfs_zfs, OID_AUTO, zio, CTLFLAG_RW, 0, "ZFS ZIO");
SYSCTL_NODE(_vfs_zfs_livelist, OID_AUTO, condense, CTLFLAG_RW, 0,
"ZFS livelist condense");
SYSCTL_NODE(_vfs_zfs_vdev, OID_AUTO, cache, CTLFLAG_RW, 0, "ZFS VDEV Cache");
SYSCTL_NODE(_vfs_zfs_vdev, OID_AUTO, file, CTLFLAG_RW, 0, "ZFS VDEV file");
SYSCTL_NODE(_vfs_zfs_vdev, OID_AUTO, mirror, CTLFLAG_RD, 0,
"ZFS VDEV mirror");

View File

@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
* Copyright (c) 2011, 2020 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@ -40,6 +40,9 @@
static taskq_t *vdev_file_taskq;
unsigned long vdev_file_logical_ashift = SPA_MINBLOCKSHIFT;
unsigned long vdev_file_physical_ashift = SPA_MINBLOCKSHIFT;
void
vdev_file_init(void)
{
@ -167,8 +170,8 @@ vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
}
*max_psize = *psize = zfa.zfa_size;
*logical_ashift = SPA_MINBLOCKSHIFT;
*physical_ashift = SPA_MINBLOCKSHIFT;
*logical_ashift = vdev_file_logical_ashift;
*physical_ashift = vdev_file_physical_ashift;
return (0);
}
@ -326,3 +329,8 @@ vdev_ops_t vdev_disk_ops = {
};
#endif
ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, logical_ashift, ULONG, ZMOD_RW,
"Logical ashift for file-based devices");
ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, physical_ashift, ULONG, ZMOD_RW,
"Physical ashift for file-based devices");

View File

@ -234,13 +234,10 @@ zfs_vop_fsync(vnode_t *vp)
int
zfs_file_fsync(zfs_file_t *fp, int flags)
{
struct vnode *v;
if (fp->f_type != DTYPE_VNODE)
return (EINVAL);
v = fp->f_vnode;
return (zfs_vop_fsync(v));
return (zfs_vop_fsync(fp->f_vnode));
}
int

View File

@ -975,7 +975,7 @@ zfsvfs_create_impl(zfsvfs_t **zfvp, zfsvfs_t *zfsvfs, objset_t *os)
#else
rrm_init(&zfsvfs->z_teardown_lock, B_FALSE);
#endif
rw_init(&zfsvfs->z_teardown_inactive_lock, NULL, RW_DEFAULT, NULL);
ZFS_INIT_TEARDOWN_INACTIVE(zfsvfs);
rw_init(&zfsvfs->z_fuid_lock, NULL, RW_DEFAULT, NULL);
for (int i = 0; i != ZFS_OBJ_MTX_SZ; i++)
mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);
@ -1126,7 +1126,7 @@ zfsvfs_free(zfsvfs_t *zfsvfs)
ASSERT(zfsvfs->z_nr_znodes == 0);
list_destroy(&zfsvfs->z_all_znodes);
rrm_destroy(&zfsvfs->z_teardown_lock);
rw_destroy(&zfsvfs->z_teardown_inactive_lock);
ZFS_DESTROY_TEARDOWN_INACTIVE(zfsvfs);
rw_destroy(&zfsvfs->z_fuid_lock);
for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
mutex_destroy(&zfsvfs->z_hold_mtx[i]);
@ -1545,7 +1545,7 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
zfsvfs->z_log = NULL;
}
rw_enter(&zfsvfs->z_teardown_inactive_lock, RW_WRITER);
ZFS_WLOCK_TEARDOWN_INACTIVE(zfsvfs);
/*
* If we are not unmounting (ie: online recv) and someone already
@ -1553,7 +1553,7 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
* or a reopen of z_os failed then just bail out now.
*/
if (!unmounting && (zfsvfs->z_unmounted || zfsvfs->z_os == NULL)) {
rw_exit(&zfsvfs->z_teardown_inactive_lock);
ZFS_WUNLOCK_TEARDOWN_INACTIVE(zfsvfs);
rrm_exit(&zfsvfs->z_teardown_lock, FTAG);
return (SET_ERROR(EIO));
}
@ -1581,7 +1581,7 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
*/
if (unmounting) {
zfsvfs->z_unmounted = B_TRUE;
rw_exit(&zfsvfs->z_teardown_inactive_lock);
ZFS_WUNLOCK_TEARDOWN_INACTIVE(zfsvfs);
rrm_exit(&zfsvfs->z_teardown_lock, FTAG);
}
@ -1901,7 +1901,7 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds)
znode_t *zp;
ASSERT(RRM_WRITE_HELD(&zfsvfs->z_teardown_lock));
ASSERT(RW_WRITE_HELD(&zfsvfs->z_teardown_inactive_lock));
ASSERT(ZFS_TEARDOWN_INACTIVE_WLOCKED(zfsvfs));
/*
* We already own this, so just update the objset_t, as the one we
@ -1939,7 +1939,7 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds)
bail:
/* release the VOPs */
rw_exit(&zfsvfs->z_teardown_inactive_lock);
ZFS_WUNLOCK_TEARDOWN_INACTIVE(zfsvfs);
rrm_exit(&zfsvfs->z_teardown_lock, FTAG);
if (err) {
@ -2056,7 +2056,7 @@ int
zfs_end_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds)
{
ASSERT(RRM_WRITE_HELD(&zfsvfs->z_teardown_lock));
ASSERT(RW_WRITE_HELD(&zfsvfs->z_teardown_inactive_lock));
ASSERT(ZFS_TEARDOWN_INACTIVE_WLOCKED(zfsvfs));
/*
* We already own this, so just hold and rele it to update the
@ -2072,7 +2072,7 @@ zfs_end_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds)
zfsvfs->z_os = os;
/* release the VOPs */
rw_exit(&zfsvfs->z_teardown_inactive_lock);
ZFS_WUNLOCK_TEARDOWN_INACTIVE(zfsvfs);
rrm_exit(&zfsvfs->z_teardown_lock, FTAG);
/*

View File

@ -4638,13 +4638,13 @@ zfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
int error;
rw_enter(&zfsvfs->z_teardown_inactive_lock, RW_READER);
ZFS_RLOCK_TEARDOWN_INACTIVE(zfsvfs);
if (zp->z_sa_hdl == NULL) {
/*
* The fs has been unmounted, or we did a
* suspend/resume and this file no longer exists.
*/
rw_exit(&zfsvfs->z_teardown_inactive_lock);
ZFS_RUNLOCK_TEARDOWN_INACTIVE(zfsvfs);
vrecycle(vp);
return;
}
@ -4653,7 +4653,7 @@ zfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
/*
* Fast path to recycle a vnode of a removed file.
*/
rw_exit(&zfsvfs->z_teardown_inactive_lock);
ZFS_RUNLOCK_TEARDOWN_INACTIVE(zfsvfs);
vrecycle(vp);
return;
}
@ -4673,7 +4673,7 @@ zfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
dmu_tx_commit(tx);
}
}
rw_exit(&zfsvfs->z_teardown_inactive_lock);
ZFS_RUNLOCK_TEARDOWN_INACTIVE(zfsvfs);
}
@ -5823,10 +5823,10 @@ zfs_freebsd_need_inactive(struct vop_need_inactive_args *ap)
if (vn_need_pageq_flush(vp))
return (1);
if (!rw_tryenter(&zfsvfs->z_teardown_inactive_lock, RW_READER))
if (!ZFS_TRYRLOCK_TEARDOWN_INACTIVE(zfsvfs))
return (1);
need = (zp->z_sa_hdl == NULL || zp->z_unlinked || zp->z_atime_dirty);
rw_exit(&zfsvfs->z_teardown_inactive_lock);
ZFS_RUNLOCK_TEARDOWN_INACTIVE(zfsvfs);
return (need);
}
@ -5857,12 +5857,12 @@ zfs_freebsd_reclaim(struct vop_reclaim_args *ap)
* zfs_znode_dmu_fini in zfsvfs_teardown during
* force unmount.
*/
rw_enter(&zfsvfs->z_teardown_inactive_lock, RW_READER);
ZFS_RLOCK_TEARDOWN_INACTIVE(zfsvfs);
if (zp->z_sa_hdl == NULL)
zfs_znode_free(zp);
else
zfs_zinactive(zp);
rw_exit(&zfsvfs->z_teardown_inactive_lock);
ZFS_RUNLOCK_TEARDOWN_INACTIVE(zfsvfs);
vp->v_data = NULL;
return (0);

View File

@ -384,7 +384,7 @@ zfs_znode_dmu_fini(znode_t *zp)
{
ASSERT(MUTEX_HELD(ZFS_OBJ_MUTEX(zp->z_zfsvfs, zp->z_id)) ||
zp->z_unlinked ||
RW_WRITE_HELD(&zp->z_zfsvfs->z_teardown_inactive_lock));
ZFS_TEARDOWN_INACTIVE_WLOCKED(zp->z_zfsvfs));
sa_handle_destroy(zp->z_sa_hdl);
zp->z_sa_hdl = NULL;

View File

@ -198,6 +198,18 @@ __cv_wait_sig(kcondvar_t *cvp, kmutex_t *mp)
}
EXPORT_SYMBOL(__cv_wait_sig);
void
__cv_wait_idle(kcondvar_t *cvp, kmutex_t *mp)
{
sigset_t blocked, saved;
sigfillset(&blocked);
(void) sigprocmask(SIG_BLOCK, &blocked, &saved);
cv_wait_common(cvp, mp, TASK_INTERRUPTIBLE, 0);
(void) sigprocmask(SIG_SETMASK, &saved, NULL);
}
EXPORT_SYMBOL(__cv_wait_idle);
#if defined(HAVE_IO_SCHEDULE_TIMEOUT)
#define spl_io_schedule_timeout(t) io_schedule_timeout(t)
#else
@ -330,6 +342,21 @@ __cv_timedwait_sig(kcondvar_t *cvp, kmutex_t *mp, clock_t exp_time)
}
EXPORT_SYMBOL(__cv_timedwait_sig);
int
__cv_timedwait_idle(kcondvar_t *cvp, kmutex_t *mp, clock_t exp_time)
{
sigset_t blocked, saved;
int rc;
sigfillset(&blocked);
(void) sigprocmask(SIG_BLOCK, &blocked, &saved);
rc = __cv_timedwait_common(cvp, mp, exp_time,
TASK_INTERRUPTIBLE, 0);
(void) sigprocmask(SIG_SETMASK, &saved, NULL);
return (rc);
}
EXPORT_SYMBOL(__cv_timedwait_idle);
/*
* 'expire_time' argument is an absolute clock time in nanoseconds.
* Return value is time left (expire_time - now) or -1 if timeout occurred.
@ -427,6 +454,23 @@ cv_timedwait_sig_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim,
}
EXPORT_SYMBOL(cv_timedwait_sig_hires);
int
cv_timedwait_idle_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim,
hrtime_t res, int flag)
{
sigset_t blocked, saved;
int rc;
sigfillset(&blocked);
(void) sigprocmask(SIG_BLOCK, &blocked, &saved);
rc = cv_timedwait_hires_common(cvp, mp, tim, res, flag,
TASK_INTERRUPTIBLE);
(void) sigprocmask(SIG_SETMASK, &saved, NULL);
return (rc);
}
EXPORT_SYMBOL(cv_timedwait_idle_hires);
void
__cv_signal(kcondvar_t *cvp)
{

View File

@ -34,6 +34,7 @@
#include <sys/abd.h>
#include <sys/fs/zfs.h>
#include <sys/zio.h>
#include <linux/blkpg.h>
#include <linux/msdos_fs.h>
#include <linux/vfs_compat.h>
@ -175,7 +176,8 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
/*
* Reopen the device if it is currently open. When expanding a
* partition force re-scanning the partition table while closed
* partition force re-scanning the partition table if userland
* did not take care of this already. We need to do this while closed
* in order to get an accurate updated block device size. Then
* since udev may need to recreate the device links increase the
* open retry timeout before reporting the device as unavailable.
@ -192,7 +194,23 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
if (bdev) {
if (v->vdev_expanding && bdev != bdev->bd_contains) {
bdevname(bdev->bd_contains, disk_name + 5);
reread_part = B_TRUE;
/*
* If userland has BLKPG_RESIZE_PARTITION,
* then it should have updated the partition
* table already. We can detect this by
* comparing our current physical size
* with that of the device. If they are
* the same, then we must not have
* BLKPG_RESIZE_PARTITION or it failed to
* update the partition table online. We
* fallback to rescanning the partition
* table from the kernel below. However,
* if the capacity already reflects the
* updated partition, then we skip
* rescanning the partition table here.
*/
if (v->vdev_psize == bdev_capacity(bdev))
reread_part = B_TRUE;
}
blkdev_put(bdev, mode | FMODE_EXCL);

View File

@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
* Copyright (c) 2011, 2020 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@ -45,6 +45,17 @@
static taskq_t *vdev_file_taskq;
/*
* By default, the logical/physical ashift for file vdevs is set to
* SPA_MINBLOCKSHIFT (9). This allows all file vdevs to use 512B (1 << 9)
* blocksizes. Users may opt to change one or both of these for testing
* or performance reasons. Care should be taken as these values will
* impact the vdev_ashift setting which can only be set at vdev creation
* time.
*/
unsigned long vdev_file_logical_ashift = SPA_MINBLOCKSHIFT;
unsigned long vdev_file_physical_ashift = SPA_MINBLOCKSHIFT;
static void
vdev_file_hold(vdev_t *vd)
{
@ -159,8 +170,8 @@ vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
}
*max_psize = *psize = zfa.zfa_size;
*logical_ashift = SPA_MINBLOCKSHIFT;
*physical_ashift = SPA_MINBLOCKSHIFT;
*logical_ashift = vdev_file_logical_ashift;
*physical_ashift = vdev_file_physical_ashift;
return (0);
}
@ -346,3 +357,8 @@ vdev_ops_t vdev_disk_ops = {
};
#endif
ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, logical_ashift, ULONG, ZMOD_RW,
"Logical ashift for file-based devices");
ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, physical_ashift, ULONG, ZMOD_RW,
"Physical ashift for file-based devices");

View File

@ -1153,7 +1153,7 @@ zfs_acl_chown_setattr(znode_t *zp)
int error;
zfs_acl_t *aclp;
if (ZTOZSB(zp)->z_acl_type == ZFS_ACLTYPE_POSIXACL)
if (ZTOZSB(zp)->z_acl_type == ZFS_ACLTYPE_POSIX)
return (0);
ASSERT(MUTEX_HELD(&zp->z_lock));

View File

@ -356,9 +356,9 @@ acltype_changed_cb(void *arg, uint64_t newval)
zfsvfs->z_acl_type = ZFS_ACLTYPE_OFF;
zfsvfs->z_sb->s_flags &= ~SB_POSIXACL;
break;
case ZFS_ACLTYPE_POSIXACL:
case ZFS_ACLTYPE_POSIX:
#ifdef CONFIG_FS_POSIX_ACL
zfsvfs->z_acl_type = ZFS_ACLTYPE_POSIXACL;
zfsvfs->z_acl_type = ZFS_ACLTYPE_POSIX;
zfsvfs->z_sb->s_flags |= SB_POSIXACL;
#else
zfsvfs->z_acl_type = ZFS_ACLTYPE_OFF;

View File

@ -187,10 +187,12 @@ __zpl_show_devname(struct seq_file *seq, zfsvfs_t *zfsvfs)
{
char *fsname;
ZFS_ENTER(zfsvfs);
fsname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
dmu_objset_name(zfsvfs->z_os, fsname);
seq_puts(seq, fsname);
kmem_free(fsname, ZFS_MAX_DATASET_NAME_LEN);
ZFS_EXIT(zfsvfs);
return (0);
}
@ -209,7 +211,7 @@ __zpl_show_options(struct seq_file *seq, zfsvfs_t *zfsvfs)
#ifdef CONFIG_FS_POSIX_ACL
switch (zfsvfs->z_acl_type) {
case ZFS_ACLTYPE_POSIXACL:
case ZFS_ACLTYPE_POSIX:
seq_puts(seq, ",posixacl");
break;
default:
@ -272,8 +274,12 @@ zpl_mount_impl(struct file_system_type *fs_type, int flags, zfs_mnt_t *zm)
* a txg sync. If the dsl_pool lock is held over sget()
* this can prevent the pool sync and cause a deadlock.
*/
dsl_dataset_long_hold(dmu_objset_ds(os), FTAG);
dsl_pool_rele(dmu_objset_pool(os), FTAG);
s = sget(fs_type, zpl_test_super, set_anon_super, flags, os);
dsl_dataset_long_rele(dmu_objset_ds(os), FTAG);
dsl_dataset_rele(dmu_objset_ds(os), FTAG);
if (IS_ERR(s))

View File

@ -1058,7 +1058,7 @@ zpl_init_acl(struct inode *ip, struct inode *dir)
struct posix_acl *acl = NULL;
int error = 0;
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
return (0);
if (!S_ISLNK(ip->i_mode)) {
@ -1103,7 +1103,7 @@ zpl_chmod_acl(struct inode *ip)
struct posix_acl *acl;
int error;
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
return (0);
if (S_ISLNK(ip->i_mode))
@ -1129,7 +1129,7 @@ __zpl_xattr_acl_list_access(struct inode *ip, char *list, size_t list_size,
char *xattr_name = XATTR_NAME_POSIX_ACL_ACCESS;
size_t xattr_size = sizeof (XATTR_NAME_POSIX_ACL_ACCESS);
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
return (0);
if (list && xattr_size <= list_size)
@ -1146,7 +1146,7 @@ __zpl_xattr_acl_list_default(struct inode *ip, char *list, size_t list_size,
char *xattr_name = XATTR_NAME_POSIX_ACL_DEFAULT;
size_t xattr_size = sizeof (XATTR_NAME_POSIX_ACL_DEFAULT);
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
return (0);
if (list && xattr_size <= list_size)
@ -1168,7 +1168,7 @@ __zpl_xattr_acl_get_access(struct inode *ip, const char *name,
if (strcmp(name, "") != 0)
return (-EINVAL);
#endif
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
return (-EOPNOTSUPP);
acl = zpl_get_acl(ip, type);
@ -1196,7 +1196,7 @@ __zpl_xattr_acl_get_default(struct inode *ip, const char *name,
if (strcmp(name, "") != 0)
return (-EINVAL);
#endif
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
return (-EOPNOTSUPP);
acl = zpl_get_acl(ip, type);
@ -1224,7 +1224,7 @@ __zpl_xattr_acl_set_access(struct inode *ip, const char *name,
if (strcmp(name, "") != 0)
return (-EINVAL);
#endif
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
return (-EOPNOTSUPP);
if (!inode_owner_or_capable(ip))
@ -1264,7 +1264,7 @@ __zpl_xattr_acl_set_default(struct inode *ip, const char *name,
if (strcmp(name, "") != 0)
return (-EINVAL);
#endif
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
return (-EOPNOTSUPP);
if (!inode_owner_or_capable(ip))

View File

@ -253,9 +253,10 @@ zfs_prop_init(void)
static zprop_index_t acltype_table[] = {
{ "off", ZFS_ACLTYPE_OFF },
{ "disabled", ZFS_ACLTYPE_OFF },
{ "noacl", ZFS_ACLTYPE_OFF },
{ "posixacl", ZFS_ACLTYPE_POSIXACL },
{ "posix", ZFS_ACLTYPE_POSIX },
{ "disabled", ZFS_ACLTYPE_OFF }, /* bkwrd compatibility */
{ "noacl", ZFS_ACLTYPE_OFF }, /* bkwrd compatibility */
{ "posixacl", ZFS_ACLTYPE_POSIX }, /* bkwrd compatibility */
{ NULL }
};
@ -430,7 +431,7 @@ zfs_prop_init(void)
#ifndef __FreeBSD__
zprop_register_index(ZFS_PROP_ACLTYPE, "acltype", ZFS_ACLTYPE_OFF,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
"noacl | posixacl", "ACLTYPE", acltype_table);
"off | posix", "ACLTYPE", acltype_table);
#endif
zprop_register_index(ZFS_PROP_ACLINHERIT, "aclinherit",
ZFS_ACL_RESTRICTED, PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
@ -705,7 +706,7 @@ zfs_prop_init(void)
zprop_register_impl(ZFS_PROP_ACLTYPE, "acltype", PROP_TYPE_INDEX,
ZFS_ACLTYPE_OFF, NULL, PROP_INHERIT,
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
"noacl | posixacl", "ACLTYPE", B_FALSE, B_FALSE, acltype_table);
"off | posix", "ACLTYPE", B_FALSE, B_FALSE, acltype_table);
#endif
zprop_register_hidden(ZFS_PROP_REMAPTXG, "remaptxg", PROP_TYPE_NUMBER,
PROP_READONLY, ZFS_TYPE_DATASET, "REMAPTXG");

View File

@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, Joyent, Inc.
* Copyright (c) 2011, 2019, Delphix. All rights reserved.
* Copyright (c) 2011, 2020, Delphix. All rights reserved.
* Copyright (c) 2014, Saso Kiselkov. All rights reserved.
* Copyright (c) 2017, Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
@ -894,6 +894,12 @@ static boolean_t l2arc_write_eligible(uint64_t, arc_buf_hdr_t *);
static void l2arc_read_done(zio_t *);
static void l2arc_do_free_on_write(void);
/*
* l2arc_mfuonly : A ZFS module parameter that controls whether only MFU
* metadata and data are cached from ARC into L2ARC.
*/
int l2arc_mfuonly = 0;
/*
* L2ARC TRIM
* l2arc_trim_ahead : A ZFS module parameter that controls how much ahead of
@ -2188,7 +2194,7 @@ arc_untransform(arc_buf_t *buf, spa_t *spa, const zbookmark_phys_t *zb,
ret = SET_ERROR(EIO);
spa_log_error(spa, zb);
(void) zfs_ereport_post(FM_EREPORT_ZFS_AUTHENTICATION,
spa, NULL, zb, NULL, 0, 0);
spa, NULL, zb, NULL, 0);
}
return (ret);
@ -5654,7 +5660,7 @@ arc_read_done(zio_t *zio)
spa_log_error(zio->io_spa, &acb->acb_zb);
(void) zfs_ereport_post(
FM_EREPORT_ZFS_AUTHENTICATION,
zio->io_spa, NULL, &acb->acb_zb, zio, 0, 0);
zio->io_spa, NULL, &acb->acb_zb, zio, 0);
}
}
@ -5931,7 +5937,7 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp,
spa_log_error(spa, zb);
(void) zfs_ereport_post(
FM_EREPORT_ZFS_AUTHENTICATION,
spa, NULL, zb, NULL, 0, 0);
spa, NULL, zb, NULL, 0);
}
}
if (rc != 0) {
@ -8909,6 +8915,15 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
* Copy buffers for L2ARC writing.
*/
for (int try = 0; try < L2ARC_FEED_TYPES; try++) {
/*
* If try == 1 or 3, we cache MRU metadata and data
* respectively.
*/
if (l2arc_mfuonly) {
if (try == 1 || try == 3)
continue;
}
multilist_sublist_t *mls = l2arc_sublist_lock(try);
uint64_t passed_sz = 0;
@ -9174,7 +9189,7 @@ l2arc_feed_thread(void *unused)
cookie = spl_fstrans_mark();
while (l2arc_thread_exit == 0) {
CALLB_CPR_SAFE_BEGIN(&cpr);
(void) cv_timedwait_sig(&l2arc_feed_thr_cv,
(void) cv_timedwait_idle(&l2arc_feed_thr_cv,
&l2arc_feed_thr_lock, next);
CALLB_CPR_SAFE_END(&cpr, &l2arc_feed_thr_lock);
next = ddi_get_lbolt() + hz;
@ -9291,8 +9306,6 @@ l2arc_add_vdev(spa_t *spa, vdev_t *vd)
ASSERT(!l2arc_vdev_present(vd));
vdev_ashift_optimize(vd);
/*
* Create a new l2arc device entry.
*/
@ -10562,6 +10575,9 @@ ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, rebuild_enabled, INT, ZMOD_RW,
ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, rebuild_blocks_min_l2size, ULONG, ZMOD_RW,
"Min size in bytes to write rebuild log blocks in L2ARC");
ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, mfuonly, INT, ZMOD_RW,
"Cache only MFU data from ARC into L2ARC");
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, lotsfree_percent, param_set_arc_int,
param_get_int, ZMOD_RW, "System free memory I/O throttle in bytes");

View File

@ -718,7 +718,7 @@ dbuf_evict_thread(void *unused)
while (!dbuf_evict_thread_exit) {
while (!dbuf_cache_above_lowater() && !dbuf_evict_thread_exit) {
CALLB_CPR_SAFE_BEGIN(&cpr);
(void) cv_timedwait_sig_hires(&dbuf_evict_cv,
(void) cv_timedwait_idle_hires(&dbuf_evict_cv,
&dbuf_evict_lock, SEC2NSEC(1), MSEC2NSEC(1), 0);
CALLB_CPR_SAFE_END(&cpr, &dbuf_evict_lock);
}

View File

@ -568,8 +568,7 @@ commit_rl_updates(objset_t *os, struct merge_data *md, uint64_t object,
uint64_t txg = dmu_tx_get_txg(tx);
if (!md->md_synctask_txg[txg & TXG_MASK]) {
dsl_sync_task_nowait(dmu_tx_pool(tx),
redaction_list_update_sync, md, 5, ZFS_SPACE_CHECK_NONE,
tx);
redaction_list_update_sync, md, tx);
md->md_synctask_txg[txg & TXG_MASK] = B_TRUE;
md->md_latest_synctask_txg = txg;
}
@ -1007,10 +1006,14 @@ dmu_redact_snap(const char *snapname, nvlist_t *redactnvl,
objset_t *os;
struct redact_thread_arg *args = NULL;
redaction_list_t *new_rl = NULL;
char *newredactbook;
if ((err = dsl_pool_hold(snapname, FTAG, &dp)) != 0)
return (err);
newredactbook = kmem_zalloc(sizeof (char) * ZFS_MAX_DATASET_NAME_LEN,
KM_SLEEP);
if ((err = dsl_dataset_hold_flags(dp, snapname, DS_HOLD_FLAG_DECRYPT,
FTAG, &ds)) != 0) {
goto out;
@ -1064,7 +1067,6 @@ dmu_redact_snap(const char *snapname, nvlist_t *redactnvl,
goto out;
boolean_t resuming = B_FALSE;
char newredactbook[ZFS_MAX_DATASET_NAME_LEN];
zfs_bookmark_phys_t bookmark;
(void) strlcpy(newredactbook, snapname, ZFS_MAX_DATASET_NAME_LEN);
@ -1074,6 +1076,10 @@ dmu_redact_snap(const char *snapname, nvlist_t *redactnvl,
"#%s", redactbook);
if (n >= ZFS_MAX_DATASET_NAME_LEN - (c - newredactbook)) {
dsl_pool_rele(dp, FTAG);
kmem_free(newredactbook,
sizeof (char) * ZFS_MAX_DATASET_NAME_LEN);
if (args != NULL)
kmem_free(args, numsnaps * sizeof (*args));
return (SET_ERROR(ENAMETOOLONG));
}
err = dsl_bookmark_lookup(dp, newredactbook, NULL, &bookmark);
@ -1146,16 +1152,23 @@ dmu_redact_snap(const char *snapname, nvlist_t *redactnvl,
(void) thread_create(NULL, 0, redact_traverse_thread, rta,
0, curproc, TS_RUN, minclsyspri);
}
struct redact_merge_thread_arg rmta = { { {0} } };
(void) bqueue_init(&rmta.q, zfs_redact_queue_ff,
struct redact_merge_thread_arg *rmta;
rmta = kmem_zalloc(sizeof (struct redact_merge_thread_arg), KM_SLEEP);
(void) bqueue_init(&rmta->q, zfs_redact_queue_ff,
zfs_redact_queue_length, offsetof(struct redact_record, ln));
rmta.numsnaps = numsnaps;
rmta.spa = os->os_spa;
rmta.thr_args = args;
(void) thread_create(NULL, 0, redact_merge_thread, &rmta, 0, curproc,
rmta->numsnaps = numsnaps;
rmta->spa = os->os_spa;
rmta->thr_args = args;
(void) thread_create(NULL, 0, redact_merge_thread, rmta, 0, curproc,
TS_RUN, minclsyspri);
err = perform_redaction(os, new_rl, &rmta);
err = perform_redaction(os, new_rl, rmta);
kmem_free(rmta, sizeof (struct redact_merge_thread_arg));
out:
kmem_free(newredactbook, sizeof (char) * ZFS_MAX_DATASET_NAME_LEN);
if (new_rl != NULL) {
dsl_redaction_list_long_rele(new_rl, FTAG);
dsl_redaction_list_rele(new_rl, FTAG);

View File

@ -1197,7 +1197,7 @@ dnode_special_open(objset_t *os, dnode_phys_t *dnp, uint64_t object,
dnode_t *dn;
zrl_init(&dnh->dnh_zrlock);
zrl_tryenter(&dnh->dnh_zrlock);
VERIFY3U(1, ==, zrl_tryenter(&dnh->dnh_zrlock));
dn = dnode_create(os, dnp, NULL, object, dnh);
DNODE_VERIFY(dn);
@ -1949,18 +1949,20 @@ static void
dnode_dirty_l1range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid,
dmu_tx_t *tx)
{
dmu_buf_impl_t db_search;
dmu_buf_impl_t *db_search;
dmu_buf_impl_t *db;
avl_index_t where;
db_search = kmem_zalloc(sizeof (dmu_buf_impl_t), KM_SLEEP);
mutex_enter(&dn->dn_dbufs_mtx);
db_search.db_level = 1;
db_search.db_blkid = start_blkid + 1;
db_search.db_state = DB_SEARCH;
db_search->db_level = 1;
db_search->db_blkid = start_blkid + 1;
db_search->db_state = DB_SEARCH;
for (;;) {
db = avl_find(&dn->dn_dbufs, &db_search, &where);
db = avl_find(&dn->dn_dbufs, db_search, &where);
if (db == NULL)
db = avl_nearest(&dn->dn_dbufs, where, AVL_AFTER);
@ -1972,7 +1974,7 @@ dnode_dirty_l1range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid,
/*
* Setup the next blkid we want to search for.
*/
db_search.db_blkid = db->db_blkid + 1;
db_search->db_blkid = db->db_blkid + 1;
ASSERT3U(db->db_blkid, >=, start_blkid);
/*
@ -1992,10 +1994,10 @@ dnode_dirty_l1range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid,
/*
* Walk all the in-core level-1 dbufs and verify they have been dirtied.
*/
db_search.db_level = 1;
db_search.db_blkid = start_blkid + 1;
db_search.db_state = DB_SEARCH;
db = avl_find(&dn->dn_dbufs, &db_search, &where);
db_search->db_level = 1;
db_search->db_blkid = start_blkid + 1;
db_search->db_state = DB_SEARCH;
db = avl_find(&dn->dn_dbufs, db_search, &where);
if (db == NULL)
db = avl_nearest(&dn->dn_dbufs, where, AVL_AFTER);
for (; db != NULL; db = AVL_NEXT(&dn->dn_dbufs, db)) {
@ -2005,6 +2007,7 @@ dnode_dirty_l1range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid,
ASSERT(db->db_dirtycnt > 0);
}
#endif
kmem_free(db_search, sizeof (dmu_buf_impl_t));
mutex_exit(&dn->dn_dbufs_mtx);
}

View File

@ -23,6 +23,7 @@
* Copyright (c) 2011, 2018 by Delphix. All rights reserved.
* Copyright 2016 Gary Mills
* Copyright (c) 2017, 2019, Datto Inc. All rights reserved.
* Copyright (c) 2015, Nexenta Systems, Inc. All rights reserved.
* Copyright 2019 Joyent, Inc.
*/

View File

@ -170,15 +170,13 @@ dsl_sync_task_sig(const char *pool, dsl_checkfunc_t *checkfunc,
static void
dsl_sync_task_nowait_common(dsl_pool_t *dp, dsl_syncfunc_t *syncfunc, void *arg,
int blocks_modified, zfs_space_check_t space_check, dmu_tx_t *tx,
boolean_t early)
dmu_tx_t *tx, boolean_t early)
{
dsl_sync_task_t *dst = kmem_zalloc(sizeof (*dst), KM_SLEEP);
dst->dst_pool = dp;
dst->dst_txg = dmu_tx_get_txg(tx);
dst->dst_space = blocks_modified << DST_AVG_BLKSHIFT;
dst->dst_space_check = space_check;
dst->dst_space_check = ZFS_SPACE_CHECK_NONE;
dst->dst_checkfunc = dsl_null_checkfunc;
dst->dst_syncfunc = syncfunc;
dst->dst_arg = arg;
@ -192,18 +190,16 @@ dsl_sync_task_nowait_common(dsl_pool_t *dp, dsl_syncfunc_t *syncfunc, void *arg,
void
dsl_sync_task_nowait(dsl_pool_t *dp, dsl_syncfunc_t *syncfunc, void *arg,
int blocks_modified, zfs_space_check_t space_check, dmu_tx_t *tx)
dmu_tx_t *tx)
{
dsl_sync_task_nowait_common(dp, syncfunc, arg,
blocks_modified, space_check, tx, B_FALSE);
dsl_sync_task_nowait_common(dp, syncfunc, arg, tx, B_FALSE);
}
void
dsl_early_sync_task_nowait(dsl_pool_t *dp, dsl_syncfunc_t *syncfunc, void *arg,
int blocks_modified, zfs_space_check_t space_check, dmu_tx_t *tx)
dmu_tx_t *tx)
{
dsl_sync_task_nowait_common(dp, syncfunc, arg,
blocks_modified, space_check, tx, B_TRUE);
dsl_sync_task_nowait_common(dp, syncfunc, arg, tx, B_TRUE);
}
/*

View File

@ -104,13 +104,15 @@ struct erpt_kstat {
kstat_named_t erpt_set_failed; /* num erpt set failures */
kstat_named_t fmri_set_failed; /* num fmri set failures */
kstat_named_t payload_set_failed; /* num payload set failures */
kstat_named_t erpt_duplicates; /* num duplicate erpts */
};
static struct erpt_kstat erpt_kstat_data = {
{ "erpt-dropped", KSTAT_DATA_UINT64 },
{ "erpt-set-failed", KSTAT_DATA_UINT64 },
{ "fmri-set-failed", KSTAT_DATA_UINT64 },
{ "payload-set-failed", KSTAT_DATA_UINT64 }
{ "payload-set-failed", KSTAT_DATA_UINT64 },
{ "erpt-duplicates", KSTAT_DATA_UINT64 }
};
kstat_t *fm_ksp;
@ -568,6 +570,12 @@ zfs_zevent_post(nvlist_t *nvl, nvlist_t *detector, zevent_cb_t *cb)
return (error);
}
void
zfs_zevent_track_duplicate(void)
{
atomic_inc_64(&erpt_kstat_data.erpt_duplicates.value.ui64);
}
static int
zfs_zevent_minor_to_state(minor_t minor, zfs_zevent_t **ze)
{
@ -1633,6 +1641,8 @@ fm_init(void)
list_create(&zevent_list, sizeof (zevent_t),
offsetof(zevent_t, ev_node));
cv_init(&zevent_cv, NULL, CV_DEFAULT, NULL);
zfs_ereport_init();
}
void
@ -1640,6 +1650,8 @@ fm_fini(void)
{
int count;
zfs_ereport_fini();
zfs_zevent_drain_all(&count);
mutex_enter(&zevent_lock);

View File

@ -22,6 +22,7 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2019 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
* Copyright (c) 2015, Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2017, Intel Corporation.
*/

View File

@ -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);
@ -671,7 +675,7 @@ mmp_thread(void *arg)
}
CALLB_CPR_SAFE_BEGIN(&cpr);
(void) cv_timedwait_sig_hires(&mmp->mmp_thread_cv,
(void) cv_timedwait_idle_hires(&mmp->mmp_thread_cv,
&mmp->mmp_thread_lock, next_time, USEC2NSEC(100),
CALLOUT_FLAG_ABSOLUTE);
CALLB_CPR_SAFE_END(&cpr, &mmp->mmp_thread_lock);

View File

@ -24,6 +24,7 @@
*/
/*
* Copyright (c) 2013, 2019 by Delphix. All rights reserved.
* Copyright (c) 2015, Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/zfs_context.h>

View File

@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2019 by Delphix. All rights reserved.
* Copyright (c) 2011, 2020 by Delphix. All rights reserved.
* Copyright (c) 2018, Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
* Copyright 2013 Saso Kiselkov. All rights reserved.
@ -1000,13 +1000,25 @@ spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q)
/*
* The write issue taskq can be extremely CPU
* intensive. Run it at slightly less important
* priority than the other taskqs. Under Linux this
* means incrementing the priority value on platforms
* like illumos it should be decremented.
* priority than the other taskqs.
*
* Under Linux and FreeBSD this means incrementing
* the priority value as opposed to platforms like
* illumos where it should be decremented.
*
* On FreeBSD, if priorities divided by four (RQ_PPQ)
* are equal then a difference between them is
* insignificant.
*/
if (t == ZIO_TYPE_WRITE && q == ZIO_TASKQ_ISSUE)
if (t == ZIO_TYPE_WRITE && q == ZIO_TASKQ_ISSUE) {
#if defined(__linux__)
pri++;
#elif defined(__FreeBSD__)
pri += 4;
#else
#error "unknown OS"
#endif
}
tq = taskq_create_proc(name, value, pri, 50,
INT_MAX, spa->spa_proc, flags);
}
@ -2485,11 +2497,12 @@ spa_livelist_delete_cb(void *arg, zthr_t *z)
VERIFY0(dsl_get_next_livelist_obj(mos, zap_obj, &ll_obj));
VERIFY0(zap_count(mos, ll_obj, &count));
if (count > 0) {
dsl_deadlist_t ll = { 0 };
dsl_deadlist_t *ll;
dsl_deadlist_entry_t *dle;
bplist_t to_free;
dsl_deadlist_open(&ll, mos, ll_obj);
dle = dsl_deadlist_first(&ll);
ll = kmem_zalloc(sizeof (dsl_deadlist_t), KM_SLEEP);
dsl_deadlist_open(ll, mos, ll_obj);
dle = dsl_deadlist_first(ll);
ASSERT3P(dle, !=, NULL);
bplist_create(&to_free);
int err = dsl_process_sub_livelist(&dle->dle_bpobj, &to_free,
@ -2497,7 +2510,7 @@ spa_livelist_delete_cb(void *arg, zthr_t *z)
if (err == 0) {
sublist_delete_arg_t sync_arg = {
.spa = spa,
.ll = &ll,
.ll = ll,
.key = dle->dle_mintxg,
.to_free = &to_free
};
@ -2512,7 +2525,8 @@ spa_livelist_delete_cb(void *arg, zthr_t *z)
}
bplist_clear(&to_free);
bplist_destroy(&to_free);
dsl_deadlist_close(&ll);
dsl_deadlist_close(ll);
kmem_free(ll, sizeof (dsl_deadlist_t));
} else {
livelist_delete_arg_t sync_arg = {
.spa = spa,
@ -2688,8 +2702,7 @@ spa_livelist_condense_cb(void *arg, zthr_t *t)
lca->first_size = first_size;
lca->next_size = next_size;
dsl_sync_task_nowait(spa_get_dsl(spa),
spa_livelist_condense_sync, lca, 0,
ZFS_SPACE_CHECK_NONE, tx);
spa_livelist_condense_sync, lca, tx);
dmu_tx_commit(tx);
return;
}
@ -2869,7 +2882,7 @@ spa_load(spa_t *spa, spa_load_state_t state, spa_import_type_t type)
}
if (error != EBADF) {
(void) zfs_ereport_post(ereport, spa,
NULL, NULL, NULL, 0, 0);
NULL, NULL, NULL, 0);
}
}
spa->spa_load_state = error ? SPA_LOAD_ERROR : SPA_LOAD_NONE;
@ -5749,7 +5762,6 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
for (int c = 0; error == 0 && c < rvd->vdev_children; c++) {
vdev_t *vd = rvd->vdev_child[c];
vdev_ashift_optimize(vd);
vdev_metaslab_set_size(vd);
vdev_expand(vd, txg);
}

View File

@ -22,7 +22,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011, 2018 by Delphix. All rights reserved.
* Copyright (c) 2011, 2020 by Delphix. All rights reserved.
* Copyright 2017 Joyent, Inc.
*/
@ -316,7 +316,7 @@ spa_write_cachefile(spa_t *target, boolean_t removing, boolean_t postsysevent)
if (target->spa_ccw_fail_time == 0) {
(void) zfs_ereport_post(
FM_EREPORT_ZFS_CONFIG_CACHE_WRITE,
target, NULL, NULL, NULL, 0, 0);
target, NULL, NULL, NULL, 0);
}
target->spa_ccw_fail_time = gethrtime();
spa_async_request(target, SPA_ASYNC_CONFIG_UPDATE);
@ -577,10 +577,8 @@ spa_config_update(spa_t *spa, int what)
(tvd->vdev_islog && tvd->vdev_removing))
continue;
if (tvd->vdev_ms_array == 0) {
vdev_ashift_optimize(tvd);
if (tvd->vdev_ms_array == 0)
vdev_metaslab_set_size(tvd);
}
vdev_expand(tvd, txg);
}
}

View File

@ -397,8 +397,7 @@ spa_history_log_nvl(spa_t *spa, nvlist_t *nvl)
fnvlist_add_uint64(nvarg, ZPOOL_HIST_WHO, crgetruid(CRED()));
/* Kick this off asynchronously; errors are ignored. */
dsl_sync_task_nowait(spa_get_dsl(spa), spa_history_log_sync,
nvarg, 0, ZFS_SPACE_CHECK_NONE, tx);
dsl_sync_task_nowait(spa_get_dsl(spa), spa_history_log_sync, nvarg, tx);
dmu_tx_commit(tx);
/* spa_history_log_sync will free nvl */
@ -532,7 +531,7 @@ log_internal(nvlist_t *nvl, const char *operation, spa_t *spa,
spa_history_log_sync(nvl, tx);
} else {
dsl_sync_task_nowait(spa_get_dsl(spa),
spa_history_log_sync, nvl, 0, ZFS_SPACE_CHECK_NONE, tx);
spa_history_log_sync, nvl, tx);
}
/* spa_history_log_sync() will free nvl */
}

View File

@ -242,16 +242,11 @@ txg_thread_wait(tx_state_t *tx, callb_cpr_t *cpr, kcondvar_t *cv, clock_t time)
{
CALLB_CPR_SAFE_BEGIN(cpr);
/*
* cv_wait_sig() is used instead of cv_wait() in order to prevent
* this process from incorrectly contributing to the system load
* average when idle.
*/
if (time) {
(void) cv_timedwait_sig(cv, &tx->tx_sync_lock,
(void) cv_timedwait_idle(cv, &tx->tx_sync_lock,
ddi_get_lbolt() + time);
} else {
cv_wait_sig(cv, &tx->tx_sync_lock);
cv_wait_idle(cv, &tx->tx_sync_lock);
}
CALLB_CPR_SAFE_END(cpr, &tx->tx_sync_lock);
@ -760,7 +755,8 @@ txg_wait_open(dsl_pool_t *dp, uint64_t txg, boolean_t should_quiesce)
if (should_quiesce == B_TRUE) {
cv_wait_io(&tx->tx_quiesce_done_cv, &tx->tx_sync_lock);
} else {
cv_wait_sig(&tx->tx_quiesce_done_cv, &tx->tx_sync_lock);
cv_wait_idle(&tx->tx_quiesce_done_cv,
&tx->tx_sync_lock);
}
}
mutex_exit(&tx->tx_sync_lock);

View File

@ -1481,7 +1481,7 @@ vdev_probe_done(zio_t *zio)
ASSERT(zio->io_error != 0);
vdev_dbgmsg(vd, "failed probe");
(void) zfs_ereport_post(FM_EREPORT_ZFS_PROBE_FAILURE,
spa, vd, NULL, NULL, 0, 0);
spa, vd, NULL, NULL, 0);
zio->io_error = SET_ERROR(ENXIO);
}
@ -1672,6 +1672,38 @@ vdev_set_deflate_ratio(vdev_t *vd)
}
}
/*
* Maximize performance by inflating the configured ashift for top level
* vdevs to be as close to the physical ashift as possible while maintaining
* administrator defined limits and ensuring it doesn't go below the
* logical ashift.
*/
static void
vdev_ashift_optimize(vdev_t *vd)
{
ASSERT(vd == vd->vdev_top);
if (vd->vdev_ashift < vd->vdev_physical_ashift) {
vd->vdev_ashift = MIN(
MAX(zfs_vdev_max_auto_ashift, vd->vdev_ashift),
MAX(zfs_vdev_min_auto_ashift,
vd->vdev_physical_ashift));
} else {
/*
* If the logical and physical ashifts are the same, then
* we ensure that the top-level vdev's ashift is not smaller
* than our minimum ashift value. For the unusual case
* where logical ashift > physical ashift, we can't cap
* the calculated ashift based on max ashift as that
* would cause failures.
* We still check if we need to increase it to match
* the min ashift.
*/
vd->vdev_ashift = MAX(zfs_vdev_min_auto_ashift,
vd->vdev_ashift);
}
}
/*
* Prepare a virtual device for access.
*/
@ -1830,16 +1862,17 @@ vdev_open(vdev_t *vd)
return (SET_ERROR(EINVAL));
}
/*
* We can always set the logical/physical ashift members since
* their values are only used to calculate the vdev_ashift when
* the device is first added to the config. These values should
* not be used for anything else since they may change whenever
* the device is reopened and we don't store them in the label.
*/
vd->vdev_physical_ashift =
MAX(physical_ashift, vd->vdev_physical_ashift);
vd->vdev_logical_ashift = MAX(logical_ashift, vd->vdev_logical_ashift);
vd->vdev_ashift = MAX(vd->vdev_logical_ashift, vd->vdev_ashift);
if (vd->vdev_logical_ashift > ASHIFT_MAX) {
vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
VDEV_AUX_ASHIFT_TOO_BIG);
return (SET_ERROR(EDOM));
}
vd->vdev_logical_ashift = MAX(logical_ashift,
vd->vdev_logical_ashift);
if (vd->vdev_asize == 0) {
/*
@ -1848,6 +1881,24 @@ vdev_open(vdev_t *vd)
*/
vd->vdev_asize = asize;
vd->vdev_max_asize = max_asize;
/*
* If the vdev_ashift was not overriden at creation time,
* then set it the logical ashift and optimize the ashift.
*/
if (vd->vdev_ashift == 0) {
vd->vdev_ashift = vd->vdev_logical_ashift;
if (vd->vdev_logical_ashift > ASHIFT_MAX) {
vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
VDEV_AUX_ASHIFT_TOO_BIG);
return (SET_ERROR(EDOM));
}
if (vd->vdev_top == vd) {
vdev_ashift_optimize(vd);
}
}
if (vd->vdev_ashift != 0 && (vd->vdev_ashift < ASHIFT_MIN ||
vd->vdev_ashift > ASHIFT_MAX)) {
vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
@ -1862,11 +1913,10 @@ vdev_open(vdev_t *vd)
vd->vdev_ops->vdev_op_leaf) {
(void) zfs_ereport_post(
FM_EREPORT_ZFS_DEVICE_BAD_ASHIFT,
spa, vd, NULL, NULL, 0, 0);
spa, vd, NULL, NULL, 0);
vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
VDEV_AUX_BAD_LABEL);
return (SET_ERROR(EDOM));
}
vd->vdev_max_asize = max_asize;
}
@ -2445,35 +2495,6 @@ vdev_metaslab_set_size(vdev_t *vd)
ASSERT3U(vd->vdev_ms_shift, >=, SPA_MAXBLOCKSHIFT);
}
/*
* Maximize performance by inflating the configured ashift for top level
* vdevs to be as close to the physical ashift as possible while maintaining
* administrator defined limits and ensuring it doesn't go below the
* logical ashift.
*/
void
vdev_ashift_optimize(vdev_t *vd)
{
if (vd == vd->vdev_top) {
if (vd->vdev_ashift < vd->vdev_physical_ashift) {
vd->vdev_ashift = MIN(
MAX(zfs_vdev_max_auto_ashift, vd->vdev_ashift),
MAX(zfs_vdev_min_auto_ashift,
vd->vdev_physical_ashift));
} else {
/*
* Unusual case where logical ashift > physical ashift
* so we can't cap the calculated ashift based on max
* ashift as that would cause failures.
* We still check if we need to increase it to match
* the min ashift.
*/
vd->vdev_ashift = MAX(zfs_vdev_min_auto_ashift,
vd->vdev_ashift);
}
}
}
void
vdev_dirty(vdev_t *vd, int flags, void *arg, uint64_t txg)
{
@ -4759,7 +4780,7 @@ vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux)
}
(void) zfs_ereport_post(class, spa, vd, NULL, NULL,
save_state, 0);
save_state);
}
/* Erase any notion of persistent removed state */

View File

@ -16,7 +16,7 @@
/*
* Copyright (c) 2014, 2017 by Delphix. All rights reserved.
* Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
* Copyright (c) 2014, 2019 by Delphix. All rights reserved.
* Copyright (c) 2014, 2020 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@ -576,8 +576,7 @@ spa_condense_indirect_commit_entry(spa_t *spa,
*/
if (list_is_empty(&sci->sci_new_mapping_entries[txgoff])) {
dsl_sync_task_nowait(dmu_tx_pool(tx),
spa_condense_indirect_commit_sync, sci,
0, ZFS_SPACE_CHECK_NONE, tx);
spa_condense_indirect_commit_sync, sci, tx);
}
vdev_indirect_mapping_entry_t *vime =
@ -1474,13 +1473,14 @@ vdev_indirect_all_checksum_errors(zio_t *zio)
vdev_t *vd = ic->ic_vdev;
mutex_enter(&vd->vdev_stat_lock);
vd->vdev_stat.vs_checksum_errors++;
mutex_exit(&vd->vdev_stat_lock);
(void) zfs_ereport_post_checksum(zio->io_spa, vd,
int ret = zfs_ereport_post_checksum(zio->io_spa, vd,
NULL, zio, is->is_target_offset, is->is_size,
NULL, NULL, NULL);
if (ret != EALREADY) {
mutex_enter(&vd->vdev_stat_lock);
vd->vdev_stat.vs_checksum_errors++;
mutex_exit(&vd->vdev_stat_lock);
}
}
}
}

View File

@ -126,7 +126,7 @@ vdev_initialize_change_state(vdev_t *vd, vdev_initializing_state_t new_state)
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
dsl_sync_task_nowait(spa_get_dsl(spa), vdev_initialize_zap_update_sync,
guid, 2, ZFS_SPACE_CHECK_NONE, tx);
guid, tx);
switch (new_state) {
case VDEV_INITIALIZE_ACTIVE:
@ -216,8 +216,7 @@ vdev_initialize_write(vdev_t *vd, uint64_t start, uint64_t size, abd_t *data)
/* This is the first write of this txg. */
dsl_sync_task_nowait(spa_get_dsl(spa),
vdev_initialize_zap_update_sync, guid, 2,
ZFS_SPACE_CHECK_RESERVED, tx);
vdev_initialize_zap_update_sync, guid, tx);
}
/*

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