From faea8c590bd304ff91d78131c8ea918862835a2c Mon Sep 17 00:00:00 2001 From: Jesus Alvarez Date: Sat, 24 Aug 2013 10:06:09 -0700 Subject: [PATCH] Delete git patches --- spl-utils/spl_git_head.patch | 1044 ----- spl/spl_git_head.patch | 1044 ----- zfs-utils/zfs_git_head.patch | 8612 ---------------------------------- zfs/zfs_git_head.patch | 8612 ---------------------------------- 4 files changed, 19312 deletions(-) delete mode 100644 spl-utils/spl_git_head.patch delete mode 100644 spl/spl_git_head.patch delete mode 100644 zfs-utils/zfs_git_head.patch delete mode 100644 zfs/zfs_git_head.patch diff --git a/spl-utils/spl_git_head.patch b/spl-utils/spl_git_head.patch deleted file mode 100644 index 7651c2f..0000000 --- a/spl-utils/spl_git_head.patch +++ /dev/null @@ -1,1044 +0,0 @@ -diff --git a/Makefile.am b/Makefile.am -index cea9db9..23dc257 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -1,3 +1,6 @@ -+ -+ACLOCAL_AMFLAGS = -I config -+ - include $(top_srcdir)/config/rpm.am - include $(top_srcdir)/config/deb.am - include $(top_srcdir)/config/tgz.am -diff --git a/autogen.sh b/autogen.sh -index 343265c..427394a 100755 ---- a/autogen.sh -+++ b/autogen.sh -@@ -1,7 +1,4 @@ - #!/bin/sh - --aclocal -I config --libtoolize --automake --copy --autoheader --automake --add-missing --include-deps --copy --autoconf -+autoreconf -fiv -+rm -Rf autom4te.cache -diff --git a/config/Rules.am b/config/Rules.am -index 0b41ec4..7c5d328 100644 ---- a/config/Rules.am -+++ b/config/Rules.am -@@ -9,5 +9,6 @@ - DEFAULT_INCLUDES = -include ${top_builddir}/spl_config.h - - AM_LIBTOOLFLAGS = --silent -+AM_CPPFLAGS = -D__USE_LARGEFILE64 - AM_CFLAGS = -Wall -Wshadow -Wstrict-prototypes -fno-strict-aliasing --AM_CFLAGS += -D__USE_LARGEFILE64 ${DEBUG_CFLAGS} -+AM_CFLAGS += ${DEBUG_CFLAGS} -diff --git a/config/deb.am b/config/deb.am -index 5efbd9d..a2bad02 100644 ---- a/config/deb.am -+++ b/config/deb.am -@@ -34,7 +34,7 @@ if CONFIG_KERNEL - version=${VERSION}-${RELEASE}; \ - arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \ - pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \ -- fakeroot $(ALIEN) --scripts --to-deb $$pkg1; \ -+ fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \ - $(RM) $$pkg1 - endif - -@@ -44,7 +44,7 @@ if CONFIG_USER - version=${VERSION}-${RELEASE}; \ - arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \ - pkg1=$${name}-$${version}.$${arch}.rpm; \ -- fakeroot $(ALIEN) --scripts --to-deb $$pkg1; \ -+ fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \ - $(RM) $$pkg1 - endif - -diff --git a/config/spl-build.m4 b/config/spl-build.m4 -index 8a8e3ba..da179e3 100644 ---- a/config/spl-build.m4 -+++ b/config/spl-build.m4 -@@ -33,6 +33,8 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ - SPL_AC_TASK_CURR - SPL_AC_CTL_UNNUMBERED - SPL_AC_CTL_NAME -+ SPL_AC_VMALLOC_INFO -+ SPL_AC_PDE_DATA - SPL_AC_FLS64 - SPL_AC_DEVICE_CREATE - SPL_AC_5ARGS_DEVICE_CREATE -@@ -1358,6 +1360,43 @@ AC_DEFUN([SPL_AC_GET_VMALLOC_INFO], - ]) - - dnl # -+dnl # 3.10 API change, -+dnl # struct vmalloc_info is now declared in linux/vmalloc.h -+dnl # -+AC_DEFUN([SPL_AC_VMALLOC_INFO], [ -+ AC_MSG_CHECKING([whether struct vmalloc_info is declared]) -+ SPL_LINUX_TRY_COMPILE([ -+ #include -+ struct vmalloc_info { void *a; }; -+ ],[ -+ return 0; -+ ],[ -+ AC_MSG_RESULT(no) -+ ],[ -+ AC_MSG_RESULT(yes) -+ AC_DEFINE(HAVE_VMALLOC_INFO, 1, [yes]) -+ ]) -+]) -+ -+dnl # -+dnl # 3.10 API change, -+dnl # PDE is replaced by PDE_DATA -+dnl # -+AC_DEFUN([SPL_AC_PDE_DATA], [ -+ AC_MSG_CHECKING([whether PDE_DATA() is available]) -+ SPL_LINUX_TRY_COMPILE_SYMBOL([ -+ #include -+ ], [ -+ PDE_DATA(NULL); -+ ], [PDE_DATA], [], [ -+ AC_MSG_RESULT(yes) -+ AC_DEFINE(HAVE_PDE_DATA, 1, [yes]) -+ ],[ -+ AC_MSG_RESULT(no) -+ ]) -+]) -+ -+dnl # - dnl # 2.6.17 API change - dnl # The helper functions first_online_pgdat(), next_online_pgdat(), and - dnl # next_zone() are introduced to simplify for_each_zone(). These symbols -diff --git a/config/spl-meta.m4 b/config/spl-meta.m4 -index 28103bc..a51fa79 100644 ---- a/config/spl-meta.m4 -+++ b/config/spl-meta.m4 -@@ -1,15 +1,37 @@ --############################################################################### --# Written by Chris Dunlap . --# Modified by Brian Behlendorf . --############################################################################### --# SPL_AC_META: Read metadata from the META file. When building from a --# git repository the SPL_META_RELEASE field will be overwritten if there --# is an annotated tag matching the form SPL_META_NAME-SPL_META_VERSION-*. --# This allows for working builds to be uniquely identified using the git --# commit hash. --############################################################################### -- -+dnl # -+dnl # DESCRIPTION: -+dnl # Read meta data from the META file. When building from a git repository -+dnl # the SPL_META_RELEASE field will be overwritten if there is an annotated -+dnl # tag matching the form SPL_META_NAME-SPL_META_VERSION-*. This allows -+dnl # for working builds to be uniquely identified using the git commit hash. -+dnl # -+dnl # The META file format is as follows: -+dnl # ^[ ]*KEY:[ \t]+VALUE$ -+dnl # -+dnl # In other words: -+dnl # - KEY is separated from VALUE by a colon and one or more spaces/tabs. -+dnl # - KEY and VALUE are case sensitive. -+dnl # - Leading spaces are ignored. -+dnl # - First match wins for duplicate keys. -+dnl # -+dnl # A line can be commented out by preceding it with a '#' (or technically -+dnl # any non-space character since that will prevent the regex from -+dnl # matching). -+dnl # -+dnl # WARNING: -+dnl # Placing a colon followed by a space or tab (ie, ":[ \t]+") within the -+dnl # VALUE will prematurely terminate the string since that sequence is -+dnl # used as the awk field separator. -+dnl # -+dnl # KEYS: -+dnl # The following META keys are recognized: -+dnl # Name, Version, Release, Date, Author, LT_Current, LT_Revision, LT_Age -+dnl # -+dnl # Written by Chris Dunlap . -+dnl # Modified by Brian Behlendorf . -+dnl # - AC_DEFUN([SPL_AC_META], [ -+ AC_PROG_AWK - AC_MSG_CHECKING([metadata]) - - META="$srcdir/META" -@@ -17,7 +39,7 @@ AC_DEFUN([SPL_AC_META], [ - if test -f "$META"; then - _spl_ac_meta_type="META file" - -- SPL_META_NAME=_SPL_AC_META_GETVAL([(?:NAME|PROJECT|PACKAGE)]); -+ SPL_META_NAME=_SPL_AC_META_GETVAL([(Name|Project|Package)]); - if test -n "$SPL_META_NAME"; then - AC_DEFINE_UNQUOTED([SPL_META_NAME], ["$SPL_META_NAME"], - [Define the project name.] -@@ -25,7 +47,7 @@ AC_DEFUN([SPL_AC_META], [ - AC_SUBST([SPL_META_NAME]) - fi - -- SPL_META_VERSION=_SPL_AC_META_GETVAL([VERSION]); -+ SPL_META_VERSION=_SPL_AC_META_GETVAL([Version]); - if test -n "$SPL_META_VERSION"; then - AC_DEFINE_UNQUOTED([SPL_META_VERSION], ["$SPL_META_VERSION"], - [Define the project version.] -@@ -33,8 +55,8 @@ AC_DEFUN([SPL_AC_META], [ - AC_SUBST([SPL_META_VERSION]) - fi - -- SPL_META_RELEASE=_SPL_AC_META_GETVAL([RELEASE]); -- if git rev-parse --git-dir > /dev/null 2>&1; then -+ SPL_META_RELEASE=_SPL_AC_META_GETVAL([Release]); -+ if test ! -f ".nogitrelease" && git rev-parse --git-dir > /dev/null 2>&1; then - _match="${SPL_META_NAME}-${SPL_META_VERSION}*" - _alias=$(git describe --match=${_match} 2>/dev/null) - _release=$(echo ${_alias}|cut -f3- -d'-'|sed 's/-/_/g') -@@ -65,7 +87,7 @@ AC_DEFUN([SPL_AC_META], [ - AC_SUBST([SPL_META_ALIAS]) - fi - -- SPL_META_DATA=_SPL_AC_META_GETVAL([DATE]); -+ SPL_META_DATA=_SPL_AC_META_GETVAL([Date]); - if test -n "$SPL_META_DATA"; then - AC_DEFINE_UNQUOTED([SPL_META_DATA], ["$SPL_META_DATA"], - [Define the project release date.] -@@ -73,7 +95,7 @@ AC_DEFUN([SPL_AC_META], [ - AC_SUBST([SPL_META_DATA]) - fi - -- SPL_META_AUTHOR=_SPL_AC_META_GETVAL([AUTHOR]); -+ SPL_META_AUTHOR=_SPL_AC_META_GETVAL([Author]); - if test -n "$SPL_META_AUTHOR"; then - AC_DEFINE_UNQUOTED([SPL_META_AUTHOR], ["$SPL_META_AUTHOR"], - [Define the project author.] -@@ -82,9 +104,9 @@ AC_DEFUN([SPL_AC_META], [ - fi - - m4_pattern_allow([^LT_(CURRENT|REVISION|AGE)$]) -- SPL_META_LT_CURRENT=_SPL_AC_META_GETVAL([LT_CURRENT]); -- SPL_META_LT_REVISION=_SPL_AC_META_GETVAL([LT_REVISION]); -- SPL_META_LT_AGE=_SPL_AC_META_GETVAL([LT_AGE]); -+ SPL_META_LT_CURRENT=_SPL_AC_META_GETVAL([LT_Current]); -+ SPL_META_LT_REVISION=_SPL_AC_META_GETVAL([LT_Revision]); -+ SPL_META_LT_AGE=_SPL_AC_META_GETVAL([LT_Age]); - if test -n "$SPL_META_LT_CURRENT" \ - -o -n "$SPL_META_LT_REVISION" \ - -o -n "$SPL_META_LT_AGE"; then -@@ -115,15 +137,18 @@ AC_DEFUN([SPL_AC_META], [ - ] - ) - --AC_DEFUN([_SPL_AC_META_GETVAL], -- [`perl -n\ -- -e "BEGIN { \\$key=shift @ARGV; }"\ -- -e "next unless s/^\s*\\$key@<:@:=@:>@//i;"\ -- -e "s/^((?:@<:@^'\"#@:>@*(?:(@<:@'\"@:>@)@<:@^\2@:>@*\2)*)*)#.*/\\@S|@1/;"\ -- -e "s/^\s+//;"\ -- -e "s/\s+$//;"\ -- -e "s/^(@<:@'\"@:>@)(.*)\1/\\@S|@2/;"\ -- -e "\\$val=\\$_;"\ -- -e "END { print \\$val if defined \\$val; }"\ -- '$1' $META`]dnl -+dnl # _SPL_AC_META_GETVAL (KEY_NAME_OR_REGEX) -+dnl # -+dnl # Returns the META VALUE associated with the given KEY_NAME_OR_REGEX expr. -+dnl # -+dnl # Despite their resemblance to line noise, -+dnl # the "@<:@" and "@:>@" constructs are quadrigraphs for "[" and "]". -+dnl # -+dnl # -+dnl # The "$[]1" and "$[]2" constructs prevent M4 parameter expansion -+dnl # so a literal $1 and $2 will be passed to the resulting awk script, -+dnl # whereas the "$1" will undergo M4 parameter expansion for the META key. -+dnl # -+AC_DEFUN([_SPL_AC_META_GETVAL], -+ [`$AWK -F ':@<:@ \t@:>@+' '$[]1 ~ /^ *$1$/ { print $[]2; exit }' $META`]dnl - ) -diff --git a/configure.ac b/configure.ac -index f9cd542..4772298 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -28,9 +28,10 @@ AC_INIT - AC_LANG(C) - SPL_AC_META - AC_CONFIG_AUX_DIR([config]) -+AC_CONFIG_MACRO_DIR([config]) - AC_CANONICAL_SYSTEM - AM_MAINTAINER_MODE --AM_SILENT_RULES -+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - AM_INIT_AUTOMAKE([$SPL_META_NAME], [$SPL_META_VERSION]) - AC_CONFIG_HEADERS([spl_config.h], [ - (mv spl_config.h spl_config.h.tmp && -diff --git a/copy-builtin b/copy-builtin -index 3277270..cd98b7a 100755 ---- a/copy-builtin -+++ b/copy-builtin -@@ -33,6 +33,7 @@ rm -rf "$KERNEL_DIR/include/spl" "$KERNEL_DIR/spl" - cp --recursive include "$KERNEL_DIR/include/spl" - cp --recursive module "$KERNEL_DIR/spl" - cp spl_config.h "$KERNEL_DIR/" -+cp spl.release.in "$KERNEL_DIR/" - - adjust_obj_paths() - { -diff --git a/include/linux/proc_compat.h b/include/linux/proc_compat.h -index 434ffa3..7b044e7 100644 ---- a/include/linux/proc_compat.h -+++ b/include/linux/proc_compat.h -@@ -43,9 +43,6 @@ - #endif - - extern struct proc_dir_entry *proc_spl_kstat; --struct proc_dir_entry *proc_dir_entry_find(struct proc_dir_entry *root, -- const char *str); --int proc_dir_entries(struct proc_dir_entry *root); - - int spl_proc_init(void); - void spl_proc_fini(void); -diff --git a/include/sys/debug.h b/include/sys/debug.h -index 25ff88e..f3f3529 100644 ---- a/include/sys/debug.h -+++ b/include/sys/debug.h -@@ -35,10 +35,12 @@ - * ASSERT3S() - Assert signed X OP Y is true, if not panic. - * ASSERT3U() - Assert unsigned X OP Y is true, if not panic. - * ASSERT3P() - Assert pointer X OP Y is true, if not panic. -+ * ASSERT0() - Assert value is zero, if not panic. - * VERIFY() - Verify X is true, if not panic. - * VERIFY3S() - Verify signed X OP Y is true, if not panic. - * VERIFY3U() - Verify unsigned X OP Y is true, if not panic. - * VERIFY3P() - Verify pointer X OP Y is true, if not panic. -+ * VERIFY0() - Verify value is zero, if not panic. - */ - - #ifndef _SPL_DEBUG_H -@@ -79,10 +81,12 @@ do { \ - #define VERIFY3U(x,y,z) VERIFY3_IMPL(x, y, z, uint64_t, "%llu", \ - (unsigned long long)) - #define VERIFY3P(x,y,z) VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *)) -+#define VERIFY0(x) VERIFY3_IMPL(0, ==, x, int64_t, "%lld", (long long)) - - #define ASSERT3S(x,y,z) ((void)0) - #define ASSERT3U(x,y,z) ((void)0) - #define ASSERT3P(x,y,z) ((void)0) -+#define ASSERT0(x) ((void)0) - - #else /* Debugging Enabled */ - -@@ -130,10 +134,12 @@ do { \ - #define VERIFY3U(x,y,z) VERIFY3_IMPL(x, y, z, uint64_t, "%llu", \ - (unsigned long long)) - #define VERIFY3P(x,y,z) VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *)) -+#define VERIFY0(x) VERIFY3_IMPL(0, ==, x, int64_t, "%lld", (long long)) - - #define ASSERT3S(x,y,z) VERIFY3S(x, y, z) - #define ASSERT3U(x,y,z) VERIFY3U(x, y, z) - #define ASSERT3P(x,y,z) VERIFY3P(x, y, z) -+#define ASSERT0(x) VERIFY0(x) - - #define ASSERTV(x) x - #define VERIFY(x) ASSERT(x) -diff --git a/include/sys/kstat.h b/include/sys/kstat.h -index 9275c1e..da3c589 100644 ---- a/include/sys/kstat.h -+++ b/include/sys/kstat.h -@@ -83,6 +83,13 @@ struct kstat_s; - typedef int kid_t; /* unique kstat id */ - typedef int kstat_update_t(struct kstat_s *, int); /* dynamic update cb */ - -+typedef struct kstat_module { -+ char ksm_name[KSTAT_STRLEN+1]; /* module name */ -+ struct list_head ksm_module_list; /* module linkage */ -+ struct list_head ksm_kstat_list; /* list of kstat entries */ -+ struct proc_dir_entry *ksm_proc; /* proc entry */ -+} kstat_module_t; -+ - typedef struct kstat_s { - int ks_magic; /* magic value */ - kid_t ks_kid; /* unique kstat ID */ -@@ -102,6 +109,7 @@ typedef struct kstat_s { - void *ks_private; /* private data */ - kmutex_t ks_lock; /* kstat data lock */ - struct list_head ks_list; /* kstat linkage */ -+ kstat_module_t *ks_owner; /* kstat module linkage */ - } kstat_t; - - typedef struct kstat_named_s { -diff --git a/include/sys/timer.h b/include/sys/timer.h -index 096eb1a..2542510 100644 ---- a/include/sys/timer.h -+++ b/include/sys/timer.h -@@ -35,7 +35,12 @@ - #define ddi_get_lbolt() ((clock_t)jiffies) - #define ddi_get_lbolt64() ((int64_t)get_jiffies_64()) - --#define delay(ticks) schedule_timeout((long)(ticks)) -+#define delay(ticks) schedule_timeout_uninterruptible(ticks) -+ -+#define SEC_TO_TICK(sec) ((sec) * HZ) -+#define MSEC_TO_TICK(ms) msecs_to_jiffies(ms) -+#define USEC_TO_TICK(us) usecs_to_jiffies(us) -+#define NSEC_TO_TICK(ns) usecs_to_jiffies(ns / NSEC_PER_USEC) - - #endif /* _SPL_TIMER_H */ - -diff --git a/include/sys/vmsystm.h b/include/sys/vmsystm.h -index 9c52d28..34aea2b 100644 ---- a/include/sys/vmsystm.h -+++ b/include/sys/vmsystm.h -@@ -74,10 +74,12 @@ extern size_t vmem_size(vmem_t *vmp, int typemask); - #ifndef HAVE_GET_VMALLOC_INFO - #ifdef CONFIG_MMU - -+#ifndef HAVE_VMALLOC_INFO - struct vmalloc_info { - unsigned long used; - unsigned long largest_chunk; - }; -+#endif - - typedef void (*get_vmalloc_info_t)(struct vmalloc_info *); - extern get_vmalloc_info_t get_vmalloc_info_fn; -diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c -index a0ca2d2..8547fa7 100644 ---- a/module/spl/spl-kmem.c -+++ b/module/spl/spl-kmem.c -@@ -403,9 +403,9 @@ kmem_del_init(spinlock_t *lock, struct hlist_head *table, int bits, const void * - - spin_lock_irqsave(lock, flags); - -- head = &table[hash_ptr(addr, bits)]; -- hlist_for_each_rcu(node, head) { -- p = list_entry_rcu(node, struct kmem_debug, kd_hlist); -+ head = &table[hash_ptr((void *)addr, bits)]; -+ hlist_for_each(node, head) { -+ p = list_entry(node, struct kmem_debug, kd_hlist); - if (p->kd_addr == addr) { - hlist_del_init(&p->kd_hlist); - list_del_init(&p->kd_list); -@@ -497,7 +497,7 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line, - dptr->kd_line = line; - - spin_lock_irqsave(&kmem_lock, irq_flags); -- hlist_add_head_rcu(&dptr->kd_hlist, -+ hlist_add_head(&dptr->kd_hlist, - &kmem_table[hash_ptr(ptr, KMEM_HASH_BITS)]); - list_add_tail(&dptr->kd_list, &kmem_list); - spin_unlock_irqrestore(&kmem_lock, irq_flags); -@@ -538,10 +538,10 @@ kmem_free_track(const void *ptr, size_t size) - - kfree(dptr->kd_func); - -- memset(dptr, 0x5a, sizeof(kmem_debug_t)); -+ memset((void *)dptr, 0x5a, sizeof(kmem_debug_t)); - kfree(dptr); - -- memset(ptr, 0x5a, size); -+ memset((void *)ptr, 0x5a, size); - kfree(ptr); - - SEXIT; -@@ -612,7 +612,7 @@ vmem_alloc_track(size_t size, int flags, const char *func, int line) - dptr->kd_line = line; - - spin_lock_irqsave(&vmem_lock, irq_flags); -- hlist_add_head_rcu(&dptr->kd_hlist, -+ hlist_add_head(&dptr->kd_hlist, - &vmem_table[hash_ptr(ptr, VMEM_HASH_BITS)]); - list_add_tail(&dptr->kd_list, &vmem_list); - spin_unlock_irqrestore(&vmem_lock, irq_flags); -@@ -653,10 +653,10 @@ vmem_free_track(const void *ptr, size_t size) - - kfree(dptr->kd_func); - -- memset(dptr, 0x5a, sizeof(kmem_debug_t)); -+ memset((void *)dptr, 0x5a, sizeof(kmem_debug_t)); - kfree(dptr); - -- memset(ptr, 0x5a, size); -+ memset((void *)ptr, 0x5a, size); - vfree(ptr); - - SEXIT; -@@ -2418,13 +2418,6 @@ spl_kmem_init(void) - int rc = 0; - SENTRY; - -- init_rwsem(&spl_kmem_cache_sem); -- INIT_LIST_HEAD(&spl_kmem_cache_list); -- spl_kmem_cache_taskq = taskq_create("spl_kmem_cache", -- 1, maxclsyspri, 1, 32, TASKQ_PREPOPULATE); -- -- spl_register_shrinker(&spl_kmem_cache_shrinker); -- - #ifdef DEBUG_KMEM - kmem_alloc_used_set(0); - vmem_alloc_used_set(0); -@@ -2432,12 +2425,25 @@ spl_kmem_init(void) - spl_kmem_init_tracking(&kmem_list, &kmem_lock, KMEM_TABLE_SIZE); - spl_kmem_init_tracking(&vmem_list, &vmem_lock, VMEM_TABLE_SIZE); - #endif -+ -+ init_rwsem(&spl_kmem_cache_sem); -+ INIT_LIST_HEAD(&spl_kmem_cache_list); -+ spl_kmem_cache_taskq = taskq_create("spl_kmem_cache", -+ 1, maxclsyspri, 1, 32, TASKQ_PREPOPULATE); -+ -+ spl_register_shrinker(&spl_kmem_cache_shrinker); -+ - SRETURN(rc); - } - - void - spl_kmem_fini(void) - { -+ SENTRY; -+ -+ spl_unregister_shrinker(&spl_kmem_cache_shrinker); -+ taskq_destroy(spl_kmem_cache_taskq); -+ - #ifdef DEBUG_KMEM - /* Display all unreclaimed memory addresses, including the - * allocation size and the first few bytes of what's located -@@ -2457,10 +2463,6 @@ spl_kmem_fini(void) - spl_kmem_fini_tracking(&kmem_list, &kmem_lock); - spl_kmem_fini_tracking(&vmem_list, &vmem_lock); - #endif /* DEBUG_KMEM */ -- SENTRY; -- -- spl_unregister_shrinker(&spl_kmem_cache_shrinker); -- taskq_destroy(spl_kmem_cache_taskq); - - SEXIT; - } -diff --git a/module/spl/spl-kstat.c b/module/spl/spl-kstat.c -index b7e4b94..4e900c0 100644 ---- a/module/spl/spl-kstat.c -+++ b/module/spl/spl-kstat.c -@@ -33,9 +33,12 @@ - #endif - - #define SS_DEBUG_SUBSYS SS_KSTAT -+#ifndef HAVE_PDE_DATA -+#define PDE_DATA(x) (PDE(x)->data) -+#endif - --static spinlock_t kstat_lock; --static struct list_head kstat_list; -+static kmutex_t kstat_module_lock; -+static struct list_head kstat_module_list; - static kid_t kstat_id; - - static void -@@ -348,6 +351,47 @@ static struct seq_operations kstat_seq_ops = { - .stop = kstat_seq_stop, - }; - -+static kstat_module_t * -+kstat_find_module(char *name) -+{ -+ kstat_module_t *module; -+ -+ list_for_each_entry(module, &kstat_module_list, ksm_module_list) -+ if (strncmp(name, module->ksm_name, KSTAT_STRLEN) == 0) -+ return (module); -+ -+ return (NULL); -+} -+ -+static kstat_module_t * -+kstat_create_module(char *name) -+{ -+ kstat_module_t *module; -+ struct proc_dir_entry *pde; -+ -+ pde = proc_mkdir(name, proc_spl_kstat); -+ if (pde == NULL) -+ return (NULL); -+ -+ module = kmem_alloc(sizeof (kstat_module_t), KM_SLEEP); -+ module->ksm_proc = pde; -+ strlcpy(module->ksm_name, name, KSTAT_STRLEN+1); -+ INIT_LIST_HEAD(&module->ksm_kstat_list); -+ list_add_tail(&module->ksm_module_list, &kstat_module_list); -+ -+ return (module); -+ -+} -+ -+static void -+kstat_delete_module(kstat_module_t *module) -+{ -+ ASSERT(list_empty(&module->ksm_kstat_list)); -+ remove_proc_entry(module->ksm_name, proc_spl_kstat); -+ list_del(&module->ksm_module_list); -+ kmem_free(module, sizeof(kstat_module_t)); -+} -+ - static int - proc_kstat_open(struct inode *inode, struct file *filp) - { -@@ -359,7 +403,7 @@ proc_kstat_open(struct inode *inode, struct file *filp) - return rc; - - f = filp->private_data; -- f->private = PDE(inode)->data; -+ f->private = PDE_DATA(inode); - - return rc; - } -@@ -390,10 +434,10 @@ __kstat_create(const char *ks_module, int ks_instance, const char *ks_name, - if (ksp == NULL) - return ksp; - -- spin_lock(&kstat_lock); -+ mutex_enter(&kstat_module_lock); - ksp->ks_kid = kstat_id; - kstat_id++; -- spin_unlock(&kstat_lock); -+ mutex_exit(&kstat_module_lock); - - ksp->ks_magic = KS_MAGIC; - mutex_init(&ksp->ks_lock, NULL, MUTEX_DEFAULT, NULL); -@@ -456,71 +500,64 @@ EXPORT_SYMBOL(__kstat_create); - void - __kstat_install(kstat_t *ksp) - { -- struct proc_dir_entry *de_module, *de_name; -+ kstat_module_t *module; - kstat_t *tmp; -- int rc = 0; -- SENTRY; -- -- spin_lock(&kstat_lock); - -- /* Item may only be added to the list once */ -- list_for_each_entry(tmp, &kstat_list, ks_list) { -- if (tmp == ksp) { -- spin_unlock(&kstat_lock); -- SGOTO(out, rc = -EEXIST); -- } -- } -+ ASSERT(ksp); - -- list_add_tail(&ksp->ks_list, &kstat_list); -- spin_unlock(&kstat_lock); -+ mutex_enter(&kstat_module_lock); - -- de_module = proc_dir_entry_find(proc_spl_kstat, ksp->ks_module); -- if (de_module == NULL) { -- de_module = proc_mkdir(ksp->ks_module, proc_spl_kstat); -- if (de_module == NULL) -- SGOTO(out, rc = -EUNATCH); -+ module = kstat_find_module(ksp->ks_module); -+ if (module == NULL) { -+ module = kstat_create_module(ksp->ks_module); -+ if (module == NULL) -+ goto out; - } - -- de_name = create_proc_entry(ksp->ks_name, 0444, de_module); -- if (de_name == NULL) -- SGOTO(out, rc = -EUNATCH); -+ /* -+ * Only one entry by this name per-module, on failure the module -+ * shouldn't be deleted because we know it has at least one entry. -+ */ -+ list_for_each_entry(tmp, &module->ksm_kstat_list, ks_list) -+ if (strncmp(tmp->ks_name, ksp->ks_name, KSTAT_STRLEN) == 0) -+ goto out; -+ -+ list_add_tail(&ksp->ks_list, &module->ksm_kstat_list); - - mutex_enter(&ksp->ks_lock); -- ksp->ks_proc = de_name; -- de_name->proc_fops = &proc_kstat_operations; -- de_name->data = (void *)ksp; -+ ksp->ks_owner = module; -+ ksp->ks_proc = proc_create_data(ksp->ks_name, 0444, -+ module->ksm_proc, &proc_kstat_operations, (void *)ksp); -+ if (ksp->ks_proc == NULL) { -+ list_del_init(&ksp->ks_list); -+ if (list_empty(&module->ksm_kstat_list)) -+ kstat_delete_module(module); -+ } - mutex_exit(&ksp->ks_lock); - out: -- if (rc) { -- spin_lock(&kstat_lock); -- list_del_init(&ksp->ks_list); -- spin_unlock(&kstat_lock); -- } -- -- SEXIT; -+ mutex_exit(&kstat_module_lock); - } - EXPORT_SYMBOL(__kstat_install); - - void - __kstat_delete(kstat_t *ksp) - { -- struct proc_dir_entry *de_module; -+ kstat_module_t *module = ksp->ks_owner; - -- spin_lock(&kstat_lock); -- list_del_init(&ksp->ks_list); -- spin_unlock(&kstat_lock); -+ mutex_enter(&kstat_module_lock); -+ list_del_init(&ksp->ks_list); -+ mutex_exit(&kstat_module_lock); - -- if (ksp->ks_proc) { -- de_module = ksp->ks_proc->parent; -- remove_proc_entry(ksp->ks_name, de_module); -+ if (ksp->ks_proc) { -+ remove_proc_entry(ksp->ks_name, module->ksm_proc); - -- /* Remove top level module directory if it's empty */ -- if (proc_dir_entries(de_module) == 0) -- remove_proc_entry(de_module->name, de_module->parent); -+ /* Remove top level module directory if it's empty */ -+ if (list_empty(&module->ksm_kstat_list)) -+ kstat_delete_module(module); - } - - if (!(ksp->ks_flags & KSTAT_FLAG_VIRTUAL)) -- kmem_free(ksp->ks_data, ksp->ks_data_size); -+ kmem_free(ksp->ks_data, ksp->ks_data_size); - - mutex_destroy(&ksp->ks_lock); - kmem_free(ksp, sizeof(*ksp)); -@@ -533,8 +570,8 @@ int - spl_kstat_init(void) - { - SENTRY; -- spin_lock_init(&kstat_lock); -- INIT_LIST_HEAD(&kstat_list); -+ mutex_init(&kstat_module_lock, NULL, MUTEX_DEFAULT, NULL); -+ INIT_LIST_HEAD(&kstat_module_list); - kstat_id = 0; - SRETURN(0); - } -@@ -543,7 +580,8 @@ void - spl_kstat_fini(void) - { - SENTRY; -- ASSERT(list_empty(&kstat_list)); -+ ASSERT(list_empty(&kstat_module_list)); -+ mutex_destroy(&kstat_module_lock); - SEXIT; - } - -diff --git a/module/spl/spl-proc.c b/module/spl/spl-proc.c -index cd4fa1b..b8379d0 100644 ---- a/module/spl/spl-proc.c -+++ b/module/spl/spl-proc.c -@@ -1120,39 +1120,6 @@ static struct ctl_table spl_root[] = { - { 0 } - }; - --static int --proc_dir_entry_match(int len, const char *name, struct proc_dir_entry *de) --{ -- if (de->namelen != len) -- return 0; -- -- return !memcmp(name, de->name, len); --} -- --struct proc_dir_entry * --proc_dir_entry_find(struct proc_dir_entry *root, const char *str) --{ -- struct proc_dir_entry *de; -- -- for (de = root->subdir; de; de = de->next) -- if (proc_dir_entry_match(strlen(str), str, de)) -- return de; -- -- return NULL; --} -- --int --proc_dir_entries(struct proc_dir_entry *root) --{ -- struct proc_dir_entry *de; -- int i = 0; -- -- for (de = root->subdir; de; de = de->next) -- i++; -- -- return i; --} -- - int - spl_proc_init(void) - { -@@ -1174,11 +1141,11 @@ spl_proc_init(void) - if (proc_spl_kmem == NULL) - SGOTO(out, rc = -EUNATCH); - -- proc_spl_kmem_slab = create_proc_entry("slab", 0444, proc_spl_kmem); -+ proc_spl_kmem_slab = proc_create_data("slab", 0444, -+ proc_spl_kmem, &proc_slab_operations, NULL); - if (proc_spl_kmem_slab == NULL) - SGOTO(out, rc = -EUNATCH); - -- proc_spl_kmem_slab->proc_fops = &proc_slab_operations; - #endif /* DEBUG_KMEM */ - - proc_spl_kstat = proc_mkdir("kstat", proc_spl); -diff --git a/module/spl/spl-taskq.c b/module/spl/spl-taskq.c -index 4feca04..bcdc98f 100644 ---- a/module/spl/spl-taskq.c -+++ b/module/spl/spl-taskq.c -@@ -342,39 +342,27 @@ taskq_find(taskq_t *tq, taskqid_t id, int *active) - SRETURN(NULL); - } - --/* -- * The taskq_wait_id() function blocks until the passed task id completes. -- * This does not guarantee that all lower task id's have completed. -- */ --void --taskq_wait_id(taskq_t *tq, taskqid_t id) -+static int -+taskq_wait_id_check(taskq_t *tq, taskqid_t id) - { -- DEFINE_WAIT(wait); -- taskq_ent_t *t; - int active = 0; -- SENTRY; -- -- ASSERT(tq); -- ASSERT(id > 0); -+ int rc; - - spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); -- t = taskq_find(tq, id, &active); -- if (t) -- prepare_to_wait(&t->tqent_waitq, &wait, TASK_UNINTERRUPTIBLE); -+ rc = (taskq_find(tq, id, &active) == NULL); - spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); - -- /* -- * We rely on the kernels autoremove_wake_function() function to -- * remove us from the wait queue in the context of wake_up(). -- * Once woken the taskq_ent_t pointer must never be accessed. -- */ -- if (t) { -- t = NULL; -- schedule(); -- __set_current_state(TASK_RUNNING); -- } -+ return (rc); -+} - -- SEXIT; -+/* -+ * The taskq_wait_id() function blocks until the passed task id completes. -+ * This does not guarantee that all lower task ids have completed. -+ */ -+void -+taskq_wait_id(taskq_t *tq, taskqid_t id) -+{ -+ wait_event(tq->tq_wait_waitq, taskq_wait_id_check(tq, id)); - } - EXPORT_SYMBOL(taskq_wait_id); - -diff --git a/module/spl/spl-time.c b/module/spl/spl-time.c -index 8f43b54..20fd0e3 100644 ---- a/module/spl/spl-time.c -+++ b/module/spl/spl-time.c -@@ -40,11 +40,10 @@ extern unsigned long long monotonic_clock(void); - void - __gethrestime(timestruc_t *ts) - { -- struct timeval tv; -+ struct timespec tspec = current_kernel_time(); - -- do_gettimeofday(&tv); -- ts->tv_sec = tv.tv_sec; -- ts->tv_nsec = tv.tv_usec * NSEC_PER_USEC; -+ ts->tv_sec = tspec.tv_sec; -+ ts->tv_nsec = tspec.tv_nsec; - } - EXPORT_SYMBOL(__gethrestime); - -diff --git a/module/splat/splat-atomic.c b/module/splat/splat-atomic.c -index df3b38f..f702196 100644 ---- a/module/splat/splat-atomic.c -+++ b/module/splat/splat-atomic.c -@@ -26,6 +26,7 @@ - - #include - #include -+#include - #include "splat-internal.h" - - #define SPLAT_ATOMIC_NAME "atomic" -diff --git a/module/splat/splat-thread.c b/module/splat/splat-thread.c -index a1e70db..e55acd0 100644 ---- a/module/splat/splat-thread.c -+++ b/module/splat/splat-thread.c -@@ -26,6 +26,7 @@ - - #include - #include -+#include - #include "splat-internal.h" - - #define SPLAT_THREAD_NAME "thread" -diff --git a/module/splat/splat-time.c b/module/splat/splat-time.c -index ca60c45..cd513c9 100644 ---- a/module/splat/splat-time.c -+++ b/module/splat/splat-time.c -@@ -25,6 +25,7 @@ - \*****************************************************************************/ - - #include -+#include - #include "splat-internal.h" - - #define SPLAT_TIME_NAME "time" -diff --git a/rpm/fedora/spl-kmod.spec.in b/rpm/fedora/spl-kmod.spec.in -index f83ff60..79e1f9d 100644 ---- a/rpm/fedora/spl-kmod.spec.in -+++ b/rpm/fedora/spl-kmod.spec.in -@@ -44,7 +44,7 @@ BuildRequires: %{_bindir}/kmodtool - # Kmodtool does its magic here. A patched version of kmodtool is shipped - # with the source rpm until kmod development packages are supported upstream. - # https://bugzilla.rpmfusion.org/show_bug.cgi?id=2714 --%{expand:%(sh %{SOURCE10} --target %{_target_cpu} --repo %{repo} --kmodname %{name} --devel %{?prefix:--prefix "%{?prefix}"} %{?buildforkernels:--%{buildforkernels}} %{?kernels:--for-kernels "%{?kernels}"} 2>/dev/null) } -+%{expand:%(sh %{SOURCE10} --target %{_target_cpu} --repo %{repo} --kmodname %{name} --devel %{?prefix:--prefix "%{?prefix}"} %{?buildforkernels:--%{buildforkernels}} %{?kernels:--for-kernels "%{?kernels}"} %{?kernelbuildroot:--buildroot "%{?kernelbuildroot}"} 2>/dev/null) } - - - %description -@@ -56,7 +56,7 @@ several interfaces provided by the Solaris kernel. - %{?kmodtool_check} - - # Print kmodtool output for debugging purposes: --sh %{SOURCE10} --target %{_target_cpu} --repo %{repo} --kmodname %{name} --devel %{?buildforkernels:--%{buildforkernels}} %{?kernels:--for-kernels "%{?kernels}"} 2>/dev/null -+sh %{SOURCE10} --target %{_target_cpu} --repo %{repo} --kmodname %{name} --devel %{?buildforkernels:--%{buildforkernels}} %{?kernels:--for-kernels "%{?kernels}"} %{?kernelbuildroot:--buildroot "%{?kernelbuildroot}"} 2>/dev/null - - %if %{with debug} - %define debug --enable-debug -diff --git a/rpm/generic/spl-dkms.spec.in b/rpm/generic/spl-dkms.spec.in -index 148d612..dbf4723 100644 ---- a/rpm/generic/spl-dkms.spec.in -+++ b/rpm/generic/spl-dkms.spec.in -@@ -15,6 +15,8 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - BuildArch: noarch - - Requires: dkms >= 2.2.0.2 -+Requires: gcc, make, perl -+Requires: kernel-devel - Provides: %{module}-kmod = %{version} - - %description -diff --git a/rpm/generic/spl-kmod.spec.in b/rpm/generic/spl-kmod.spec.in -index 224660b..1b0a6f1 100644 ---- a/rpm/generic/spl-kmod.spec.in -+++ b/rpm/generic/spl-kmod.spec.in -@@ -18,7 +18,7 @@ License: GPLv2+ - URL: http://zfsonlinux.org/ - Source0: %{module}-%{version}.tar.gz - Source10: kmodtool --BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id} -u -n) - - # The developments headers will conflict with the dkms packages. - Conflicts: %{module}-dkms -@@ -44,7 +44,7 @@ Conflicts: %{module}-dkms - # Kmodtool does its magic here. A patched version of kmodtool is shipped - # because the latest versions may not be available for your distribution. - # https://bugzilla.rpmfusion.org/show_bug.cgi?id=2714 --%{expand:%(bash %{SOURCE10} --target %{_target_cpu} --kmodname %{name} --devel %{?prefix:--prefix "%{?prefix}"} %{?kernels:--for-kernels "%{?kernels}"} 2>/dev/null) } -+%{expand:%(bash %{SOURCE10} --target %{_target_cpu} --kmodname %{name} --devel %{?prefix:--prefix "%{?prefix}"} %{?kernels:--for-kernels "%{?kernels}"} %{?kernelbuildroot:--buildroot "%{?kernelbuildroot}"} 2>/dev/null) } - - - %description -@@ -56,7 +56,7 @@ several interfaces provided by the Solaris kernel. - %{?kmodtool_check} - - # Print kmodtool output for debugging purposes: --bash %{SOURCE10} --target %{_target_cpu} --kmodname %{name} --devel %{?prefix:--prefix "%{?prefix}"} %{?kernels:--for-kernels "%{?kernels}"} 2>/dev/null -+bash %{SOURCE10} --target %{_target_cpu} --kmodname %{name} --devel %{?prefix:--prefix "%{?prefix}"} %{?kernels:--for-kernels "%{?kernels}"} %{?kernelbuildroot:--buildroot "%{?kernelbuildroot}"} 2>/dev/null - - %if %{with debug} - %define debug --enable-debug -@@ -106,12 +106,12 @@ for kernel_version in %{?kernel_versions}; do - --with-linux="${kernel_version##*___}" \ - --with-linux-obj="${kernel_version##*___}" \ - %else -- --with-linux=\ -- %(if [ -e /lib/modules/${kernel_version%%___*}/source ]; then \ -- echo "/lib/modules/${kernel_version%%___*}/source" \ -+ --with-linux="$( \ -+ if [ -e "/lib/modules/${kernel_version%%___*}/source" ]; then \ -+ echo "/lib/modules/${kernel_version%%___*}/source"; \ - else \ -- echo "/lib/modules/${kernel_version%%___*}/build" \ -- fi) \ -+ echo "/lib/modules/${kernel_version%%___*}/build"; \ -+ fi)" \ - --with-linux-obj="/lib/modules/${kernel_version%%___*}/build" \ - %endif - %{debug} \ -diff --git a/scripts/kmodtool b/scripts/kmodtool -old mode 100755 -new mode 100644 -index 2fe014c..6b73780 ---- a/scripts/kmodtool -+++ b/scripts/kmodtool -@@ -37,6 +37,7 @@ kernel_versions_to_build_for= - prefix= - filterfile= - target= -+buildroot= - - error_out() - { -@@ -305,9 +306,9 @@ print_customrpmtemplate () - { - for kernel in ${1} - do -- if [[ -e "/usr/src/kernels/${kernel}" ]] ; then -+ if [[ -e "${buildroot}/usr/src/kernels/${kernel}" ]] ; then - # this looks like a Fedora/RH kernel -- print a normal template (which includes the proper BR) and be happy :) -- kernel_versions="${kernel_versions}${kernel}___%{_usrsrc}/kernels/${kernel} " -+ kernel_versions="${kernel_versions}${kernel}___${buildroot}%{_usrsrc}/kernels/${kernel} " - - # parse kernel versions string and print template - local kernel_verrelarch=${kernel%%${kernels_known_variants}} -@@ -382,7 +383,6 @@ myprog_help () - echo "Usage: $(basename ${0}) [OPTIONS]" - echo $'\n'"Creates a template to be used during kmod building" - echo $'\n'"Available options:" -- # FIXME echo " --datadir -- look for our shared files in " - echo " --filterfile -- filter the results with grep --file " - echo " --for-kernels -- created templates only for these kernels" - echo " --kmodname -- name of the kmod (required)" -@@ -390,6 +390,7 @@ myprog_help () - echo " --noakmod -- no akmod package" - echo " --repo -- use buildsys-build--kerneldevpkgs" - echo " --target -- target-arch (required)" -+ echo " --buildroot -- Build root (place to look for build files)" - } - - while [ "${1}" ] ; do -@@ -478,6 +479,11 @@ while [ "${1}" ] ; do - shift - build_kernels="current" - ;; -+ --buildroot) -+ shift -+ buildroot="${1}" -+ shift -+ ;; - --help) - myprog_help - exit 0 diff --git a/spl/spl_git_head.patch b/spl/spl_git_head.patch deleted file mode 100644 index 7651c2f..0000000 --- a/spl/spl_git_head.patch +++ /dev/null @@ -1,1044 +0,0 @@ -diff --git a/Makefile.am b/Makefile.am -index cea9db9..23dc257 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -1,3 +1,6 @@ -+ -+ACLOCAL_AMFLAGS = -I config -+ - include $(top_srcdir)/config/rpm.am - include $(top_srcdir)/config/deb.am - include $(top_srcdir)/config/tgz.am -diff --git a/autogen.sh b/autogen.sh -index 343265c..427394a 100755 ---- a/autogen.sh -+++ b/autogen.sh -@@ -1,7 +1,4 @@ - #!/bin/sh - --aclocal -I config --libtoolize --automake --copy --autoheader --automake --add-missing --include-deps --copy --autoconf -+autoreconf -fiv -+rm -Rf autom4te.cache -diff --git a/config/Rules.am b/config/Rules.am -index 0b41ec4..7c5d328 100644 ---- a/config/Rules.am -+++ b/config/Rules.am -@@ -9,5 +9,6 @@ - DEFAULT_INCLUDES = -include ${top_builddir}/spl_config.h - - AM_LIBTOOLFLAGS = --silent -+AM_CPPFLAGS = -D__USE_LARGEFILE64 - AM_CFLAGS = -Wall -Wshadow -Wstrict-prototypes -fno-strict-aliasing --AM_CFLAGS += -D__USE_LARGEFILE64 ${DEBUG_CFLAGS} -+AM_CFLAGS += ${DEBUG_CFLAGS} -diff --git a/config/deb.am b/config/deb.am -index 5efbd9d..a2bad02 100644 ---- a/config/deb.am -+++ b/config/deb.am -@@ -34,7 +34,7 @@ if CONFIG_KERNEL - version=${VERSION}-${RELEASE}; \ - arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \ - pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \ -- fakeroot $(ALIEN) --scripts --to-deb $$pkg1; \ -+ fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \ - $(RM) $$pkg1 - endif - -@@ -44,7 +44,7 @@ if CONFIG_USER - version=${VERSION}-${RELEASE}; \ - arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \ - pkg1=$${name}-$${version}.$${arch}.rpm; \ -- fakeroot $(ALIEN) --scripts --to-deb $$pkg1; \ -+ fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \ - $(RM) $$pkg1 - endif - -diff --git a/config/spl-build.m4 b/config/spl-build.m4 -index 8a8e3ba..da179e3 100644 ---- a/config/spl-build.m4 -+++ b/config/spl-build.m4 -@@ -33,6 +33,8 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ - SPL_AC_TASK_CURR - SPL_AC_CTL_UNNUMBERED - SPL_AC_CTL_NAME -+ SPL_AC_VMALLOC_INFO -+ SPL_AC_PDE_DATA - SPL_AC_FLS64 - SPL_AC_DEVICE_CREATE - SPL_AC_5ARGS_DEVICE_CREATE -@@ -1358,6 +1360,43 @@ AC_DEFUN([SPL_AC_GET_VMALLOC_INFO], - ]) - - dnl # -+dnl # 3.10 API change, -+dnl # struct vmalloc_info is now declared in linux/vmalloc.h -+dnl # -+AC_DEFUN([SPL_AC_VMALLOC_INFO], [ -+ AC_MSG_CHECKING([whether struct vmalloc_info is declared]) -+ SPL_LINUX_TRY_COMPILE([ -+ #include -+ struct vmalloc_info { void *a; }; -+ ],[ -+ return 0; -+ ],[ -+ AC_MSG_RESULT(no) -+ ],[ -+ AC_MSG_RESULT(yes) -+ AC_DEFINE(HAVE_VMALLOC_INFO, 1, [yes]) -+ ]) -+]) -+ -+dnl # -+dnl # 3.10 API change, -+dnl # PDE is replaced by PDE_DATA -+dnl # -+AC_DEFUN([SPL_AC_PDE_DATA], [ -+ AC_MSG_CHECKING([whether PDE_DATA() is available]) -+ SPL_LINUX_TRY_COMPILE_SYMBOL([ -+ #include -+ ], [ -+ PDE_DATA(NULL); -+ ], [PDE_DATA], [], [ -+ AC_MSG_RESULT(yes) -+ AC_DEFINE(HAVE_PDE_DATA, 1, [yes]) -+ ],[ -+ AC_MSG_RESULT(no) -+ ]) -+]) -+ -+dnl # - dnl # 2.6.17 API change - dnl # The helper functions first_online_pgdat(), next_online_pgdat(), and - dnl # next_zone() are introduced to simplify for_each_zone(). These symbols -diff --git a/config/spl-meta.m4 b/config/spl-meta.m4 -index 28103bc..a51fa79 100644 ---- a/config/spl-meta.m4 -+++ b/config/spl-meta.m4 -@@ -1,15 +1,37 @@ --############################################################################### --# Written by Chris Dunlap . --# Modified by Brian Behlendorf . --############################################################################### --# SPL_AC_META: Read metadata from the META file. When building from a --# git repository the SPL_META_RELEASE field will be overwritten if there --# is an annotated tag matching the form SPL_META_NAME-SPL_META_VERSION-*. --# This allows for working builds to be uniquely identified using the git --# commit hash. --############################################################################### -- -+dnl # -+dnl # DESCRIPTION: -+dnl # Read meta data from the META file. When building from a git repository -+dnl # the SPL_META_RELEASE field will be overwritten if there is an annotated -+dnl # tag matching the form SPL_META_NAME-SPL_META_VERSION-*. This allows -+dnl # for working builds to be uniquely identified using the git commit hash. -+dnl # -+dnl # The META file format is as follows: -+dnl # ^[ ]*KEY:[ \t]+VALUE$ -+dnl # -+dnl # In other words: -+dnl # - KEY is separated from VALUE by a colon and one or more spaces/tabs. -+dnl # - KEY and VALUE are case sensitive. -+dnl # - Leading spaces are ignored. -+dnl # - First match wins for duplicate keys. -+dnl # -+dnl # A line can be commented out by preceding it with a '#' (or technically -+dnl # any non-space character since that will prevent the regex from -+dnl # matching). -+dnl # -+dnl # WARNING: -+dnl # Placing a colon followed by a space or tab (ie, ":[ \t]+") within the -+dnl # VALUE will prematurely terminate the string since that sequence is -+dnl # used as the awk field separator. -+dnl # -+dnl # KEYS: -+dnl # The following META keys are recognized: -+dnl # Name, Version, Release, Date, Author, LT_Current, LT_Revision, LT_Age -+dnl # -+dnl # Written by Chris Dunlap . -+dnl # Modified by Brian Behlendorf . -+dnl # - AC_DEFUN([SPL_AC_META], [ -+ AC_PROG_AWK - AC_MSG_CHECKING([metadata]) - - META="$srcdir/META" -@@ -17,7 +39,7 @@ AC_DEFUN([SPL_AC_META], [ - if test -f "$META"; then - _spl_ac_meta_type="META file" - -- SPL_META_NAME=_SPL_AC_META_GETVAL([(?:NAME|PROJECT|PACKAGE)]); -+ SPL_META_NAME=_SPL_AC_META_GETVAL([(Name|Project|Package)]); - if test -n "$SPL_META_NAME"; then - AC_DEFINE_UNQUOTED([SPL_META_NAME], ["$SPL_META_NAME"], - [Define the project name.] -@@ -25,7 +47,7 @@ AC_DEFUN([SPL_AC_META], [ - AC_SUBST([SPL_META_NAME]) - fi - -- SPL_META_VERSION=_SPL_AC_META_GETVAL([VERSION]); -+ SPL_META_VERSION=_SPL_AC_META_GETVAL([Version]); - if test -n "$SPL_META_VERSION"; then - AC_DEFINE_UNQUOTED([SPL_META_VERSION], ["$SPL_META_VERSION"], - [Define the project version.] -@@ -33,8 +55,8 @@ AC_DEFUN([SPL_AC_META], [ - AC_SUBST([SPL_META_VERSION]) - fi - -- SPL_META_RELEASE=_SPL_AC_META_GETVAL([RELEASE]); -- if git rev-parse --git-dir > /dev/null 2>&1; then -+ SPL_META_RELEASE=_SPL_AC_META_GETVAL([Release]); -+ if test ! -f ".nogitrelease" && git rev-parse --git-dir > /dev/null 2>&1; then - _match="${SPL_META_NAME}-${SPL_META_VERSION}*" - _alias=$(git describe --match=${_match} 2>/dev/null) - _release=$(echo ${_alias}|cut -f3- -d'-'|sed 's/-/_/g') -@@ -65,7 +87,7 @@ AC_DEFUN([SPL_AC_META], [ - AC_SUBST([SPL_META_ALIAS]) - fi - -- SPL_META_DATA=_SPL_AC_META_GETVAL([DATE]); -+ SPL_META_DATA=_SPL_AC_META_GETVAL([Date]); - if test -n "$SPL_META_DATA"; then - AC_DEFINE_UNQUOTED([SPL_META_DATA], ["$SPL_META_DATA"], - [Define the project release date.] -@@ -73,7 +95,7 @@ AC_DEFUN([SPL_AC_META], [ - AC_SUBST([SPL_META_DATA]) - fi - -- SPL_META_AUTHOR=_SPL_AC_META_GETVAL([AUTHOR]); -+ SPL_META_AUTHOR=_SPL_AC_META_GETVAL([Author]); - if test -n "$SPL_META_AUTHOR"; then - AC_DEFINE_UNQUOTED([SPL_META_AUTHOR], ["$SPL_META_AUTHOR"], - [Define the project author.] -@@ -82,9 +104,9 @@ AC_DEFUN([SPL_AC_META], [ - fi - - m4_pattern_allow([^LT_(CURRENT|REVISION|AGE)$]) -- SPL_META_LT_CURRENT=_SPL_AC_META_GETVAL([LT_CURRENT]); -- SPL_META_LT_REVISION=_SPL_AC_META_GETVAL([LT_REVISION]); -- SPL_META_LT_AGE=_SPL_AC_META_GETVAL([LT_AGE]); -+ SPL_META_LT_CURRENT=_SPL_AC_META_GETVAL([LT_Current]); -+ SPL_META_LT_REVISION=_SPL_AC_META_GETVAL([LT_Revision]); -+ SPL_META_LT_AGE=_SPL_AC_META_GETVAL([LT_Age]); - if test -n "$SPL_META_LT_CURRENT" \ - -o -n "$SPL_META_LT_REVISION" \ - -o -n "$SPL_META_LT_AGE"; then -@@ -115,15 +137,18 @@ AC_DEFUN([SPL_AC_META], [ - ] - ) - --AC_DEFUN([_SPL_AC_META_GETVAL], -- [`perl -n\ -- -e "BEGIN { \\$key=shift @ARGV; }"\ -- -e "next unless s/^\s*\\$key@<:@:=@:>@//i;"\ -- -e "s/^((?:@<:@^'\"#@:>@*(?:(@<:@'\"@:>@)@<:@^\2@:>@*\2)*)*)#.*/\\@S|@1/;"\ -- -e "s/^\s+//;"\ -- -e "s/\s+$//;"\ -- -e "s/^(@<:@'\"@:>@)(.*)\1/\\@S|@2/;"\ -- -e "\\$val=\\$_;"\ -- -e "END { print \\$val if defined \\$val; }"\ -- '$1' $META`]dnl -+dnl # _SPL_AC_META_GETVAL (KEY_NAME_OR_REGEX) -+dnl # -+dnl # Returns the META VALUE associated with the given KEY_NAME_OR_REGEX expr. -+dnl # -+dnl # Despite their resemblance to line noise, -+dnl # the "@<:@" and "@:>@" constructs are quadrigraphs for "[" and "]". -+dnl # -+dnl # -+dnl # The "$[]1" and "$[]2" constructs prevent M4 parameter expansion -+dnl # so a literal $1 and $2 will be passed to the resulting awk script, -+dnl # whereas the "$1" will undergo M4 parameter expansion for the META key. -+dnl # -+AC_DEFUN([_SPL_AC_META_GETVAL], -+ [`$AWK -F ':@<:@ \t@:>@+' '$[]1 ~ /^ *$1$/ { print $[]2; exit }' $META`]dnl - ) -diff --git a/configure.ac b/configure.ac -index f9cd542..4772298 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -28,9 +28,10 @@ AC_INIT - AC_LANG(C) - SPL_AC_META - AC_CONFIG_AUX_DIR([config]) -+AC_CONFIG_MACRO_DIR([config]) - AC_CANONICAL_SYSTEM - AM_MAINTAINER_MODE --AM_SILENT_RULES -+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - AM_INIT_AUTOMAKE([$SPL_META_NAME], [$SPL_META_VERSION]) - AC_CONFIG_HEADERS([spl_config.h], [ - (mv spl_config.h spl_config.h.tmp && -diff --git a/copy-builtin b/copy-builtin -index 3277270..cd98b7a 100755 ---- a/copy-builtin -+++ b/copy-builtin -@@ -33,6 +33,7 @@ rm -rf "$KERNEL_DIR/include/spl" "$KERNEL_DIR/spl" - cp --recursive include "$KERNEL_DIR/include/spl" - cp --recursive module "$KERNEL_DIR/spl" - cp spl_config.h "$KERNEL_DIR/" -+cp spl.release.in "$KERNEL_DIR/" - - adjust_obj_paths() - { -diff --git a/include/linux/proc_compat.h b/include/linux/proc_compat.h -index 434ffa3..7b044e7 100644 ---- a/include/linux/proc_compat.h -+++ b/include/linux/proc_compat.h -@@ -43,9 +43,6 @@ - #endif - - extern struct proc_dir_entry *proc_spl_kstat; --struct proc_dir_entry *proc_dir_entry_find(struct proc_dir_entry *root, -- const char *str); --int proc_dir_entries(struct proc_dir_entry *root); - - int spl_proc_init(void); - void spl_proc_fini(void); -diff --git a/include/sys/debug.h b/include/sys/debug.h -index 25ff88e..f3f3529 100644 ---- a/include/sys/debug.h -+++ b/include/sys/debug.h -@@ -35,10 +35,12 @@ - * ASSERT3S() - Assert signed X OP Y is true, if not panic. - * ASSERT3U() - Assert unsigned X OP Y is true, if not panic. - * ASSERT3P() - Assert pointer X OP Y is true, if not panic. -+ * ASSERT0() - Assert value is zero, if not panic. - * VERIFY() - Verify X is true, if not panic. - * VERIFY3S() - Verify signed X OP Y is true, if not panic. - * VERIFY3U() - Verify unsigned X OP Y is true, if not panic. - * VERIFY3P() - Verify pointer X OP Y is true, if not panic. -+ * VERIFY0() - Verify value is zero, if not panic. - */ - - #ifndef _SPL_DEBUG_H -@@ -79,10 +81,12 @@ do { \ - #define VERIFY3U(x,y,z) VERIFY3_IMPL(x, y, z, uint64_t, "%llu", \ - (unsigned long long)) - #define VERIFY3P(x,y,z) VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *)) -+#define VERIFY0(x) VERIFY3_IMPL(0, ==, x, int64_t, "%lld", (long long)) - - #define ASSERT3S(x,y,z) ((void)0) - #define ASSERT3U(x,y,z) ((void)0) - #define ASSERT3P(x,y,z) ((void)0) -+#define ASSERT0(x) ((void)0) - - #else /* Debugging Enabled */ - -@@ -130,10 +134,12 @@ do { \ - #define VERIFY3U(x,y,z) VERIFY3_IMPL(x, y, z, uint64_t, "%llu", \ - (unsigned long long)) - #define VERIFY3P(x,y,z) VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *)) -+#define VERIFY0(x) VERIFY3_IMPL(0, ==, x, int64_t, "%lld", (long long)) - - #define ASSERT3S(x,y,z) VERIFY3S(x, y, z) - #define ASSERT3U(x,y,z) VERIFY3U(x, y, z) - #define ASSERT3P(x,y,z) VERIFY3P(x, y, z) -+#define ASSERT0(x) VERIFY0(x) - - #define ASSERTV(x) x - #define VERIFY(x) ASSERT(x) -diff --git a/include/sys/kstat.h b/include/sys/kstat.h -index 9275c1e..da3c589 100644 ---- a/include/sys/kstat.h -+++ b/include/sys/kstat.h -@@ -83,6 +83,13 @@ struct kstat_s; - typedef int kid_t; /* unique kstat id */ - typedef int kstat_update_t(struct kstat_s *, int); /* dynamic update cb */ - -+typedef struct kstat_module { -+ char ksm_name[KSTAT_STRLEN+1]; /* module name */ -+ struct list_head ksm_module_list; /* module linkage */ -+ struct list_head ksm_kstat_list; /* list of kstat entries */ -+ struct proc_dir_entry *ksm_proc; /* proc entry */ -+} kstat_module_t; -+ - typedef struct kstat_s { - int ks_magic; /* magic value */ - kid_t ks_kid; /* unique kstat ID */ -@@ -102,6 +109,7 @@ typedef struct kstat_s { - void *ks_private; /* private data */ - kmutex_t ks_lock; /* kstat data lock */ - struct list_head ks_list; /* kstat linkage */ -+ kstat_module_t *ks_owner; /* kstat module linkage */ - } kstat_t; - - typedef struct kstat_named_s { -diff --git a/include/sys/timer.h b/include/sys/timer.h -index 096eb1a..2542510 100644 ---- a/include/sys/timer.h -+++ b/include/sys/timer.h -@@ -35,7 +35,12 @@ - #define ddi_get_lbolt() ((clock_t)jiffies) - #define ddi_get_lbolt64() ((int64_t)get_jiffies_64()) - --#define delay(ticks) schedule_timeout((long)(ticks)) -+#define delay(ticks) schedule_timeout_uninterruptible(ticks) -+ -+#define SEC_TO_TICK(sec) ((sec) * HZ) -+#define MSEC_TO_TICK(ms) msecs_to_jiffies(ms) -+#define USEC_TO_TICK(us) usecs_to_jiffies(us) -+#define NSEC_TO_TICK(ns) usecs_to_jiffies(ns / NSEC_PER_USEC) - - #endif /* _SPL_TIMER_H */ - -diff --git a/include/sys/vmsystm.h b/include/sys/vmsystm.h -index 9c52d28..34aea2b 100644 ---- a/include/sys/vmsystm.h -+++ b/include/sys/vmsystm.h -@@ -74,10 +74,12 @@ extern size_t vmem_size(vmem_t *vmp, int typemask); - #ifndef HAVE_GET_VMALLOC_INFO - #ifdef CONFIG_MMU - -+#ifndef HAVE_VMALLOC_INFO - struct vmalloc_info { - unsigned long used; - unsigned long largest_chunk; - }; -+#endif - - typedef void (*get_vmalloc_info_t)(struct vmalloc_info *); - extern get_vmalloc_info_t get_vmalloc_info_fn; -diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c -index a0ca2d2..8547fa7 100644 ---- a/module/spl/spl-kmem.c -+++ b/module/spl/spl-kmem.c -@@ -403,9 +403,9 @@ kmem_del_init(spinlock_t *lock, struct hlist_head *table, int bits, const void * - - spin_lock_irqsave(lock, flags); - -- head = &table[hash_ptr(addr, bits)]; -- hlist_for_each_rcu(node, head) { -- p = list_entry_rcu(node, struct kmem_debug, kd_hlist); -+ head = &table[hash_ptr((void *)addr, bits)]; -+ hlist_for_each(node, head) { -+ p = list_entry(node, struct kmem_debug, kd_hlist); - if (p->kd_addr == addr) { - hlist_del_init(&p->kd_hlist); - list_del_init(&p->kd_list); -@@ -497,7 +497,7 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line, - dptr->kd_line = line; - - spin_lock_irqsave(&kmem_lock, irq_flags); -- hlist_add_head_rcu(&dptr->kd_hlist, -+ hlist_add_head(&dptr->kd_hlist, - &kmem_table[hash_ptr(ptr, KMEM_HASH_BITS)]); - list_add_tail(&dptr->kd_list, &kmem_list); - spin_unlock_irqrestore(&kmem_lock, irq_flags); -@@ -538,10 +538,10 @@ kmem_free_track(const void *ptr, size_t size) - - kfree(dptr->kd_func); - -- memset(dptr, 0x5a, sizeof(kmem_debug_t)); -+ memset((void *)dptr, 0x5a, sizeof(kmem_debug_t)); - kfree(dptr); - -- memset(ptr, 0x5a, size); -+ memset((void *)ptr, 0x5a, size); - kfree(ptr); - - SEXIT; -@@ -612,7 +612,7 @@ vmem_alloc_track(size_t size, int flags, const char *func, int line) - dptr->kd_line = line; - - spin_lock_irqsave(&vmem_lock, irq_flags); -- hlist_add_head_rcu(&dptr->kd_hlist, -+ hlist_add_head(&dptr->kd_hlist, - &vmem_table[hash_ptr(ptr, VMEM_HASH_BITS)]); - list_add_tail(&dptr->kd_list, &vmem_list); - spin_unlock_irqrestore(&vmem_lock, irq_flags); -@@ -653,10 +653,10 @@ vmem_free_track(const void *ptr, size_t size) - - kfree(dptr->kd_func); - -- memset(dptr, 0x5a, sizeof(kmem_debug_t)); -+ memset((void *)dptr, 0x5a, sizeof(kmem_debug_t)); - kfree(dptr); - -- memset(ptr, 0x5a, size); -+ memset((void *)ptr, 0x5a, size); - vfree(ptr); - - SEXIT; -@@ -2418,13 +2418,6 @@ spl_kmem_init(void) - int rc = 0; - SENTRY; - -- init_rwsem(&spl_kmem_cache_sem); -- INIT_LIST_HEAD(&spl_kmem_cache_list); -- spl_kmem_cache_taskq = taskq_create("spl_kmem_cache", -- 1, maxclsyspri, 1, 32, TASKQ_PREPOPULATE); -- -- spl_register_shrinker(&spl_kmem_cache_shrinker); -- - #ifdef DEBUG_KMEM - kmem_alloc_used_set(0); - vmem_alloc_used_set(0); -@@ -2432,12 +2425,25 @@ spl_kmem_init(void) - spl_kmem_init_tracking(&kmem_list, &kmem_lock, KMEM_TABLE_SIZE); - spl_kmem_init_tracking(&vmem_list, &vmem_lock, VMEM_TABLE_SIZE); - #endif -+ -+ init_rwsem(&spl_kmem_cache_sem); -+ INIT_LIST_HEAD(&spl_kmem_cache_list); -+ spl_kmem_cache_taskq = taskq_create("spl_kmem_cache", -+ 1, maxclsyspri, 1, 32, TASKQ_PREPOPULATE); -+ -+ spl_register_shrinker(&spl_kmem_cache_shrinker); -+ - SRETURN(rc); - } - - void - spl_kmem_fini(void) - { -+ SENTRY; -+ -+ spl_unregister_shrinker(&spl_kmem_cache_shrinker); -+ taskq_destroy(spl_kmem_cache_taskq); -+ - #ifdef DEBUG_KMEM - /* Display all unreclaimed memory addresses, including the - * allocation size and the first few bytes of what's located -@@ -2457,10 +2463,6 @@ spl_kmem_fini(void) - spl_kmem_fini_tracking(&kmem_list, &kmem_lock); - spl_kmem_fini_tracking(&vmem_list, &vmem_lock); - #endif /* DEBUG_KMEM */ -- SENTRY; -- -- spl_unregister_shrinker(&spl_kmem_cache_shrinker); -- taskq_destroy(spl_kmem_cache_taskq); - - SEXIT; - } -diff --git a/module/spl/spl-kstat.c b/module/spl/spl-kstat.c -index b7e4b94..4e900c0 100644 ---- a/module/spl/spl-kstat.c -+++ b/module/spl/spl-kstat.c -@@ -33,9 +33,12 @@ - #endif - - #define SS_DEBUG_SUBSYS SS_KSTAT -+#ifndef HAVE_PDE_DATA -+#define PDE_DATA(x) (PDE(x)->data) -+#endif - --static spinlock_t kstat_lock; --static struct list_head kstat_list; -+static kmutex_t kstat_module_lock; -+static struct list_head kstat_module_list; - static kid_t kstat_id; - - static void -@@ -348,6 +351,47 @@ static struct seq_operations kstat_seq_ops = { - .stop = kstat_seq_stop, - }; - -+static kstat_module_t * -+kstat_find_module(char *name) -+{ -+ kstat_module_t *module; -+ -+ list_for_each_entry(module, &kstat_module_list, ksm_module_list) -+ if (strncmp(name, module->ksm_name, KSTAT_STRLEN) == 0) -+ return (module); -+ -+ return (NULL); -+} -+ -+static kstat_module_t * -+kstat_create_module(char *name) -+{ -+ kstat_module_t *module; -+ struct proc_dir_entry *pde; -+ -+ pde = proc_mkdir(name, proc_spl_kstat); -+ if (pde == NULL) -+ return (NULL); -+ -+ module = kmem_alloc(sizeof (kstat_module_t), KM_SLEEP); -+ module->ksm_proc = pde; -+ strlcpy(module->ksm_name, name, KSTAT_STRLEN+1); -+ INIT_LIST_HEAD(&module->ksm_kstat_list); -+ list_add_tail(&module->ksm_module_list, &kstat_module_list); -+ -+ return (module); -+ -+} -+ -+static void -+kstat_delete_module(kstat_module_t *module) -+{ -+ ASSERT(list_empty(&module->ksm_kstat_list)); -+ remove_proc_entry(module->ksm_name, proc_spl_kstat); -+ list_del(&module->ksm_module_list); -+ kmem_free(module, sizeof(kstat_module_t)); -+} -+ - static int - proc_kstat_open(struct inode *inode, struct file *filp) - { -@@ -359,7 +403,7 @@ proc_kstat_open(struct inode *inode, struct file *filp) - return rc; - - f = filp->private_data; -- f->private = PDE(inode)->data; -+ f->private = PDE_DATA(inode); - - return rc; - } -@@ -390,10 +434,10 @@ __kstat_create(const char *ks_module, int ks_instance, const char *ks_name, - if (ksp == NULL) - return ksp; - -- spin_lock(&kstat_lock); -+ mutex_enter(&kstat_module_lock); - ksp->ks_kid = kstat_id; - kstat_id++; -- spin_unlock(&kstat_lock); -+ mutex_exit(&kstat_module_lock); - - ksp->ks_magic = KS_MAGIC; - mutex_init(&ksp->ks_lock, NULL, MUTEX_DEFAULT, NULL); -@@ -456,71 +500,64 @@ EXPORT_SYMBOL(__kstat_create); - void - __kstat_install(kstat_t *ksp) - { -- struct proc_dir_entry *de_module, *de_name; -+ kstat_module_t *module; - kstat_t *tmp; -- int rc = 0; -- SENTRY; -- -- spin_lock(&kstat_lock); - -- /* Item may only be added to the list once */ -- list_for_each_entry(tmp, &kstat_list, ks_list) { -- if (tmp == ksp) { -- spin_unlock(&kstat_lock); -- SGOTO(out, rc = -EEXIST); -- } -- } -+ ASSERT(ksp); - -- list_add_tail(&ksp->ks_list, &kstat_list); -- spin_unlock(&kstat_lock); -+ mutex_enter(&kstat_module_lock); - -- de_module = proc_dir_entry_find(proc_spl_kstat, ksp->ks_module); -- if (de_module == NULL) { -- de_module = proc_mkdir(ksp->ks_module, proc_spl_kstat); -- if (de_module == NULL) -- SGOTO(out, rc = -EUNATCH); -+ module = kstat_find_module(ksp->ks_module); -+ if (module == NULL) { -+ module = kstat_create_module(ksp->ks_module); -+ if (module == NULL) -+ goto out; - } - -- de_name = create_proc_entry(ksp->ks_name, 0444, de_module); -- if (de_name == NULL) -- SGOTO(out, rc = -EUNATCH); -+ /* -+ * Only one entry by this name per-module, on failure the module -+ * shouldn't be deleted because we know it has at least one entry. -+ */ -+ list_for_each_entry(tmp, &module->ksm_kstat_list, ks_list) -+ if (strncmp(tmp->ks_name, ksp->ks_name, KSTAT_STRLEN) == 0) -+ goto out; -+ -+ list_add_tail(&ksp->ks_list, &module->ksm_kstat_list); - - mutex_enter(&ksp->ks_lock); -- ksp->ks_proc = de_name; -- de_name->proc_fops = &proc_kstat_operations; -- de_name->data = (void *)ksp; -+ ksp->ks_owner = module; -+ ksp->ks_proc = proc_create_data(ksp->ks_name, 0444, -+ module->ksm_proc, &proc_kstat_operations, (void *)ksp); -+ if (ksp->ks_proc == NULL) { -+ list_del_init(&ksp->ks_list); -+ if (list_empty(&module->ksm_kstat_list)) -+ kstat_delete_module(module); -+ } - mutex_exit(&ksp->ks_lock); - out: -- if (rc) { -- spin_lock(&kstat_lock); -- list_del_init(&ksp->ks_list); -- spin_unlock(&kstat_lock); -- } -- -- SEXIT; -+ mutex_exit(&kstat_module_lock); - } - EXPORT_SYMBOL(__kstat_install); - - void - __kstat_delete(kstat_t *ksp) - { -- struct proc_dir_entry *de_module; -+ kstat_module_t *module = ksp->ks_owner; - -- spin_lock(&kstat_lock); -- list_del_init(&ksp->ks_list); -- spin_unlock(&kstat_lock); -+ mutex_enter(&kstat_module_lock); -+ list_del_init(&ksp->ks_list); -+ mutex_exit(&kstat_module_lock); - -- if (ksp->ks_proc) { -- de_module = ksp->ks_proc->parent; -- remove_proc_entry(ksp->ks_name, de_module); -+ if (ksp->ks_proc) { -+ remove_proc_entry(ksp->ks_name, module->ksm_proc); - -- /* Remove top level module directory if it's empty */ -- if (proc_dir_entries(de_module) == 0) -- remove_proc_entry(de_module->name, de_module->parent); -+ /* Remove top level module directory if it's empty */ -+ if (list_empty(&module->ksm_kstat_list)) -+ kstat_delete_module(module); - } - - if (!(ksp->ks_flags & KSTAT_FLAG_VIRTUAL)) -- kmem_free(ksp->ks_data, ksp->ks_data_size); -+ kmem_free(ksp->ks_data, ksp->ks_data_size); - - mutex_destroy(&ksp->ks_lock); - kmem_free(ksp, sizeof(*ksp)); -@@ -533,8 +570,8 @@ int - spl_kstat_init(void) - { - SENTRY; -- spin_lock_init(&kstat_lock); -- INIT_LIST_HEAD(&kstat_list); -+ mutex_init(&kstat_module_lock, NULL, MUTEX_DEFAULT, NULL); -+ INIT_LIST_HEAD(&kstat_module_list); - kstat_id = 0; - SRETURN(0); - } -@@ -543,7 +580,8 @@ void - spl_kstat_fini(void) - { - SENTRY; -- ASSERT(list_empty(&kstat_list)); -+ ASSERT(list_empty(&kstat_module_list)); -+ mutex_destroy(&kstat_module_lock); - SEXIT; - } - -diff --git a/module/spl/spl-proc.c b/module/spl/spl-proc.c -index cd4fa1b..b8379d0 100644 ---- a/module/spl/spl-proc.c -+++ b/module/spl/spl-proc.c -@@ -1120,39 +1120,6 @@ static struct ctl_table spl_root[] = { - { 0 } - }; - --static int --proc_dir_entry_match(int len, const char *name, struct proc_dir_entry *de) --{ -- if (de->namelen != len) -- return 0; -- -- return !memcmp(name, de->name, len); --} -- --struct proc_dir_entry * --proc_dir_entry_find(struct proc_dir_entry *root, const char *str) --{ -- struct proc_dir_entry *de; -- -- for (de = root->subdir; de; de = de->next) -- if (proc_dir_entry_match(strlen(str), str, de)) -- return de; -- -- return NULL; --} -- --int --proc_dir_entries(struct proc_dir_entry *root) --{ -- struct proc_dir_entry *de; -- int i = 0; -- -- for (de = root->subdir; de; de = de->next) -- i++; -- -- return i; --} -- - int - spl_proc_init(void) - { -@@ -1174,11 +1141,11 @@ spl_proc_init(void) - if (proc_spl_kmem == NULL) - SGOTO(out, rc = -EUNATCH); - -- proc_spl_kmem_slab = create_proc_entry("slab", 0444, proc_spl_kmem); -+ proc_spl_kmem_slab = proc_create_data("slab", 0444, -+ proc_spl_kmem, &proc_slab_operations, NULL); - if (proc_spl_kmem_slab == NULL) - SGOTO(out, rc = -EUNATCH); - -- proc_spl_kmem_slab->proc_fops = &proc_slab_operations; - #endif /* DEBUG_KMEM */ - - proc_spl_kstat = proc_mkdir("kstat", proc_spl); -diff --git a/module/spl/spl-taskq.c b/module/spl/spl-taskq.c -index 4feca04..bcdc98f 100644 ---- a/module/spl/spl-taskq.c -+++ b/module/spl/spl-taskq.c -@@ -342,39 +342,27 @@ taskq_find(taskq_t *tq, taskqid_t id, int *active) - SRETURN(NULL); - } - --/* -- * The taskq_wait_id() function blocks until the passed task id completes. -- * This does not guarantee that all lower task id's have completed. -- */ --void --taskq_wait_id(taskq_t *tq, taskqid_t id) -+static int -+taskq_wait_id_check(taskq_t *tq, taskqid_t id) - { -- DEFINE_WAIT(wait); -- taskq_ent_t *t; - int active = 0; -- SENTRY; -- -- ASSERT(tq); -- ASSERT(id > 0); -+ int rc; - - spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); -- t = taskq_find(tq, id, &active); -- if (t) -- prepare_to_wait(&t->tqent_waitq, &wait, TASK_UNINTERRUPTIBLE); -+ rc = (taskq_find(tq, id, &active) == NULL); - spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); - -- /* -- * We rely on the kernels autoremove_wake_function() function to -- * remove us from the wait queue in the context of wake_up(). -- * Once woken the taskq_ent_t pointer must never be accessed. -- */ -- if (t) { -- t = NULL; -- schedule(); -- __set_current_state(TASK_RUNNING); -- } -+ return (rc); -+} - -- SEXIT; -+/* -+ * The taskq_wait_id() function blocks until the passed task id completes. -+ * This does not guarantee that all lower task ids have completed. -+ */ -+void -+taskq_wait_id(taskq_t *tq, taskqid_t id) -+{ -+ wait_event(tq->tq_wait_waitq, taskq_wait_id_check(tq, id)); - } - EXPORT_SYMBOL(taskq_wait_id); - -diff --git a/module/spl/spl-time.c b/module/spl/spl-time.c -index 8f43b54..20fd0e3 100644 ---- a/module/spl/spl-time.c -+++ b/module/spl/spl-time.c -@@ -40,11 +40,10 @@ extern unsigned long long monotonic_clock(void); - void - __gethrestime(timestruc_t *ts) - { -- struct timeval tv; -+ struct timespec tspec = current_kernel_time(); - -- do_gettimeofday(&tv); -- ts->tv_sec = tv.tv_sec; -- ts->tv_nsec = tv.tv_usec * NSEC_PER_USEC; -+ ts->tv_sec = tspec.tv_sec; -+ ts->tv_nsec = tspec.tv_nsec; - } - EXPORT_SYMBOL(__gethrestime); - -diff --git a/module/splat/splat-atomic.c b/module/splat/splat-atomic.c -index df3b38f..f702196 100644 ---- a/module/splat/splat-atomic.c -+++ b/module/splat/splat-atomic.c -@@ -26,6 +26,7 @@ - - #include - #include -+#include - #include "splat-internal.h" - - #define SPLAT_ATOMIC_NAME "atomic" -diff --git a/module/splat/splat-thread.c b/module/splat/splat-thread.c -index a1e70db..e55acd0 100644 ---- a/module/splat/splat-thread.c -+++ b/module/splat/splat-thread.c -@@ -26,6 +26,7 @@ - - #include - #include -+#include - #include "splat-internal.h" - - #define SPLAT_THREAD_NAME "thread" -diff --git a/module/splat/splat-time.c b/module/splat/splat-time.c -index ca60c45..cd513c9 100644 ---- a/module/splat/splat-time.c -+++ b/module/splat/splat-time.c -@@ -25,6 +25,7 @@ - \*****************************************************************************/ - - #include -+#include - #include "splat-internal.h" - - #define SPLAT_TIME_NAME "time" -diff --git a/rpm/fedora/spl-kmod.spec.in b/rpm/fedora/spl-kmod.spec.in -index f83ff60..79e1f9d 100644 ---- a/rpm/fedora/spl-kmod.spec.in -+++ b/rpm/fedora/spl-kmod.spec.in -@@ -44,7 +44,7 @@ BuildRequires: %{_bindir}/kmodtool - # Kmodtool does its magic here. A patched version of kmodtool is shipped - # with the source rpm until kmod development packages are supported upstream. - # https://bugzilla.rpmfusion.org/show_bug.cgi?id=2714 --%{expand:%(sh %{SOURCE10} --target %{_target_cpu} --repo %{repo} --kmodname %{name} --devel %{?prefix:--prefix "%{?prefix}"} %{?buildforkernels:--%{buildforkernels}} %{?kernels:--for-kernels "%{?kernels}"} 2>/dev/null) } -+%{expand:%(sh %{SOURCE10} --target %{_target_cpu} --repo %{repo} --kmodname %{name} --devel %{?prefix:--prefix "%{?prefix}"} %{?buildforkernels:--%{buildforkernels}} %{?kernels:--for-kernels "%{?kernels}"} %{?kernelbuildroot:--buildroot "%{?kernelbuildroot}"} 2>/dev/null) } - - - %description -@@ -56,7 +56,7 @@ several interfaces provided by the Solaris kernel. - %{?kmodtool_check} - - # Print kmodtool output for debugging purposes: --sh %{SOURCE10} --target %{_target_cpu} --repo %{repo} --kmodname %{name} --devel %{?buildforkernels:--%{buildforkernels}} %{?kernels:--for-kernels "%{?kernels}"} 2>/dev/null -+sh %{SOURCE10} --target %{_target_cpu} --repo %{repo} --kmodname %{name} --devel %{?buildforkernels:--%{buildforkernels}} %{?kernels:--for-kernels "%{?kernels}"} %{?kernelbuildroot:--buildroot "%{?kernelbuildroot}"} 2>/dev/null - - %if %{with debug} - %define debug --enable-debug -diff --git a/rpm/generic/spl-dkms.spec.in b/rpm/generic/spl-dkms.spec.in -index 148d612..dbf4723 100644 ---- a/rpm/generic/spl-dkms.spec.in -+++ b/rpm/generic/spl-dkms.spec.in -@@ -15,6 +15,8 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - BuildArch: noarch - - Requires: dkms >= 2.2.0.2 -+Requires: gcc, make, perl -+Requires: kernel-devel - Provides: %{module}-kmod = %{version} - - %description -diff --git a/rpm/generic/spl-kmod.spec.in b/rpm/generic/spl-kmod.spec.in -index 224660b..1b0a6f1 100644 ---- a/rpm/generic/spl-kmod.spec.in -+++ b/rpm/generic/spl-kmod.spec.in -@@ -18,7 +18,7 @@ License: GPLv2+ - URL: http://zfsonlinux.org/ - Source0: %{module}-%{version}.tar.gz - Source10: kmodtool --BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id} -u -n) - - # The developments headers will conflict with the dkms packages. - Conflicts: %{module}-dkms -@@ -44,7 +44,7 @@ Conflicts: %{module}-dkms - # Kmodtool does its magic here. A patched version of kmodtool is shipped - # because the latest versions may not be available for your distribution. - # https://bugzilla.rpmfusion.org/show_bug.cgi?id=2714 --%{expand:%(bash %{SOURCE10} --target %{_target_cpu} --kmodname %{name} --devel %{?prefix:--prefix "%{?prefix}"} %{?kernels:--for-kernels "%{?kernels}"} 2>/dev/null) } -+%{expand:%(bash %{SOURCE10} --target %{_target_cpu} --kmodname %{name} --devel %{?prefix:--prefix "%{?prefix}"} %{?kernels:--for-kernels "%{?kernels}"} %{?kernelbuildroot:--buildroot "%{?kernelbuildroot}"} 2>/dev/null) } - - - %description -@@ -56,7 +56,7 @@ several interfaces provided by the Solaris kernel. - %{?kmodtool_check} - - # Print kmodtool output for debugging purposes: --bash %{SOURCE10} --target %{_target_cpu} --kmodname %{name} --devel %{?prefix:--prefix "%{?prefix}"} %{?kernels:--for-kernels "%{?kernels}"} 2>/dev/null -+bash %{SOURCE10} --target %{_target_cpu} --kmodname %{name} --devel %{?prefix:--prefix "%{?prefix}"} %{?kernels:--for-kernels "%{?kernels}"} %{?kernelbuildroot:--buildroot "%{?kernelbuildroot}"} 2>/dev/null - - %if %{with debug} - %define debug --enable-debug -@@ -106,12 +106,12 @@ for kernel_version in %{?kernel_versions}; do - --with-linux="${kernel_version##*___}" \ - --with-linux-obj="${kernel_version##*___}" \ - %else -- --with-linux=\ -- %(if [ -e /lib/modules/${kernel_version%%___*}/source ]; then \ -- echo "/lib/modules/${kernel_version%%___*}/source" \ -+ --with-linux="$( \ -+ if [ -e "/lib/modules/${kernel_version%%___*}/source" ]; then \ -+ echo "/lib/modules/${kernel_version%%___*}/source"; \ - else \ -- echo "/lib/modules/${kernel_version%%___*}/build" \ -- fi) \ -+ echo "/lib/modules/${kernel_version%%___*}/build"; \ -+ fi)" \ - --with-linux-obj="/lib/modules/${kernel_version%%___*}/build" \ - %endif - %{debug} \ -diff --git a/scripts/kmodtool b/scripts/kmodtool -old mode 100755 -new mode 100644 -index 2fe014c..6b73780 ---- a/scripts/kmodtool -+++ b/scripts/kmodtool -@@ -37,6 +37,7 @@ kernel_versions_to_build_for= - prefix= - filterfile= - target= -+buildroot= - - error_out() - { -@@ -305,9 +306,9 @@ print_customrpmtemplate () - { - for kernel in ${1} - do -- if [[ -e "/usr/src/kernels/${kernel}" ]] ; then -+ if [[ -e "${buildroot}/usr/src/kernels/${kernel}" ]] ; then - # this looks like a Fedora/RH kernel -- print a normal template (which includes the proper BR) and be happy :) -- kernel_versions="${kernel_versions}${kernel}___%{_usrsrc}/kernels/${kernel} " -+ kernel_versions="${kernel_versions}${kernel}___${buildroot}%{_usrsrc}/kernels/${kernel} " - - # parse kernel versions string and print template - local kernel_verrelarch=${kernel%%${kernels_known_variants}} -@@ -382,7 +383,6 @@ myprog_help () - echo "Usage: $(basename ${0}) [OPTIONS]" - echo $'\n'"Creates a template to be used during kmod building" - echo $'\n'"Available options:" -- # FIXME echo " --datadir -- look for our shared files in " - echo " --filterfile -- filter the results with grep --file " - echo " --for-kernels -- created templates only for these kernels" - echo " --kmodname -- name of the kmod (required)" -@@ -390,6 +390,7 @@ myprog_help () - echo " --noakmod -- no akmod package" - echo " --repo -- use buildsys-build--kerneldevpkgs" - echo " --target -- target-arch (required)" -+ echo " --buildroot -- Build root (place to look for build files)" - } - - while [ "${1}" ] ; do -@@ -478,6 +479,11 @@ while [ "${1}" ] ; do - shift - build_kernels="current" - ;; -+ --buildroot) -+ shift -+ buildroot="${1}" -+ shift -+ ;; - --help) - myprog_help - exit 0 diff --git a/zfs-utils/zfs_git_head.patch b/zfs-utils/zfs_git_head.patch deleted file mode 100644 index 978b07e..0000000 --- a/zfs-utils/zfs_git_head.patch +++ /dev/null @@ -1,8612 +0,0 @@ -diff --git a/Makefile.am b/Makefile.am -index 18ad36d..9c299a9 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -1,3 +1,6 @@ -+ -+ACLOCAL_AMFLAGS = -I config -+ - include $(top_srcdir)/config/rpm.am - include $(top_srcdir)/config/deb.am - include $(top_srcdir)/config/tgz.am -diff --git a/autogen.sh b/autogen.sh -index 343265c..427394a 100755 ---- a/autogen.sh -+++ b/autogen.sh -@@ -1,7 +1,4 @@ - #!/bin/sh - --aclocal -I config --libtoolize --automake --copy --autoheader --automake --add-missing --include-deps --copy --autoconf -+autoreconf -fiv -+rm -Rf autom4te.cache -diff --git a/cmd/Makefile.am b/cmd/Makefile.am -index 1a51ddc..bad1af6 100644 ---- a/cmd/Makefile.am -+++ b/cmd/Makefile.am -@@ -1,2 +1,2 @@ - SUBDIRS = zfs zpool zdb zhack zinject zstreamdump ztest zpios --SUBDIRS += mount_zfs fsck_zfs zvol_id vdev_id -+SUBDIRS += mount_zfs fsck_zfs zvol_id vdev_id arcstat -diff --git a/cmd/arcstat/Makefile.am b/cmd/arcstat/Makefile.am -new file mode 100644 -index 0000000..802b8e1 ---- /dev/null -+++ b/cmd/arcstat/Makefile.am -@@ -0,0 +1,2 @@ -+bin_SCRIPTS = arcstat.py -+EXTRA_DIST = $(bin_SCRIPTS) -diff --git a/cmd/arcstat/arcstat.py b/cmd/arcstat/arcstat.py -new file mode 100755 -index 0000000..e01dd8b ---- /dev/null -+++ b/cmd/arcstat/arcstat.py -@@ -0,0 +1,440 @@ -+#!/usr/bin/python -+# -+# Print out ZFS ARC Statistics exported via kstat(1) -+# For a definition of fields, or usage, use arctstat.pl -v -+# -+# This script is a fork of the original arcstat.pl (0.1) by -+# Neelakanth Nadgir, originally published on his Sun blog on -+# 09/18/2007 -+# http://blogs.sun.com/realneel/entry/zfs_arc_statistics -+# -+# This version aims to improve upon the original by adding features -+# and fixing bugs as needed. This version is maintained by -+# Mike Harsch and is hosted in a public open source repository: -+# http://github.com/mharsch/arcstat -+# -+# Comments, Questions, or Suggestions are always welcome. -+# Contact the maintainer at ( mike at harschsystems dot com ) -+# -+# CDDL HEADER START -+# -+# The contents of this file are subject to the terms of the -+# Common Development and Distribution License, Version 1.0 only -+# (the "License"). You may not use this file except in compliance -+# with the License. -+# -+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -+# or http://www.opensolaris.org/os/licensing. -+# See the License for the specific language governing permissions -+# and limitations under the License. -+# -+# When distributing Covered Code, include this CDDL HEADER in each -+# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -+# If applicable, add the following below this CDDL HEADER, with the -+# fields enclosed by brackets "[]" replaced with your own identifying -+# information: Portions Copyright [yyyy] [name of copyright owner] -+# -+# CDDL HEADER END -+# -+# -+# Fields have a fixed width. Every interval, we fill the "v" -+# hash with its corresponding value (v[field]=value) using calculate(). -+# @hdr is the array of fields that needs to be printed, so we -+# just iterate over this array and print the values using our pretty printer. -+# -+ -+ -+import sys -+import time -+import getopt -+import re -+import copy -+ -+from decimal import Decimal -+from signal import signal, SIGINT -+ -+cols = { -+ # HDR: [Size, Scale, Description] -+ "time": [8, -1, "Time"], -+ "hits": [4, 1000, "ARC reads per second"], -+ "miss": [4, 1000, "ARC misses per second"], -+ "read": [4, 1000, "Total ARC accesses per second"], -+ "hit%": [4, 100, "ARC Hit percentage"], -+ "miss%": [5, 100, "ARC miss percentage"], -+ "dhit": [4, 1000, "Demand Data hits per second"], -+ "dmis": [4, 1000, "Demand Data misses per second"], -+ "dh%": [3, 100, "Demand Data hit percentage"], -+ "dm%": [3, 100, "Demand Data miss percentage"], -+ "phit": [4, 1000, "Prefetch hits per second"], -+ "pmis": [4, 1000, "Prefetch misses per second"], -+ "ph%": [3, 100, "Prefetch hits percentage"], -+ "pm%": [3, 100, "Prefetch miss percentage"], -+ "mhit": [4, 1000, "Metadata hits per second"], -+ "mmis": [4, 1000, "Metadata misses per second"], -+ "mread": [4, 1000, "Metadata accesses per second"], -+ "mh%": [3, 100, "Metadata hit percentage"], -+ "mm%": [3, 100, "Metadata miss percentage"], -+ "arcsz": [5, 1024, "ARC Size"], -+ "c": [4, 1024, "ARC Target Size"], -+ "mfu": [4, 1000, "MFU List hits per second"], -+ "mru": [4, 1000, "MRU List hits per second"], -+ "mfug": [4, 1000, "MFU Ghost List hits per second"], -+ "mrug": [4, 1000, "MRU Ghost List hits per second"], -+ "eskip": [5, 1000, "evict_skip per second"], -+ "mtxmis": [6, 1000, "mutex_miss per second"], -+ "rmis": [4, 1000, "recycle_miss per second"], -+ "dread": [5, 1000, "Demand data accesses per second"], -+ "pread": [5, 1000, "Prefetch accesses per second"], -+ "l2hits": [6, 1000, "L2ARC hits per second"], -+ "l2miss": [6, 1000, "L2ARC misses per second"], -+ "l2read": [6, 1000, "Total L2ARC accesses per second"], -+ "l2hit%": [6, 100, "L2ARC access hit percentage"], -+ "l2miss%": [7, 100, "L2ARC access miss percentage"], -+ "l2size": [6, 1024, "Size of the L2ARC"], -+ "l2bytes": [7, 1024, "bytes read per second from the L2ARC"], -+} -+ -+v = {} -+hdr = ["time", "read", "miss", "miss%", "dmis", "dm%", "pmis", "pm%", "mmis", -+ "mm%", "arcsz", "c"] -+xhdr = ["time", "mfu", "mru", "mfug", "mrug", "eskip", "mtxmis", "rmis", -+ "dread", "pread", "read"] -+sint = 1 # Default interval is 1 second -+count = 1 # Default count is 1 -+hdr_intr = 20 # Print header every 20 lines of output -+opfile = None -+sep = " " # Default separator is 2 spaces -+version = "0.4" -+l2exist = False -+cmd = ("Usage: arcstat [-hvx] [-f fields] [-o file] [-s string] [interval " -+ "[count]]\n") -+cur = {} -+d = {} -+out = None -+kstat = None -+float_pobj = re.compile("^[0-9]+(\.[0-9]+)?$") -+ -+ -+def detailed_usage(): -+ sys.stderr.write("%s\n" % cmd) -+ sys.stderr.write("Field definitions are as follows:\n") -+ for key in cols: -+ sys.stderr.write("%11s : %s\n" % (key, cols[key][2])) -+ sys.stderr.write("\n") -+ -+ sys.exit(1) -+ -+ -+def usage(): -+ sys.stderr.write("%s\n" % cmd) -+ sys.stderr.write("\t -h : Print this help message\n") -+ sys.stderr.write("\t -v : List all possible field headers and definitions" -+ "\n") -+ sys.stderr.write("\t -x : Print extended stats\n") -+ sys.stderr.write("\t -f : Specify specific fields to print (see -v)\n") -+ sys.stderr.write("\t -o : Redirect output to the specified file\n") -+ sys.stderr.write("\t -s : Override default field separator with custom " -+ "character or string\n") -+ sys.stderr.write("\nExamples:\n") -+ sys.stderr.write("\tarcstat -o /tmp/a.log 2 10\n") -+ sys.stderr.write("\tarcstat -s \",\" -o /tmp/a.log 2 10\n") -+ sys.stderr.write("\tarcstat -v\n") -+ sys.stderr.write("\tarcstat -f time,hit%,dh%,ph%,mh% 1\n") -+ sys.stderr.write("\n") -+ -+ sys.exit(1) -+ -+ -+def kstat_update(): -+ global kstat -+ -+ k = [line.strip() for line in open('/proc/spl/kstat/zfs/arcstats')] -+ -+ if not k: -+ sys.exit(1) -+ -+ del k[0:2] -+ kstat = {} -+ -+ for s in k: -+ if not s: -+ continue -+ -+ name, unused, value = s.split() -+ kstat[name] = Decimal(value) -+ -+ -+def snap_stats(): -+ global cur -+ global kstat -+ -+ prev = copy.deepcopy(cur) -+ kstat_update() -+ -+ cur = kstat -+ for key in cur: -+ if re.match(key, "class"): -+ continue -+ if key in prev: -+ d[key] = cur[key] - prev[key] -+ else: -+ d[key] = cur[key] -+ -+ -+def prettynum(sz, scale, num=0): -+ suffix = [' ', 'K', 'M', 'G', 'T', 'P', 'E', 'Z'] -+ index = 0 -+ save = 0 -+ -+ # Special case for date field -+ if scale == -1: -+ return "%s" % num -+ -+ # Rounding error, return 0 -+ elif num > 0 and num < 1: -+ num = 0 -+ -+ while num > scale and index < 5: -+ save = num -+ num = num / scale -+ index += 1 -+ -+ if index == 0: -+ return "%*d" % (sz, num) -+ -+ if (save / scale) < 10: -+ return "%*.1f%s" % (sz - 1, num, suffix[index]) -+ else: -+ return "%*d%s" % (sz - 1, num, suffix[index]) -+ -+ -+def print_values(): -+ global hdr -+ global sep -+ global v -+ -+ for col in hdr: -+ sys.stdout.write("%s%s" % ( -+ prettynum(cols[col][0], cols[col][1], v[col]), -+ sep -+ )) -+ sys.stdout.write("\n") -+ -+ -+def print_header(): -+ global hdr -+ global sep -+ -+ for col in hdr: -+ sys.stdout.write("%*s%s" % (cols[col][0], col, sep)) -+ sys.stdout.write("\n") -+ -+ -+def init(): -+ global sint -+ global count -+ global hdr -+ global xhdr -+ global opfile -+ global sep -+ global out -+ global l2exist -+ -+ desired_cols = None -+ xflag = False -+ hflag = False -+ vflag = False -+ i = 1 -+ -+ try: -+ opts, args = getopt.getopt( -+ sys.argv[1:], -+ "xo:hvs:f:", -+ [ -+ "extended", -+ "outfile", -+ "help", -+ "verbose", -+ "seperator", -+ "columns" -+ ] -+ ) -+ -+ except getopt.error, msg: -+ sys.stderr.write(msg) -+ usage() -+ -+ for opt, arg in opts: -+ if opt in ('-x', '--extended'): -+ xflag = True -+ if opt in ('-o', '--outfile'): -+ opfile = arg -+ i += 1 -+ if opt in ('-h', '--help'): -+ hflag = True -+ if opt in ('-v', '--verbose'): -+ vflag = True -+ if opt in ('-s', '--seperator'): -+ sep = arg -+ i += 1 -+ if opt in ('-f', '--columns'): -+ desired_cols = arg -+ i += 1 -+ i += 1 -+ -+ argv = sys.argv[i:] -+ sint = Decimal(argv[0]) if argv else sint -+ count = int(argv[1]) if len(argv) > 1 else count -+ -+ if len(argv) > 1: -+ sint = Decimal(argv[0]) -+ count = int(argv[1]) -+ -+ elif len(argv) > 0: -+ sint = Decimal(argv[0]) -+ count = 0 -+ -+ if hflag or (xflag and desired_cols): -+ usage() -+ -+ if vflag: -+ detailed_usage() -+ -+ if xflag: -+ hdr = xhdr -+ -+ # check if L2ARC exists -+ snap_stats() -+ l2_size = cur.get("l2_size") -+ if l2_size: -+ l2exist = True -+ -+ if desired_cols: -+ hdr = desired_cols.split(",") -+ -+ invalid = [] -+ incompat = [] -+ for ele in hdr: -+ if ele not in cols: -+ invalid.append(ele) -+ elif not l2exist and ele.startswith("l2"): -+ sys.stdout.write("No L2ARC Here\n%s\n" % ele) -+ incompat.append(ele) -+ -+ if len(invalid) > 0: -+ sys.stderr.write("Invalid column definition! -- %s\n" % invalid) -+ usage() -+ -+ if len(incompat) > 0: -+ sys.stderr.write("Incompatible field specified! -- %s\n" % ( -+ incompat, -+ )) -+ usage() -+ -+ if opfile: -+ try: -+ out = open(opfile, "w") -+ sys.stdout = out -+ -+ except: -+ sys.stderr.write("Cannot open %s for writing\n" % opfile) -+ sys.exit(1) -+ -+ -+def calculate(): -+ global d -+ global v -+ global l2exist -+ -+ v = {} -+ v["time"] = time.strftime("%H:%M:%S", time.localtime()) -+ v["hits"] = d["hits"] / sint -+ v["miss"] = d["misses"] / sint -+ v["read"] = v["hits"] + v["miss"] -+ v["hit%"] = 100 * v["hits"] / v["read"] if v["read"] > 0 else 0 -+ v["miss%"] = 100 - v["hit%"] if v["read"] > 0 else 0 -+ -+ v["dhit"] = (d["demand_data_hits"] + d["demand_metadata_hits"]) / sint -+ v["dmis"] = (d["demand_data_misses"] + d["demand_metadata_misses"]) / sint -+ -+ v["dread"] = v["dhit"] + v["dmis"] -+ v["dh%"] = 100 * v["dhit"] / v["dread"] if v["dread"] > 0 else 0 -+ v["dm%"] = 100 - v["dh%"] if v["dread"] > 0 else 0 -+ -+ v["phit"] = (d["prefetch_data_hits"] + d["prefetch_metadata_hits"]) / sint -+ v["pmis"] = (d["prefetch_data_misses"] + -+ d["prefetch_metadata_misses"]) / sint -+ -+ v["pread"] = v["phit"] + v["pmis"] -+ v["ph%"] = 100 * v["phit"] / v["pread"] if v["pread"] > 0 else 0 -+ v["pm%"] = 100 - v["ph%"] if v["pread"] > 0 else 0 -+ -+ v["mhit"] = (d["prefetch_metadata_hits"] + -+ d["demand_metadata_hits"]) / sint -+ v["mmis"] = (d["prefetch_metadata_misses"] + -+ d["demand_metadata_misses"]) / sint -+ -+ v["mread"] = v["mhit"] + v["mmis"] -+ v["mh%"] = 100 * v["mhit"] / v["mread"] if v["mread"] > 0 else 0 -+ v["mm%"] = 100 - v["mh%"] if v["mread"] > 0 else 0 -+ -+ v["arcsz"] = cur["size"] -+ v["c"] = cur["c"] -+ v["mfu"] = d["mfu_hits"] / sint -+ v["mru"] = d["mru_hits"] / sint -+ v["mrug"] = d["mru_ghost_hits"] / sint -+ v["mfug"] = d["mfu_ghost_hits"] / sint -+ v["eskip"] = d["evict_skip"] / sint -+ v["rmis"] = d["recycle_miss"] / sint -+ v["mtxmis"] = d["mutex_miss"] / sint -+ -+ if l2exist: -+ v["l2hits"] = d["l2_hits"] / sint -+ v["l2miss"] = d["l2_misses"] / sint -+ v["l2read"] = v["l2hits"] + v["l2miss"] -+ v["l2hit%"] = 100 * v["l2hits"] / v["l2read"] if v["l2read"] > 0 else 0 -+ -+ v["l2miss%"] = 100 - v["l2hit%"] if v["l2read"] > 0 else 0 -+ v["l2size"] = cur["l2_size"] -+ v["l2bytes"] = d["l2_read_bytes"] / sint -+ -+ -+def sighandler(*args): -+ sys.exit(0) -+ -+ -+def main(): -+ global sint -+ global count -+ global hdr_intr -+ -+ i = 0 -+ count_flag = 0 -+ -+ init() -+ if count > 0: -+ count_flag = 1 -+ -+ signal(SIGINT, sighandler) -+ while True: -+ if i == 0: -+ print_header() -+ -+ snap_stats() -+ calculate() -+ print_values() -+ -+ if count_flag == 1: -+ if count <= 1: -+ break -+ count -= 1 -+ -+ i = 0 if i == hdr_intr else i + 1 -+ time.sleep(sint) -+ -+ if out: -+ out.close() -+ -+ -+if __name__ == '__main__': -+ main() -diff --git a/cmd/mount_zfs/mount_zfs.c b/cmd/mount_zfs/mount_zfs.c -index cd27314..4db33ed 100644 ---- a/cmd/mount_zfs/mount_zfs.c -+++ b/cmd/mount_zfs/mount_zfs.c -@@ -131,15 +131,6 @@ parse_option(char *mntopt, unsigned long *mntflags, - if (strncmp(name, opt->name, strlen(name)) == 0) { - *mntflags |= opt->mntmask; - *zfsflags |= opt->zfsmask; -- -- /* MS_USERS implies default user options */ -- if (opt->mntmask & (MS_USERS)) -- *mntflags |= (MS_NOEXEC|MS_NOSUID|MS_NODEV); -- -- /* MS_OWNER|MS_GROUP imply default owner options */ -- if (opt->mntmask & (MS_OWNER | MS_GROUP)) -- *mntflags |= (MS_NOSUID|MS_NODEV); -- - error = 0; - goto out; - } -@@ -220,17 +211,57 @@ out: - } - - /* -- * If a file or directory in your current working directory is named -- * 'dataset' then mount(8) will prepend your current working directory -- * to dataset. The is no way to prevent this behavior so we simply -- * check for it and strip the prepended patch when it is added. -+ * Return the pool/dataset to mount given the name passed to mount. This -+ * is expected to be of the form pool/dataset, however may also refer to -+ * a block device if that device contains a valid zfs label. - */ - static char * - parse_dataset(char *dataset) - { - char cwd[PATH_MAX]; -+ struct stat64 statbuf; -+ int error; - int len; - -+ /* -+ * We expect a pool/dataset to be provided, however if we're -+ * given a device which is a member of a zpool we attempt to -+ * extract the pool name stored in the label. Given the pool -+ * name we can mount the root dataset. -+ */ -+ error = stat64(dataset, &statbuf); -+ if (error == 0) { -+ nvlist_t *config; -+ char *name; -+ int fd; -+ -+ fd = open(dataset, O_RDONLY); -+ if (fd < 0) -+ goto out; -+ -+ error = zpool_read_label(fd, &config); -+ (void) close(fd); -+ if (error) -+ goto out; -+ -+ error = nvlist_lookup_string(config, -+ ZPOOL_CONFIG_POOL_NAME, &name); -+ if (error) { -+ nvlist_free(config); -+ } else { -+ dataset = strdup(name); -+ nvlist_free(config); -+ return (dataset); -+ } -+ } -+out: -+ /* -+ * If a file or directory in your current working directory is -+ * named 'dataset' then mount(8) will prepend your current working -+ * directory to the dataset. There is no way to prevent this -+ * behavior so we simply check for it and strip the prepended -+ * patch when it is added. -+ */ - if (getcwd(cwd, PATH_MAX) == NULL) - return (dataset); - -diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c -index 70b4ba2..82491ad 100644 ---- a/cmd/zdb/zdb.c -+++ b/cmd/zdb/zdb.c -@@ -86,6 +86,7 @@ extern void dump_intent_log(zilog_t *); - uint64_t *zopt_object = NULL; - int zopt_objects = 0; - libzfs_handle_t *g_zfs; -+uint64_t max_inflight = 200; - - /* - * These libumem hooks provide a reasonable set of defaults for the allocator's -@@ -108,13 +109,14 @@ usage(void) - { - (void) fprintf(stderr, - "Usage: %s [-CumdibcsDvhLXFPA] [-t txg] [-e [-p path...]] " -- "poolname [object...]\n" -- " %s [-divPA] [-e -p path...] dataset [object...]\n" -- " %s -m [-LXFPA] [-t txg] [-e [-p path...]] " -+ "[-U config] [-M inflight I/Os] poolname [object...]\n" -+ " %s [-divPA] [-e -p path...] [-U config] dataset " -+ "[object...]\n" -+ " %s -m [-LXFPA] [-t txg] [-e [-p path...]] [-U config] " - "poolname [vdev [metaslab...]]\n" - " %s -R [-A] [-e [-p path...]] poolname " - "vdev:offset:size[:flags]\n" -- " %s -S [-PA] [-e [-p path...]] poolname\n" -+ " %s -S [-PA] [-e [-p path...]] [-U config] poolname\n" - " %s -l [-uA] device\n" - " %s -C [-A] [-U config]\n\n", - cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname); -@@ -161,6 +163,8 @@ usage(void) - (void) fprintf(stderr, " -P print numbers in parseable form\n"); - (void) fprintf(stderr, " -t -- highest txg to use when " - "searching for uberblocks\n"); -+ (void) fprintf(stderr, " -M -- " -+ "specify the maximum number of checksumming I/Os [default is 200]\n"); - (void) fprintf(stderr, "Specify an option more than once (e.g. -bb) " - "to make only that option verbose\n"); - (void) fprintf(stderr, "Default is to dump everything non-verbosely\n"); -@@ -544,7 +548,7 @@ static void - dump_metaslab_stats(metaslab_t *msp) - { - char maxbuf[32]; -- space_map_t *sm = &msp->ms_map; -+ space_map_t *sm = msp->ms_map; - avl_tree_t *t = sm->sm_pp_root; - int free_pct = sm->sm_space * 100 / sm->sm_size; - -@@ -560,7 +564,7 @@ dump_metaslab(metaslab_t *msp) - { - vdev_t *vd = msp->ms_group->mg_vd; - spa_t *spa = vd->vdev_spa; -- space_map_t *sm = &msp->ms_map; -+ space_map_t *sm = msp->ms_map; - space_map_obj_t *smo = &msp->ms_smo; - char freebuf[32]; - -@@ -992,7 +996,7 @@ visit_indirect(spa_t *spa, const dnode_phys_t *dnp, - arc_buf_t *buf; - uint64_t fill = 0; - -- err = arc_read_nolock(NULL, spa, bp, arc_getbuf_func, &buf, -+ err = arc_read(NULL, spa, bp, arc_getbuf_func, &buf, - ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb); - if (err) - return (err); -@@ -1323,6 +1327,61 @@ dump_uidgid(objset_t *os, uint64_t uid, uint64_t gid) - print_idstr(gid, "gid"); - } - -+static void -+dump_znode_sa_xattr(sa_handle_t *hdl) -+{ -+ nvlist_t *sa_xattr; -+ nvpair_t *elem = NULL; -+ int sa_xattr_size = 0; -+ int sa_xattr_entries = 0; -+ int error; -+ char *sa_xattr_packed; -+ -+ error = sa_size(hdl, sa_attr_table[ZPL_DXATTR], &sa_xattr_size); -+ if (error || sa_xattr_size == 0) -+ return; -+ -+ sa_xattr_packed = malloc(sa_xattr_size); -+ if (sa_xattr_packed == NULL) -+ return; -+ -+ error = sa_lookup(hdl, sa_attr_table[ZPL_DXATTR], -+ sa_xattr_packed, sa_xattr_size); -+ if (error) { -+ free(sa_xattr_packed); -+ return; -+ } -+ -+ error = nvlist_unpack(sa_xattr_packed, sa_xattr_size, &sa_xattr, 0); -+ if (error) { -+ free(sa_xattr_packed); -+ return; -+ } -+ -+ while ((elem = nvlist_next_nvpair(sa_xattr, elem)) != NULL) -+ sa_xattr_entries++; -+ -+ (void) printf("\tSA xattrs: %d bytes, %d entries\n\n", -+ sa_xattr_size, sa_xattr_entries); -+ while ((elem = nvlist_next_nvpair(sa_xattr, elem)) != NULL) { -+ uchar_t *value; -+ uint_t cnt, idx; -+ -+ (void) printf("\t\t%s = ", nvpair_name(elem)); -+ nvpair_value_byte_array(elem, &value, &cnt); -+ for (idx = 0 ; idx < cnt ; ++idx) { -+ if (isprint(value[idx])) -+ (void) putchar(value[idx]); -+ else -+ (void) printf("\\%3.3o", value[idx]); -+ } -+ (void) putchar('\n'); -+ } -+ -+ nvlist_free(sa_xattr); -+ free(sa_xattr_packed); -+} -+ - /*ARGSUSED*/ - static void - dump_znode(objset_t *os, uint64_t object, void *data, size_t size) -@@ -1423,6 +1482,7 @@ dump_znode(objset_t *os, uint64_t object, void *data, size_t size) - if (sa_lookup(hdl, sa_attr_table[ZPL_RDEV], &rdev, - sizeof (uint64_t)) == 0) - (void) printf("\trdev 0x%016llx\n", (u_longlong_t)rdev); -+ dump_znode_sa_xattr(hdl); - sa_handle_destroy(hdl); - } - -@@ -2005,9 +2065,47 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp, - bp, NULL, NULL, ZIO_FLAG_CANFAIL)), ==, 0); - } - --/* ARGSUSED */ -+static void -+zdb_blkptr_done(zio_t *zio) -+{ -+ spa_t *spa = zio->io_spa; -+ blkptr_t *bp = zio->io_bp; -+ int ioerr = zio->io_error; -+ zdb_cb_t *zcb = zio->io_private; -+ zbookmark_t *zb = &zio->io_bookmark; -+ -+ zio_data_buf_free(zio->io_data, zio->io_size); -+ -+ mutex_enter(&spa->spa_scrub_lock); -+ spa->spa_scrub_inflight--; -+ cv_broadcast(&spa->spa_scrub_io_cv); -+ -+ if (ioerr && !(zio->io_flags & ZIO_FLAG_SPECULATIVE)) { -+ char blkbuf[BP_SPRINTF_LEN]; -+ -+ zcb->zcb_haderrors = 1; -+ zcb->zcb_errors[ioerr]++; -+ -+ if (dump_opt['b'] >= 2) -+ sprintf_blkptr(blkbuf, bp); -+ else -+ blkbuf[0] = '\0'; -+ -+ (void) printf("zdb_blkptr_cb: " -+ "Got error %d reading " -+ "<%llu, %llu, %lld, %llx> %s -- skipping\n", -+ ioerr, -+ (u_longlong_t)zb->zb_objset, -+ (u_longlong_t)zb->zb_object, -+ (u_longlong_t)zb->zb_level, -+ (u_longlong_t)zb->zb_blkid, -+ blkbuf); -+ } -+ mutex_exit(&spa->spa_scrub_lock); -+} -+ - static int --zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, arc_buf_t *pbuf, -+zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, - const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg) - { - zdb_cb_t *zcb = arg; -@@ -2026,39 +2124,23 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, arc_buf_t *pbuf, - is_metadata = (BP_GET_LEVEL(bp) != 0 || DMU_OT_IS_METADATA(type)); - - if (dump_opt['c'] > 1 || (dump_opt['c'] && is_metadata)) { -- int ioerr; - size_t size = BP_GET_PSIZE(bp); -- void *data = malloc(size); -+ void *data = zio_data_buf_alloc(size); - int flags = ZIO_FLAG_CANFAIL | ZIO_FLAG_SCRUB | ZIO_FLAG_RAW; - - /* If it's an intent log block, failure is expected. */ - if (zb->zb_level == ZB_ZIL_LEVEL) - flags |= ZIO_FLAG_SPECULATIVE; - -- ioerr = zio_wait(zio_read(NULL, spa, bp, data, size, -- NULL, NULL, ZIO_PRIORITY_ASYNC_READ, flags, zb)); -- -- free(data); -+ mutex_enter(&spa->spa_scrub_lock); -+ while (spa->spa_scrub_inflight > max_inflight) -+ cv_wait(&spa->spa_scrub_io_cv, &spa->spa_scrub_lock); -+ spa->spa_scrub_inflight++; -+ mutex_exit(&spa->spa_scrub_lock); - -- if (ioerr && !(flags & ZIO_FLAG_SPECULATIVE)) { -- zcb->zcb_haderrors = 1; -- zcb->zcb_errors[ioerr]++; -+ zio_nowait(zio_read(NULL, spa, bp, data, size, -+ zdb_blkptr_done, zcb, ZIO_PRIORITY_ASYNC_READ, flags, zb)); - -- if (dump_opt['b'] >= 2) -- sprintf_blkptr(blkbuf, bp); -- else -- blkbuf[0] = '\0'; -- -- (void) printf("zdb_blkptr_cb: " -- "Got error %d reading " -- "<%llu, %llu, %lld, %llx> %s -- skipping\n", -- ioerr, -- (u_longlong_t)zb->zb_objset, -- (u_longlong_t)zb->zb_object, -- (u_longlong_t)zb->zb_level, -- (u_longlong_t)zb->zb_blkid, -- blkbuf); -- } - } - - zcb->zcb_readfails = 0; -@@ -2167,11 +2249,11 @@ zdb_leak_init(spa_t *spa, zdb_cb_t *zcb) - for (m = 0; m < vd->vdev_ms_count; m++) { - metaslab_t *msp = vd->vdev_ms[m]; - mutex_enter(&msp->ms_lock); -- space_map_unload(&msp->ms_map); -- VERIFY(space_map_load(&msp->ms_map, -+ space_map_unload(msp->ms_map); -+ VERIFY(space_map_load(msp->ms_map, - &zdb_space_map_ops, SM_ALLOC, &msp->ms_smo, - spa->spa_meta_objset) == 0); -- msp->ms_map.sm_ppd = vd; -+ msp->ms_map->sm_ppd = vd; - mutex_exit(&msp->ms_lock); - } - } -@@ -2196,7 +2278,7 @@ zdb_leak_fini(spa_t *spa) - for (m = 0; m < vd->vdev_ms_count; m++) { - metaslab_t *msp = vd->vdev_ms[m]; - mutex_enter(&msp->ms_lock); -- space_map_unload(&msp->ms_map); -+ space_map_unload(msp->ms_map); - mutex_exit(&msp->ms_lock); - } - } -@@ -2266,6 +2348,18 @@ dump_block_stats(spa_t *spa) - - zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb); - -+ /* -+ * If we've traversed the data blocks then we need to wait for those -+ * I/Os to complete. We leverage "The Godfather" zio to wait on -+ * all async I/Os to complete. -+ */ -+ if (dump_opt['c']) { -+ (void) zio_wait(spa->spa_async_zio_root); -+ spa->spa_async_zio_root = zio_root(spa, NULL, NULL, -+ ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE | -+ ZIO_FLAG_GODFATHER); -+ } -+ - if (zcb.zcb_haderrors) { - (void) printf("\nError counts:\n\n"); - (void) printf("\t%5s %s\n", "errno", "count"); -@@ -2418,7 +2512,7 @@ typedef struct zdb_ddt_entry { - /* ARGSUSED */ - static int - zdb_ddt_add_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, -- arc_buf_t *pbuf, const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg) -+ const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg) - { - avl_tree_t *t = arg; - avl_index_t where; -@@ -2806,7 +2900,7 @@ zdb_read_block(char *thing, spa_t *spa) - psize = size; - lsize = size; - -- pbuf = umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL); -+ pbuf = umem_alloc_aligned(SPA_MAXBLOCKSIZE, 512, UMEM_NOFAIL); - lbuf = umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL); - - BP_ZERO(bp); -@@ -3020,13 +3114,23 @@ main(int argc, char **argv) - nvlist_t *policy = NULL; - uint64_t max_txg = UINT64_MAX; - int rewind = ZPOOL_NEVER_REWIND; -+ char *spa_config_path_env; - - (void) setrlimit(RLIMIT_NOFILE, &rl); - (void) enable_extended_FILE_stdio(-1, -1); - - dprintf_setup(&argc, argv); - -- while ((c = getopt(argc, argv, "bcdhilmsuCDRSAFLXevp:t:U:P")) != -1) { -+ /* -+ * If there is an environment variable SPA_CONFIG_PATH it overrides -+ * default spa_config_path setting. If -U flag is specified it will -+ * override this environment variable settings once again. -+ */ -+ spa_config_path_env = getenv("SPA_CONFIG_PATH"); -+ if (spa_config_path_env != NULL) -+ spa_config_path = spa_config_path_env; -+ -+ while ((c = getopt(argc, argv, "bcdhilmM:suCDRSAFLXevp:t:U:P")) != -1) { - switch (c) { - case 'b': - case 'c': -@@ -3055,6 +3159,15 @@ main(int argc, char **argv) - case 'v': - verbose++; - break; -+ case 'M': -+ max_inflight = strtoull(optarg, NULL, 0); -+ if (max_inflight == 0) { -+ (void) fprintf(stderr, "maximum number " -+ "of inflight I/Os must be greater " -+ "than 0\n"); -+ usage(); -+ } -+ break; - case 'p': - if (searchdirs == NULL) { - searchdirs = umem_alloc(sizeof (char *), -diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c -index 818ab91..9671c0c 100644 ---- a/cmd/zfs/zfs_main.c -+++ b/cmd/zfs/zfs_main.c -@@ -5383,7 +5383,7 @@ get_one_dataset(zfs_handle_t *zhp, void *data) - } - - /* -- * Interate over any nested datasets. -+ * Iterate over any nested datasets. - */ - if (zfs_iter_filesystems(zhp, get_one_dataset, data) != 0) { - zfs_close(zhp); -diff --git a/cmd/zinject/translate.c b/cmd/zinject/translate.c -index 1607866..fc16127 100644 ---- a/cmd/zinject/translate.c -+++ b/cmd/zinject/translate.c -@@ -20,6 +20,7 @@ - */ - /* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2012 by Delphix. All rights reserved. - */ - - #include -@@ -476,6 +477,20 @@ translate_device(const char *pool, const char *device, err_type_t label_type, - &record->zi_guid) == 0); - } - -+ /* -+ * Device faults can take on three different forms: -+ * 1). delayed or hanging I/O -+ * 2). zfs label faults -+ * 3). generic disk faults -+ */ -+ if (record->zi_timer != 0) { -+ record->zi_cmd = ZINJECT_DELAY_IO; -+ } else if (label_type != TYPE_INVAL) { -+ record->zi_cmd = ZINJECT_LABEL_FAULT; -+ } else { -+ record->zi_cmd = ZINJECT_DEVICE_FAULT; -+ } -+ - switch (label_type) { - default: - break; -diff --git a/cmd/zinject/zinject.c b/cmd/zinject/zinject.c -index d584ead..13d067d 100644 ---- a/cmd/zinject/zinject.c -+++ b/cmd/zinject/zinject.c -@@ -20,6 +20,7 @@ - */ - /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2012 by Delphix. All rights reserved. - */ - - /* -@@ -235,8 +236,8 @@ usage(void) - "\t\t'pad1', or 'pad2'.\n" - "\t\t'errno' can be 'nxio' (the default), 'io', or 'dtl'.\n" - "\n" -- "\tzinject -d device -A pool\n" -- "\t\tPerform a specific action on a particular device\n" -+ "\tzinject -d device -A -D pool\n" -+ "\t\tPerform a specific action on a particular device.\n" - "\n" - "\tzinject -I [-s | -g ] pool\n" - "\t\tCause the pool to stop writing blocks yet not\n" -@@ -573,6 +574,16 @@ main(int argc, char **argv) - int ret; - int flags = 0; - -+ if ((g_zfs = libzfs_init()) == NULL) -+ return (1); -+ -+ libzfs_print_on_error(g_zfs, B_TRUE); -+ -+ if ((zfs_fd = open(ZFS_DEV, O_RDWR)) < 0) { -+ (void) fprintf(stderr, "failed to open ZFS device\n"); -+ return (1); -+ } -+ - if (argc == 1) { - /* - * No arguments. Print the available handlers. If there are no -@@ -589,7 +600,7 @@ main(int argc, char **argv) - } - - while ((c = getopt(argc, argv, -- ":aA:b:d:f:Fg:qhIc:t:T:l:mr:s:e:uL:p:")) != -1) { -+ ":aA:b:d:D:f:Fg:qhIc:t:T:l:mr:s:e:uL:p:")) != -1) { - switch (c) { - case 'a': - flags |= ZINJECT_FLUSH_ARC; -@@ -615,6 +626,16 @@ main(int argc, char **argv) - case 'd': - device = optarg; - break; -+ case 'D': -+ errno = 0; -+ record.zi_timer = strtoull(optarg, &end, 10); -+ if (errno != 0 || *end != '\0') { -+ (void) fprintf(stderr, "invalid i/o delay " -+ "value: '%s'\n", optarg); -+ usage(); -+ return (1); -+ } -+ break; - case 'e': - if (strcasecmp(optarg, "io") == 0) { - error = EIO; -@@ -679,6 +700,7 @@ main(int argc, char **argv) - case 'p': - (void) strlcpy(record.zi_func, optarg, - sizeof (record.zi_func)); -+ record.zi_cmd = ZINJECT_PANIC; - break; - case 'q': - quiet = 1; -@@ -752,23 +774,15 @@ main(int argc, char **argv) - argc -= optind; - argv += optind; - -- if ((g_zfs = libzfs_init()) == NULL) -- return (1); -- -- libzfs_print_on_error(g_zfs, B_TRUE); -- -- if ((zfs_fd = open(ZFS_DEV, O_RDWR)) < 0) { -- (void) fprintf(stderr, "failed to open ZFS device\n"); -- return (1); -- } -+ if (record.zi_duration != 0) -+ record.zi_cmd = ZINJECT_IGNORED_WRITES; - - if (cancel != NULL) { - /* - * '-c' is invalid with any other options. - */ - if (raw != NULL || range != NULL || type != TYPE_INVAL || -- level != 0 || record.zi_func[0] != '\0' || -- record.zi_duration != 0) { -+ level != 0 || record.zi_cmd != ZINJECT_UNINITIALIZED) { - (void) fprintf(stderr, "cancel (-c) incompatible with " - "any other options\n"); - usage(); -@@ -800,8 +814,7 @@ main(int argc, char **argv) - * for doing injection, so handle it separately here. - */ - if (raw != NULL || range != NULL || type != TYPE_INVAL || -- level != 0 || record.zi_func[0] != '\0' || -- record.zi_duration != 0) { -+ level != 0 || record.zi_cmd != ZINJECT_UNINITIALIZED) { - (void) fprintf(stderr, "device (-d) incompatible with " - "data error injection\n"); - usage(); -@@ -835,7 +848,7 @@ main(int argc, char **argv) - - } else if (raw != NULL) { - if (range != NULL || type != TYPE_INVAL || level != 0 || -- record.zi_func[0] != '\0' || record.zi_duration != 0) { -+ record.zi_cmd != ZINJECT_UNINITIALIZED) { - (void) fprintf(stderr, "raw (-b) format with " - "any other options\n"); - usage(); -@@ -858,13 +871,14 @@ main(int argc, char **argv) - return (1); - } - -+ record.zi_cmd = ZINJECT_DATA_FAULT; - if (translate_raw(raw, &record) != 0) - return (1); - if (!error) - error = EIO; -- } else if (record.zi_func[0] != '\0') { -+ } else if (record.zi_cmd == ZINJECT_PANIC) { - if (raw != NULL || range != NULL || type != TYPE_INVAL || -- level != 0 || device != NULL || record.zi_duration != 0) { -+ level != 0 || device != NULL) { - (void) fprintf(stderr, "panic (-p) incompatible with " - "other options\n"); - usage(); -@@ -882,7 +896,7 @@ main(int argc, char **argv) - if (argv[1] != NULL) - record.zi_type = atoi(argv[1]); - dataset[0] = '\0'; -- } else if (record.zi_duration != 0) { -+ } else if (record.zi_cmd == ZINJECT_IGNORED_WRITES) { - if (nowrites == 0) { - (void) fprintf(stderr, "-s or -g meaningless " - "without -I (ignore writes)\n"); -@@ -936,6 +950,7 @@ main(int argc, char **argv) - return (1); - } - -+ record.zi_cmd = ZINJECT_DATA_FAULT; - if (translate_record(type, argv[0], range, level, &record, pool, - dataset) != 0) - return (1); -diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c -index 3200698..b96fbe4 100644 ---- a/cmd/zpool/zpool_main.c -+++ b/cmd/zpool/zpool_main.c -@@ -63,6 +63,7 @@ static int zpool_do_destroy(int, char **); - - static int zpool_do_add(int, char **); - static int zpool_do_remove(int, char **); -+static int zpool_do_labelclear(int, char **); - - static int zpool_do_list(int, char **); - static int zpool_do_iostat(int, char **); -@@ -123,6 +124,7 @@ typedef enum { - HELP_HISTORY, - HELP_IMPORT, - HELP_IOSTAT, -+ HELP_LABELCLEAR, - HELP_LIST, - HELP_OFFLINE, - HELP_ONLINE, -@@ -162,6 +164,8 @@ static zpool_command_t command_table[] = { - { "add", zpool_do_add, HELP_ADD }, - { "remove", zpool_do_remove, HELP_REMOVE }, - { NULL }, -+ { "labelclear", zpool_do_labelclear, HELP_LABELCLEAR }, -+ { NULL }, - { "list", zpool_do_list, HELP_LIST }, - { "iostat", zpool_do_iostat, HELP_IOSTAT }, - { "status", zpool_do_status, HELP_STATUS }, -@@ -233,8 +237,10 @@ get_usage(zpool_help_t idx) { - case HELP_IOSTAT: - return (gettext("\tiostat [-v] [-T d|u] [pool] ... [interval " - "[count]]\n")); -+ case HELP_LABELCLEAR: -+ return (gettext("\tlabelclear [-f] \n")); - case HELP_LIST: -- return (gettext("\tlist [-H] [-o property[,...]] " -+ return (gettext("\tlist [-Hv] [-o property[,...]] " - "[-T d|u] [pool] ... [interval [count]]\n")); - case HELP_OFFLINE: - return (gettext("\toffline [-t] ...\n")); -@@ -246,7 +252,7 @@ get_usage(zpool_help_t idx) { - case HELP_REMOVE: - return (gettext("\tremove ...\n")); - case HELP_REOPEN: -- return (""); /* Undocumented command */ -+ return (gettext("\treopen \n")); - case HELP_SCRUB: - return (gettext("\tscrub [-s] ...\n")); - case HELP_STATUS: -@@ -642,6 +648,127 @@ zpool_do_remove(int argc, char **argv) - } - - /* -+ * zpool labelclear -+ * -+ * Verifies that the vdev is not active and zeros out the label information -+ * on the device. -+ */ -+int -+zpool_do_labelclear(int argc, char **argv) -+{ -+ char *vdev, *name; -+ int c, fd = -1, ret = 0; -+ pool_state_t state; -+ boolean_t inuse = B_FALSE; -+ boolean_t force = B_FALSE; -+ -+ /* check options */ -+ while ((c = getopt(argc, argv, "f")) != -1) { -+ switch (c) { -+ case 'f': -+ force = B_TRUE; -+ break; -+ default: -+ (void) fprintf(stderr, gettext("invalid option '%c'\n"), -+ optopt); -+ usage(B_FALSE); -+ } -+ } -+ -+ argc -= optind; -+ argv += optind; -+ -+ /* get vdev name */ -+ if (argc < 1) { -+ (void) fprintf(stderr, gettext("missing vdev device name\n")); -+ usage(B_FALSE); -+ } -+ -+ vdev = argv[0]; -+ if ((fd = open(vdev, O_RDWR)) < 0) { -+ (void) fprintf(stderr, gettext("Unable to open %s\n"), vdev); -+ return (B_FALSE); -+ } -+ -+ name = NULL; -+ if (zpool_in_use(g_zfs, fd, &state, &name, &inuse) != 0) { -+ if (force) -+ goto wipe_label; -+ -+ (void) fprintf(stderr, -+ gettext("Unable to determine pool state for %s\n" -+ "Use -f to force the clearing any label data\n"), vdev); -+ -+ return (1); -+ } -+ -+ if (inuse) { -+ switch (state) { -+ default: -+ case POOL_STATE_ACTIVE: -+ case POOL_STATE_SPARE: -+ case POOL_STATE_L2CACHE: -+ (void) fprintf(stderr, -+ gettext("labelclear operation failed.\n" -+ "\tVdev %s is a member (%s), of pool \"%s\".\n" -+ "\tTo remove label information from this device, " -+ "export or destroy\n\tthe pool, or remove %s from " -+ "the configuration of this pool\n\tand retry the " -+ "labelclear operation.\n"), -+ vdev, zpool_pool_state_to_name(state), name, vdev); -+ ret = 1; -+ goto errout; -+ -+ case POOL_STATE_EXPORTED: -+ if (force) -+ break; -+ -+ (void) fprintf(stderr, -+ gettext("labelclear operation failed.\n\tVdev " -+ "%s is a member of the exported pool \"%s\".\n" -+ "\tUse \"zpool labelclear -f %s\" to force the " -+ "removal of label\n\tinformation.\n"), -+ vdev, name, vdev); -+ ret = 1; -+ goto errout; -+ -+ case POOL_STATE_POTENTIALLY_ACTIVE: -+ if (force) -+ break; -+ -+ (void) fprintf(stderr, -+ gettext("labelclear operation failed.\n" -+ "\tVdev %s is a member of the pool \"%s\".\n" -+ "\tThis pool is unknown to this system, but may " -+ "be active on\n\tanother system. Use " -+ "\'zpool labelclear -f %s\' to force the\n" -+ "\tremoval of label information.\n"), -+ vdev, name, vdev); -+ ret = 1; -+ goto errout; -+ -+ case POOL_STATE_DESTROYED: -+ /* inuse should never be set for a destroyed pool... */ -+ break; -+ } -+ } -+ -+wipe_label: -+ if (zpool_clear_label(fd) != 0) { -+ (void) fprintf(stderr, -+ gettext("Label clear failed on vdev %s\n"), vdev); -+ ret = 1; -+ } -+ -+errout: -+ close(fd); -+ if (name != NULL) -+ free(name); -+ -+ return (ret); -+} -+ -+/* - * zpool create [-fnd] [-o property=value] ... - * [-O file-system-property=value] ... - * [-R root] [-m mountpoint] ... -@@ -2932,7 +3059,7 @@ int - zpool_do_list(int argc, char **argv) - { - int c; -- int ret; -+ int ret = 0; - list_cbdata_t cb = { 0 }; - static char default_props[] = - "name,size,allocated,free,capacity,dedupratio," -@@ -3612,22 +3739,37 @@ zpool_do_reguid(int argc, char **argv) - * zpool reopen - * - * Reopen the pool so that the kernel can update the sizes of all vdevs. -- * -- * NOTE: This command is currently undocumented. If the command is ever -- * exposed then the appropriate usage() messages will need to be made. - */ - int - zpool_do_reopen(int argc, char **argv) - { -+ int c; - int ret = 0; - zpool_handle_t *zhp; - char *pool; - -+ /* check options */ -+ while ((c = getopt(argc, argv, "")) != -1) { -+ switch (c) { -+ case '?': -+ (void) fprintf(stderr, gettext("invalid option '%c'\n"), -+ optopt); -+ usage(B_FALSE); -+ } -+ } -+ - argc--; - argv++; - -- if (argc != 1) -- return (2); -+ if (argc < 1) { -+ (void) fprintf(stderr, gettext("missing pool name\n")); -+ usage(B_FALSE); -+ } -+ -+ if (argc > 1) { -+ (void) fprintf(stderr, gettext("too many arguments\n")); -+ usage(B_FALSE); -+ } - - pool = argv[0]; - if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) -@@ -5228,6 +5370,7 @@ zpool_do_events_next(ev_opts_t *opts) - zpool_do_events_nvprint(nvl, 8); - printf(gettext("\n")); - } -+ (void) fflush(stdout); - - nvlist_free(nvl); - } -diff --git a/cmd/ztest/ztest.c b/cmd/ztest/ztest.c -index bb495b6..93a5f1e 100644 ---- a/cmd/ztest/ztest.c -+++ b/cmd/ztest/ztest.c -@@ -1039,7 +1039,7 @@ ztest_dsl_prop_set_uint64(char *osname, zfs_prop_t prop, uint64_t value, - ztest_record_enospc(FTAG); - return (error); - } -- ASSERT3U(error, ==, 0); -+ ASSERT0(error); - - setpoint = umem_alloc(MAXPATHLEN, UMEM_NOFAIL); - VERIFY3U(dsl_prop_get(osname, propname, sizeof (curval), -@@ -1073,7 +1073,7 @@ ztest_spa_prop_set_uint64(zpool_prop_t prop, uint64_t value) - ztest_record_enospc(FTAG); - return (error); - } -- ASSERT3U(error, ==, 0); -+ ASSERT0(error); - - return (error); - } -@@ -1776,7 +1776,7 @@ ztest_replay_setattr(ztest_ds_t *zd, lr_setattr_t *lr, boolean_t byteswap) - - ASSERT3U(lr->lr_size, >=, sizeof (*bbt)); - ASSERT3U(lr->lr_size, <=, db->db_size); -- VERIFY3U(dmu_set_bonus(db, lr->lr_size, tx), ==, 0); -+ VERIFY0(dmu_set_bonus(db, lr->lr_size, tx)); - bbt = ztest_bt_bonus(db); - - ztest_bt_generate(bbt, os, lr->lr_foid, -1ULL, lr->lr_mode, txg, crtxg); -@@ -2581,7 +2581,7 @@ ztest_vdev_aux_add_remove(ztest_ds_t *zd, uint64_t id) - zs->zs_vdev_aux = 0; - for (;;) { - int c; -- (void) snprintf(path, sizeof (path), ztest_aux_template, -+ (void) snprintf(path, MAXPATHLEN, ztest_aux_template, - ztest_opts.zo_dir, ztest_opts.zo_pool, aux, - zs->zs_vdev_aux); - for (c = 0; c < sav->sav_count; c++) -@@ -3200,7 +3200,7 @@ ztest_objset_destroy_cb(const char *name, void *arg) - error = dmu_object_info(os, ZTEST_DIROBJ, &doi); - if (error != ENOENT) { - /* We could have crashed in the middle of destroying it */ -- ASSERT3U(error, ==, 0); -+ ASSERT0(error); - ASSERT3U(doi.doi_type, ==, DMU_OT_ZAP_OTHER); - ASSERT3S(doi.doi_physical_blocks_512, >=, 0); - } -@@ -3673,10 +3673,10 @@ ztest_dmu_read_write(ztest_ds_t *zd, uint64_t id) - */ - error = dmu_read(os, packobj, packoff, packsize, packbuf, - DMU_READ_PREFETCH); -- ASSERT3U(error, ==, 0); -+ ASSERT0(error); - error = dmu_read(os, bigobj, bigoff, bigsize, bigbuf, - DMU_READ_PREFETCH); -- ASSERT3U(error, ==, 0); -+ ASSERT0(error); - - /* - * Get a tx for the mods to both packobj and bigobj. -@@ -3999,10 +3999,10 @@ ztest_dmu_read_write_zcopy(ztest_ds_t *zd, uint64_t id) - if (i != 0 || ztest_random(2) != 0) { - error = dmu_read(os, packobj, packoff, - packsize, packbuf, DMU_READ_PREFETCH); -- ASSERT3U(error, ==, 0); -+ ASSERT0(error); - error = dmu_read(os, bigobj, bigoff, bigsize, - bigbuf, DMU_READ_PREFETCH); -- ASSERT3U(error, ==, 0); -+ ASSERT0(error); - } - compare_and_update_pbbufs(s, packbuf, bigbuf, bigsize, - n, chunksize, txg); -@@ -4287,7 +4287,7 @@ ztest_zap(ztest_ds_t *zd, uint64_t id) - if (error == ENOENT) - goto out; - -- ASSERT3U(error, ==, 0); -+ ASSERT0(error); - - tx = dmu_tx_create(os); - dmu_tx_hold_zap(tx, object, B_TRUE, NULL); -@@ -4494,7 +4494,7 @@ ztest_commit_callback(void *arg, int error) - data->zcd_called = B_TRUE; - - if (error == ECANCELED) { -- ASSERT3U(data->zcd_txg, ==, 0); -+ ASSERT0(data->zcd_txg); - ASSERT(!data->zcd_added); - - /* -@@ -4704,7 +4704,7 @@ ztest_spa_prop_get_set(ztest_ds_t *zd, uint64_t id) - (void) ztest_spa_prop_set_uint64(ZPOOL_PROP_DEDUPDITTO, - ZIO_DEDUPDITTO_MIN + ztest_random(ZIO_DEDUPDITTO_MIN)); - -- VERIFY3U(spa_prop_get(ztest_spa, &props), ==, 0); -+ VERIFY0(spa_prop_get(ztest_spa, &props)); - - if (ztest_opts.zo_verbose >= 6) - dump_nvlist(props, 4); -@@ -5557,7 +5557,7 @@ ztest_dataset_open(int d) - } - ASSERT(error == 0 || error == EEXIST); - -- VERIFY3U(dmu_objset_hold(name, zd, &os), ==, 0); -+ VERIFY0(dmu_objset_hold(name, zd, &os)); - (void) rw_exit(&ztest_name_lock); - - ztest_zd_init(zd, ZTEST_GET_SHARED_DS(d), os); -@@ -5757,7 +5757,7 @@ ztest_run(ztest_shared_t *zs) - - /* Verify that at least one commit cb was called in a timely fashion */ - if (zc_cb_counter >= ZTEST_COMMIT_CB_MIN_REG) -- VERIFY3U(zc_min_txg_delay, ==, 0); -+ VERIFY0(zc_min_txg_delay); - - spa_close(spa, FTAG); - -diff --git a/config/Rules.am b/config/Rules.am -index bd4f0ea..e3fa5b5 100644 ---- a/config/Rules.am -+++ b/config/Rules.am -@@ -3,6 +3,6 @@ DEFAULT_INCLUDES = -include ${top_builddir}/zfs_config.h - AM_LIBTOOLFLAGS = --silent - AM_CFLAGS = -Wall -Wstrict-prototypes - AM_CFLAGS += -fno-strict-aliasing ${NO_UNUSED_BUT_SET_VARIABLE} ${DEBUG_CFLAGS} --AM_CFLAGS += -D_GNU_SOURCE -D__EXTENSIONS__ -D_REENTRANT --AM_CFLAGS += -D_POSIX_PTHREAD_SEMANTICS -D_FILE_OFFSET_BITS=64 --AM_CFLAGS += -D_LARGEFILE64_SOURCE -DTEXT_DOMAIN=\"zfs-linux-user\" -+AM_CPPFLAGS = -D_GNU_SOURCE -D__EXTENSIONS__ -D_REENTRANT -+AM_CPPFLAGS += -D_POSIX_PTHREAD_SEMANTICS -D_FILE_OFFSET_BITS=64 -+AM_CPPFLAGS += -D_LARGEFILE64_SOURCE -DTEXT_DOMAIN=\"zfs-linux-user\" -diff --git a/config/deb.am b/config/deb.am -index 078dd0c..78b01f0 100644 ---- a/config/deb.am -+++ b/config/deb.am -@@ -20,7 +20,7 @@ if CONFIG_KERNEL - version=${VERSION}-${RELEASE}; \ - arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \ - pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \ -- fakeroot $(ALIEN) --scripts --to-deb $$pkg1; \ -+ fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \ - $(RM) $$pkg1 - endif - -@@ -33,7 +33,7 @@ if CONFIG_USER - pkg2=$${name}-devel-$${version}.$${arch}.rpm; \ - pkg3=$${name}-test-$${version}.$${arch}.rpm; \ - pkg4=$${name}-dracut-$${version}.$${arch}.rpm; \ -- fakeroot $(ALIEN) --scripts --to-deb $$pkg1 $$pkg2 $$pkg3 $$pkg4; \ -+ fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1 $$pkg2 $$pkg3 $$pkg4; \ - $(RM) $$pkg1 $$pkg2 $$pkg3 $$pkg4 - endif - -diff --git a/config/kernel-bdev-block-device-operations.m4 b/config/kernel-bdev-block-device-operations.m4 -index 8b5e0a3..faacc19 100644 ---- a/config/kernel-bdev-block-device-operations.m4 -+++ b/config/kernel-bdev-block-device-operations.m4 -@@ -10,7 +10,6 @@ AC_DEFUN([ZFS_AC_KERNEL_BDEV_BLOCK_DEVICE_OPERATIONS], [ - - int blk_open(struct block_device *bdev, fmode_t mode) - { return 0; } -- int blk_release(struct gendisk *g, fmode_t mode) { return 0; } - int blk_ioctl(struct block_device *bdev, fmode_t mode, - unsigned x, unsigned long y) { return 0; } - int blk_compat_ioctl(struct block_device * bdev, fmode_t mode, -@@ -19,7 +18,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BDEV_BLOCK_DEVICE_OPERATIONS], [ - static const struct block_device_operations - bops __attribute__ ((unused)) = { - .open = blk_open, -- .release = blk_release, -+ .release = NULL, - .ioctl = blk_ioctl, - .compat_ioctl = blk_compat_ioctl, - }; -diff --git a/config/kernel-block-device-operations-release-void.m4 b/config/kernel-block-device-operations-release-void.m4 -new file mode 100644 -index 0000000..a73f858 ---- /dev/null -+++ b/config/kernel-block-device-operations-release-void.m4 -@@ -0,0 +1,29 @@ -+dnl # -+dnl # 3.10.x API change -+dnl # -+AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [ -+ AC_MSG_CHECKING([whether block_device_operations.release is void]) -+ tmp_flags="$EXTRA_KCFLAGS" -+ EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}" -+ ZFS_LINUX_TRY_COMPILE([ -+ #include -+ -+ void blk_release(struct gendisk *g, fmode_t mode) { return; } -+ -+ static const struct block_device_operations -+ bops __attribute__ ((unused)) = { -+ .open = NULL, -+ .release = blk_release, -+ .ioctl = NULL, -+ .compat_ioctl = NULL, -+ }; -+ ],[ -+ ],[ -+ AC_MSG_RESULT(void) -+ AC_DEFINE(HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID, 1, -+ [struct block_device_operations.release returns void]) -+ ],[ -+ AC_MSG_RESULT(int) -+ ]) -+ EXTRA_KCFLAGS="$tmp_flags" -+]) -diff --git a/config/kernel-lseek-execute.m4 b/config/kernel-lseek-execute.m4 -new file mode 100644 -index 0000000..8c4032b ---- /dev/null -+++ b/config/kernel-lseek-execute.m4 -@@ -0,0 +1,23 @@ -+dnl # -+dnl # 3.11 API change -+dnl # lseek_execute helper exported -+dnl # -+AC_DEFUN([ZFS_AC_KERNEL_LSEEK_EXECUTE], -+ [AC_MSG_CHECKING([whether lseek_execute() is available]) -+ ZFS_LINUX_TRY_COMPILE_SYMBOL([ -+ #include -+ ], [ -+ struct file *fp __attribute__ ((unused)) = NULL; -+ struct inode *ip __attribute__ ((unused)) = NULL; -+ loff_t offset __attribute__ ((unused)) = 0; -+ loff_t maxsize __attribute__ ((unused)) = 0; -+ -+ lseek_execute(fp, ip, offset, maxsize); -+ ], [lseek_exclusive], [fs/read_write.c], [ -+ AC_MSG_RESULT(yes) -+ AC_DEFINE(HAVE_LSEEK_EXECUTE, 1, -+ [lseek_execute() is available]) -+ ], [ -+ AC_MSG_RESULT(no) -+ ]) -+]) -diff --git a/config/kernel-shrink.m4 b/config/kernel-shrink.m4 -index 479fb3a..1c211ed 100644 ---- a/config/kernel-shrink.m4 -+++ b/config/kernel-shrink.m4 -@@ -28,6 +28,45 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINK], [ - ]) - ]) - -+dnl # -+dnl # 3.3 API change -+dnl # The super_block structure was changed to use an hlist_node instead -+dnl # of a list_head for the .s_instance linkage. -+dnl # -+dnl # This was done in part to resolve a race in the iterate_supers_type() -+dnl # function which was introduced in Linux 3.0 kernel. The iterator -+dnl # was supposed to provide a safe way to call an arbitrary function on -+dnl # all super blocks of a specific type. Unfortunately, because a -+dnl # list_head was used it was possible for iterate_supers_type() to -+dnl # get stuck spinning a super block which was just deactivated. -+dnl # -+dnl # This can occur because when the list head is removed from the -+dnl # fs_supers list it is reinitialized to point to itself. If the -+dnl # iterate_supers_type() function happened to be processing the -+dnl # removed list_head it will get stuck spinning on that list_head. -+dnl # -+dnl # To resolve the issue for existing 3.0 - 3.2 kernels we detect when -+dnl # a list_head is used. Then to prevent the spinning from occurring -+dnl # the .next pointer is set to the fs_supers list_head which ensures -+dnl # the iterate_supers_type() function will always terminate. -+dnl # -+AC_DEFUN([ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD], [ -+ AC_MSG_CHECKING([whether super_block has s_instances list_head]) -+ ZFS_LINUX_TRY_COMPILE([ -+ #include -+ ],[ -+ struct super_block sb __attribute__ ((unused)); -+ -+ INIT_LIST_HEAD(&sb.s_instances); -+ ],[ -+ AC_MSG_RESULT(yes) -+ AC_DEFINE(HAVE_S_INSTANCES_LIST_HEAD, 1, -+ [struct super_block has s_instances list_head]) -+ ],[ -+ AC_MSG_RESULT(no) -+ ]) -+]) -+ - AC_DEFUN([ZFS_AC_KERNEL_NR_CACHED_OBJECTS], [ - AC_MSG_CHECKING([whether sops->nr_cached_objects() exists]) - ZFS_LINUX_TRY_COMPILE([ -diff --git a/config/kernel.m4 b/config/kernel.m4 -index 88590be..8742bc5 100644 ---- a/config/kernel.m4 -+++ b/config/kernel.m4 -@@ -7,6 +7,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ - ZFS_AC_TEST_MODULE - ZFS_AC_KERNEL_CONFIG - ZFS_AC_KERNEL_BDEV_BLOCK_DEVICE_OPERATIONS -+ ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID - ZFS_AC_KERNEL_TYPE_FMODE_T - ZFS_AC_KERNEL_KOBJ_NAME_LEN - ZFS_AC_KERNEL_3ARG_BLKDEV_GET -@@ -71,12 +72,14 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ - ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY - ZFS_AC_KERNEL_MOUNT_NODEV - ZFS_AC_KERNEL_SHRINK -+ ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD - ZFS_AC_KERNEL_S_D_OP - ZFS_AC_KERNEL_BDI - ZFS_AC_KERNEL_BDI_SETUP_AND_REGISTER - ZFS_AC_KERNEL_SET_NLINK - ZFS_AC_KERNEL_ELEVATOR_CHANGE - ZFS_AC_KERNEL_5ARG_SGET -+ ZFS_AC_KERNEL_LSEEK_EXECUTE - - AS_IF([test "$LINUX_OBJ" != "$LINUX"], [ - KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ" -@@ -109,7 +112,7 @@ AC_DEFUN([ZFS_AC_MODULE_SYMVERS], [ - AS_IF([test ! -f "$LINUX_OBJ/$LINUX_SYMBOLS"], [ - AC_MSG_ERROR([ - *** Please make sure the kernel devel package for your distribution -- *** is installed. If your building with a custom kernel make sure the -+ *** is installed. If you are building with a custom kernel, make sure the - *** kernel is configured, built, and the '--with-linux=PATH' configure - *** option refers to the location of the kernel source.]) - ]) -@@ -163,7 +166,7 @@ AC_DEFUN([ZFS_AC_KERNEL], [ - AS_IF([test ! -d "$kernelsrc"], [ - AC_MSG_ERROR([ - *** Please make sure the kernel devel package for your distribution -- *** is installed then try again. If that fails you can specify the -+ *** is installed and then try again. If that fails, you can specify the - *** location of the kernel source with the '--with-linux=PATH' option.]) - ]) - -@@ -229,54 +232,6 @@ AC_DEFUN([ZFS_AC_KERNEL], [ - ZFS_AC_MODULE_SYMVERS - ]) - --dnl # --dnl # Detect name used for the additional SPL Module.symvers file. If one --dnl # does not exist this is likely because the SPL has been configured --dnl # but not built. The '--with-spl-timeout' option can be passed --dnl # to pause here, waiting for the file to appear from a concurrently --dnl # building SPL package. If the file does not appear in time, a good --dnl # guess is made as to what this file will be named based on what it --dnl # is named in the kernel build products. This file will first be --dnl # used at link time so if the guess is wrong the build will fail --dnl # then. This unfortunately means the ZFS package does not contain a --dnl # reliable mechanism to detect symbols exported by the SPL at --dnl # configure time. --dnl # --AC_DEFUN([ZFS_AC_SPL_MODULE_SYMVERS], [ -- AC_ARG_WITH([spl-timeout], -- AS_HELP_STRING([--with-spl-timeout=SECS], -- [Wait SECS for symvers file to appear @<:@default=0@:>@]), -- [timeout="$withval"], [timeout=0]) -- -- AC_MSG_CHECKING([spl file name for module symbols]) -- SPL_SYMBOLS=NONE -- -- while true; do -- AS_IF([test -r $SPL_OBJ/Module.symvers], [ -- SPL_SYMBOLS=Module.symvers -- ], [test -r $SPL_OBJ/Modules.symvers], [ -- SPL_SYMBOLS=Modules.symvers -- ], [test -r $SPL_OBJ/module/Module.symvers], [ -- SPL_SYMBOLS=Module.symvers -- ], [test -r $SPL_OBJ/module/Modules.symvers], [ -- SPL_SYMBOLS=Modules.symvers -- ]) -- -- AS_IF([test $SPL_SYMBOLS != NONE -o $timeout -le 0], [ -- break; -- ], [ -- sleep 1 -- timeout=$((timeout-1)) -- ]) -- done -- -- AS_IF([test "$SPL_SYMBOLS" = NONE], [ -- SPL_SYMBOLS=$LINUX_SYMBOLS -- ]) -- -- AC_MSG_RESULT([$SPL_SYMBOLS]) -- AC_SUBST(SPL_SYMBOLS) --]) - - dnl # - dnl # Detect the SPL module to be built against -@@ -292,6 +247,11 @@ AC_DEFUN([ZFS_AC_SPL], [ - [Path to spl build objects]), - [splbuild="$withval"]) - -+ AC_ARG_WITH([spl-timeout], -+ AS_HELP_STRING([--with-spl-timeout=SECS], -+ [Wait SECS for SPL header and symver file @<:@default=0@:>@]), -+ [timeout="$withval"], [timeout=0]) -+ - dnl # - dnl # The existence of spl.release.in is used to identify a valid - dnl # source directory. In order of preference: -@@ -338,16 +298,30 @@ AC_DEFUN([ZFS_AC_SPL], [ - dnl # directory are the same, however the objects may also reside - dnl # is a subdirectory named after the kernel version. - dnl # -+ dnl # This file is supposed to be available after DKMS finishes -+ dnl # building the SPL kernel module for the target kernel. The -+ dnl # '--with-spl-timeout' option can be passed to pause here, -+ dnl # waiting for the file to appear from a concurrently building -+ dnl # SPL package. -+ dnl # - AC_MSG_CHECKING([spl build directory]) -- AS_IF([test -z "$splbuild"], [ -- AS_IF([ test -e "${splsrc}/${LINUX_VERSION}/spl_config.h" ], [ -- splbuild="${splsrc}/${LINUX_VERSION}" -- ], [ test -e "${splsrc}/spl_config.h" ], [ -- splbuild="${splsrc}" -+ while true; do -+ AS_IF([test -z "$splbuild"], [ -+ AS_IF([ test -e "${splsrc}/${LINUX_VERSION}/spl_config.h" ], [ -+ splbuild="${splsrc}/${LINUX_VERSION}" -+ ], [ test -e "${splsrc}/spl_config.h" ], [ -+ splbuild="${splsrc}" -+ ], [ -+ splbuild="[Not found]" -+ ]) -+ ]) -+ AS_IF([test -e "$splbuild/spl_config.h" -o $timeout -le 0], [ -+ break; - ], [ -- splbuild="[Not found]" -+ sleep 1 -+ timeout=$((timeout-1)) - ]) -- ]) -+ done - - AC_MSG_RESULT([$splbuild]) - AS_IF([ ! test -e "$splbuild/spl_config.h"], [ -@@ -385,7 +359,47 @@ AC_DEFUN([ZFS_AC_SPL], [ - AC_SUBST(SPL_OBJ) - AC_SUBST(SPL_VERSION) - -- ZFS_AC_SPL_MODULE_SYMVERS -+ dnl # -+ dnl # Detect the name used for the SPL Module.symvers file. If one -+ dnl # does not exist this is likely because the SPL has been configured -+ dnl # but not built. The '--with-spl-timeout' option can be passed -+ dnl # to pause here, waiting for the file to appear from a concurrently -+ dnl # building SPL package. If the file does not appear in time, a good -+ dnl # guess is made as to what this file will be named based on what it -+ dnl # is named in the kernel build products. This file will first be -+ dnl # used at link time so if the guess is wrong the build will fail -+ dnl # then. This unfortunately means the ZFS package does not contain a -+ dnl # reliable mechanism to detect symbols exported by the SPL at -+ dnl # configure time. -+ dnl # -+ AC_MSG_CHECKING([spl file name for module symbols]) -+ SPL_SYMBOLS=NONE -+ -+ while true; do -+ AS_IF([test -r $SPL_OBJ/Module.symvers], [ -+ SPL_SYMBOLS=Module.symvers -+ ], [test -r $SPL_OBJ/Modules.symvers], [ -+ SPL_SYMBOLS=Modules.symvers -+ ], [test -r $SPL_OBJ/module/Module.symvers], [ -+ SPL_SYMBOLS=Module.symvers -+ ], [test -r $SPL_OBJ/module/Modules.symvers], [ -+ SPL_SYMBOLS=Modules.symvers -+ ]) -+ -+ AS_IF([test $SPL_SYMBOLS != NONE -o $timeout -le 0], [ -+ break; -+ ], [ -+ sleep 1 -+ timeout=$((timeout-1)) -+ ]) -+ done -+ -+ AS_IF([test "$SPL_SYMBOLS" = NONE], [ -+ SPL_SYMBOLS=$LINUX_SYMBOLS -+ ]) -+ -+ AC_MSG_RESULT([$SPL_SYMBOLS]) -+ AC_SUBST(SPL_SYMBOLS) - ]) - - dnl # -diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 -index cccd87f..005185b 100644 ---- a/config/zfs-build.m4 -+++ b/config/zfs-build.m4 -@@ -138,7 +138,7 @@ AC_DEFUN([ZFS_AC_RPM], [ - AC_MSG_RESULT([$HAVE_RPMBUILD]) - ]) - -- RPM_DEFINE_COMMON= -+ RPM_DEFINE_COMMON='--define "$(DEBUG_ZFS) 1" --define "$(DEBUG_DMU_TX) 1"' - RPM_DEFINE_UTIL= - RPM_DEFINE_KMOD='--define "kernels $(LINUX_VERSION)"' - RPM_DEFINE_DKMS= -diff --git a/config/zfs-meta.m4 b/config/zfs-meta.m4 -index 2deda71..20a61cf 100644 ---- a/config/zfs-meta.m4 -+++ b/config/zfs-meta.m4 -@@ -1,14 +1,35 @@ --############################################################################### --# Written by Chris Dunlap . --# Modified by Brian Behlendorf . --############################################################################### --# ZFS_AC_META: Read metadata from the META file. When building from a --# git repository the ZFS_META_RELEASE field will be overwritten if there --# is an annotated tag matching the form ZFS_META_NAME-ZFS_META_VERSION-*. --# This allows for working builds to be uniquely identified using the git --# commit hash. --############################################################################### -- -+dnl # -+dnl # DESCRIPTION: -+dnl # Read meta data from the META file. When building from a git repository -+dnl # the ZFS_META_RELEASE field will be overwritten if there is an annotated -+dnl # tag matching the form ZFS_META_NAME-ZFS_META_VERSION-*. This allows -+dnl # for working builds to be uniquely identified using the git commit hash. -+dnl # -+dnl # The META file format is as follows: -+dnl # ^[ ]*KEY:[ \t]+VALUE$ -+dnl # -+dnl # In other words: -+dnl # - KEY is separated from VALUE by a colon and one or more spaces/tabs. -+dnl # - KEY and VALUE are case sensitive. -+dnl # - Leading spaces are ignored. -+dnl # - First match wins for duplicate keys. -+dnl # -+dnl # A line can be commented out by preceding it with a '#' (or technically -+dnl # any non-space character since that will prevent the regex from -+dnl # matching). -+dnl # -+dnl # WARNING: -+dnl # Placing a colon followed by a space or tab (ie, ":[ \t]+") within the -+dnl # VALUE will prematurely terminate the string since that sequence is -+dnl # used as the awk field separator. -+dnl # -+dnl # KEYS: -+dnl # The following META keys are recognized: -+dnl # Name, Version, Release, Date, Author, LT_Current, LT_Revision, LT_Age -+dnl # -+dnl # Written by Chris Dunlap . -+dnl # Modified by Brian Behlendorf . -+dnl # - AC_DEFUN([ZFS_AC_META], [ - - AH_BOTTOM([ -@@ -21,6 +42,7 @@ AC_DEFUN([ZFS_AC_META], [ - #undef STDC_HEADERS - #undef VERSION]) - -+ AC_PROG_AWK - AC_MSG_CHECKING([metadata]) - - META="$srcdir/META" -@@ -28,7 +50,7 @@ AC_DEFUN([ZFS_AC_META], [ - if test -f "$META"; then - _zfs_ac_meta_type="META file" - -- ZFS_META_NAME=_ZFS_AC_META_GETVAL([(?:NAME|PROJECT|PACKAGE)]); -+ ZFS_META_NAME=_ZFS_AC_META_GETVAL([(Name|Project|Package)]); - if test -n "$ZFS_META_NAME"; then - AC_DEFINE_UNQUOTED([ZFS_META_NAME], ["$ZFS_META_NAME"], - [Define the project name.] -@@ -36,7 +58,7 @@ AC_DEFUN([ZFS_AC_META], [ - AC_SUBST([ZFS_META_NAME]) - fi - -- ZFS_META_VERSION=_ZFS_AC_META_GETVAL([VERSION]); -+ ZFS_META_VERSION=_ZFS_AC_META_GETVAL([Version]); - if test -n "$ZFS_META_VERSION"; then - AC_DEFINE_UNQUOTED([ZFS_META_VERSION], ["$ZFS_META_VERSION"], - [Define the project version.] -@@ -44,8 +66,8 @@ AC_DEFUN([ZFS_AC_META], [ - AC_SUBST([ZFS_META_VERSION]) - fi - -- ZFS_META_RELEASE=_ZFS_AC_META_GETVAL([RELEASE]); -- if git rev-parse --git-dir > /dev/null 2>&1; then -+ ZFS_META_RELEASE=_ZFS_AC_META_GETVAL([Release]); -+ if test ! -f ".nogitrelease" && git rev-parse --git-dir > /dev/null 2>&1; then - _match="${ZFS_META_NAME}-${ZFS_META_VERSION}*" - _alias=$(git describe --match=${_match} 2>/dev/null) - _release=$(echo ${_alias}|cut -f3- -d'-'|sed 's/-/_/g') -@@ -65,7 +87,7 @@ AC_DEFUN([ZFS_AC_META], [ - AC_SUBST([RELEASE]) - fi - -- ZFS_META_LICENSE=_ZFS_AC_META_GETVAL([LICENSE]); -+ ZFS_META_LICENSE=_ZFS_AC_META_GETVAL([License]); - if test -n "$ZFS_META_LICENSE"; then - AC_DEFINE_UNQUOTED([ZFS_META_LICENSE], ["$ZFS_META_LICENSE"], - [Define the project license.] -@@ -84,7 +106,7 @@ AC_DEFUN([ZFS_AC_META], [ - AC_SUBST([ZFS_META_ALIAS]) - fi - -- ZFS_META_DATA=_ZFS_AC_META_GETVAL([DATE]); -+ ZFS_META_DATA=_ZFS_AC_META_GETVAL([Date]); - if test -n "$ZFS_META_DATA"; then - AC_DEFINE_UNQUOTED([ZFS_META_DATA], ["$ZFS_META_DATA"], - [Define the project release date.] -@@ -92,7 +114,7 @@ AC_DEFUN([ZFS_AC_META], [ - AC_SUBST([ZFS_META_DATA]) - fi - -- ZFS_META_AUTHOR=_ZFS_AC_META_GETVAL([AUTHOR]); -+ ZFS_META_AUTHOR=_ZFS_AC_META_GETVAL([Author]); - if test -n "$ZFS_META_AUTHOR"; then - AC_DEFINE_UNQUOTED([ZFS_META_AUTHOR], ["$ZFS_META_AUTHOR"], - [Define the project author.] -@@ -101,9 +123,9 @@ AC_DEFUN([ZFS_AC_META], [ - fi - - m4_pattern_allow([^LT_(CURRENT|REVISION|AGE)$]) -- ZFS_META_LT_CURRENT=_ZFS_AC_META_GETVAL([LT_CURRENT]); -- ZFS_META_LT_REVISION=_ZFS_AC_META_GETVAL([LT_REVISION]); -- ZFS_META_LT_AGE=_ZFS_AC_META_GETVAL([LT_AGE]); -+ ZFS_META_LT_CURRENT=_ZFS_AC_META_GETVAL([LT_Current]); -+ ZFS_META_LT_REVISION=_ZFS_AC_META_GETVAL([LT_Revision]); -+ ZFS_META_LT_AGE=_ZFS_AC_META_GETVAL([LT_Age]); - if test -n "$ZFS_META_LT_CURRENT" \ - -o -n "$ZFS_META_LT_REVISION" \ - -o -n "$ZFS_META_LT_AGE"; then -@@ -134,15 +156,18 @@ AC_DEFUN([ZFS_AC_META], [ - ] - ) - --AC_DEFUN([_ZFS_AC_META_GETVAL], -- [`perl -n\ -- -e "BEGIN { \\$key=shift @ARGV; }"\ -- -e "next unless s/^\s*\\$key@<:@:=@:>@//i;"\ -- -e "s/^((?:@<:@^'\"#@:>@*(?:(@<:@'\"@:>@)@<:@^\2@:>@*\2)*)*)#.*/\\@S|@1/;"\ -- -e "s/^\s+//;"\ -- -e "s/\s+$//;"\ -- -e "s/^(@<:@'\"@:>@)(.*)\1/\\@S|@2/;"\ -- -e "\\$val=\\$_;"\ -- -e "END { print \\$val if defined \\$val; }"\ -- '$1' $META`]dnl -+dnl # _ZFS_AC_META_GETVAL (KEY_NAME_OR_REGEX) -+dnl # -+dnl # Returns the META VALUE associated with the given KEY_NAME_OR_REGEX expr. -+dnl # -+dnl # Despite their resemblance to line noise, -+dnl # the "@<:@" and "@:>@" constructs are quadrigraphs for "[" and "]". -+dnl # -+dnl # -+dnl # The "$[]1" and "$[]2" constructs prevent M4 parameter expansion -+dnl # so a literal $1 and $2 will be passed to the resulting awk script, -+dnl # whereas the "$1" will undergo M4 parameter expansion for the META key. -+dnl # -+AC_DEFUN([_ZFS_AC_META_GETVAL], -+ [`$AWK -F ':@<:@ \t@:>@+' '$[]1 ~ /^ *$1$/ { print $[]2; exit }' $META`]dnl - ) -diff --git a/configure.ac b/configure.ac -index 413114b..58e2158 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -34,9 +34,10 @@ AC_INIT - AC_LANG(C) - ZFS_AC_META - AC_CONFIG_AUX_DIR([config]) -+AC_CONFIG_MACRO_DIR([config]) - AC_CANONICAL_SYSTEM - AM_MAINTAINER_MODE --AM_SILENT_RULES -+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - AM_INIT_AUTOMAKE([$ZFS_META_NAME], [$ZFS_META_VERSION]) - AC_CONFIG_HEADERS([zfs_config.h], [ - (mv zfs_config.h zfs_config.h.tmp && -@@ -101,6 +102,7 @@ AC_CONFIG_FILES([ - cmd/fsck_zfs/Makefile - cmd/zvol_id/Makefile - cmd/vdev_id/Makefile -+ cmd/arcstat/Makefile - module/Makefile - module/avl/Makefile - module/nvpair/Makefile -diff --git a/etc/init.d/zfs.fedora.in b/etc/init.d/zfs.fedora.in -index 04f2077..3cece9b 100644 ---- a/etc/init.d/zfs.fedora.in -+++ b/etc/init.d/zfs.fedora.in -@@ -25,6 +25,11 @@ - - export PATH=/usr/local/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin - -+if [ -z "$init" ]; then -+ # Not interactive -+ grep -Eqi 'zfs=off|zfs=no' /proc/cmdline && exit 3 -+fi -+ - # Source function library & LSB routines - . /etc/rc.d/init.d/functions - -diff --git a/etc/init.d/zfs.gentoo.in b/etc/init.d/zfs.gentoo.in -index df883cf..0034e02 100644 ---- a/etc/init.d/zfs.gentoo.in -+++ b/etc/init.d/zfs.gentoo.in -@@ -3,11 +3,23 @@ - # Released under the 2-clause BSD license. - # $Header: /var/cvsroot/gentoo-x86/sys-fs/zfs/files/zfs,v 0.9 2011/04/30 10:13:43 devsk Exp $ - -+if [ -z "$init" ]; then -+ # Not interactive -+ grep -Eqi 'zfs=off|zfs=no' /proc/cmdline && exit 3 -+fi -+ - depend() - { -+ # Try to allow people to mix and match fstab with ZFS in a way that makes sense. -+ if [ "$(mountinfo -s /)" = 'zfs' ] -+ then -+ before localmount -+ else -+ after localmount -+ fi -+ - # bootmisc will log to /var which may be a different zfs than root. -- before net bootmisc -- after udev localmount -+ before bootmisc logger - keyword -lxc -openvz -prefix -vserver - } - -diff --git a/etc/init.d/zfs.lsb.in b/etc/init.d/zfs.lsb.in -index 3d04206..0d0ffb4 100644 ---- a/etc/init.d/zfs.lsb.in -+++ b/etc/init.d/zfs.lsb.in -@@ -36,6 +36,11 @@ ZPOOL_CACHE="@sysconfdir@/zfs/zpool.cache" - [ -x "$ZPOOL" ] || exit 1 - [ -x "$ZFS" ] || exit 2 - -+if [ -z "$init" ]; then -+ # Not interactive -+ grep -Eqi 'zfs=off|zfs=no' /proc/cmdline && exit 3 -+fi -+ - start() - { - [ -f "$LOCKFILE" ] && return 3 -diff --git a/etc/init.d/zfs.lunar.in b/etc/init.d/zfs.lunar.in -index 97384dc..3cf79ce 100644 ---- a/etc/init.d/zfs.lunar.in -+++ b/etc/init.d/zfs.lunar.in -@@ -14,6 +14,11 @@ ZFS="@sbindir@/zfs" - ZPOOL="@sbindir@/zpool" - ZPOOL_CACHE="@sysconfdir@/zfs/zpool.cache" - -+if [ -z "$init" ]; then -+ # Not interactive -+ grep -Eqi 'zfs=off|zfs=no' /proc/cmdline && exit 3 -+fi -+ - case $1 in - start) echo "$1ing ZFS filesystems" - -diff --git a/etc/init.d/zfs.redhat.in b/etc/init.d/zfs.redhat.in -index ae797c1..fb5187f 100644 ---- a/etc/init.d/zfs.redhat.in -+++ b/etc/init.d/zfs.redhat.in -@@ -25,6 +25,11 @@ - - export PATH=/usr/local/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin - -+if [ -z "$init" ]; then -+ # Not interactive -+ grep -Eqi 'zfs=off|zfs=no' /proc/cmdline && exit 3 -+fi -+ - # Source function library & LSB routines - . /etc/rc.d/init.d/functions - -diff --git a/include/libzfs.h b/include/libzfs.h -index 82cb66a..3472b76 100644 ---- a/include/libzfs.h -+++ b/include/libzfs.h -@@ -212,6 +212,7 @@ extern void zpool_close(zpool_handle_t *); - extern const char *zpool_get_name(zpool_handle_t *); - extern int zpool_get_state(zpool_handle_t *); - extern char *zpool_state_to_name(vdev_state_t, vdev_aux_t); -+extern const char *zpool_pool_state_to_name(pool_state_t); - extern void zpool_free_handles(libzfs_handle_t *); - - /* -diff --git a/include/linux/blkdev_compat.h b/include/linux/blkdev_compat.h -index 47f569b..ec9926f 100644 ---- a/include/linux/blkdev_compat.h -+++ b/include/linux/blkdev_compat.h -@@ -485,6 +485,6 @@ blk_queue_discard_granularity(struct request_queue *q, unsigned int dg) - * user space processes which don't pass this value will get EBUSY. This is - * currently required for the correct operation of hot spares. - */ --#define VDEV_HOLDER ((void *)0x2f5401de7) -+#define VDEV_HOLDER ((void *)0x2401de7) - - #endif /* _ZFS_BLKDEV_H */ -diff --git a/include/linux/vfs_compat.h b/include/linux/vfs_compat.h -index c9fa76e..17fa3ff 100644 ---- a/include/linux/vfs_compat.h -+++ b/include/linux/vfs_compat.h -@@ -149,4 +149,29 @@ typedef int zpl_umode_t; - #define zpl_sget(type, cmp, set, fl, mtd) sget(type, cmp, set, mtd) - #endif /* HAVE_5ARG_SGET */ - -+#define ZFS_IOC_GETFLAGS FS_IOC_GETFLAGS -+#define ZFS_IOC_SETFLAGS FS_IOC_SETFLAGS -+ -+#if defined(SEEK_HOLE) && defined(SEEK_DATA) && !defined(HAVE_LSEEK_EXECUTE) -+static inline loff_t -+lseek_execute(struct file *filp, struct inode *inode, -+ loff_t offset, loff_t maxsize) -+{ -+ if (offset < 0 && !(filp->f_mode & FMODE_UNSIGNED_OFFSET)) -+ return (-EINVAL); -+ -+ if (offset > maxsize) -+ return (-EINVAL); -+ -+ if (offset != filp->f_pos) { -+ spin_lock(&filp->f_lock); -+ filp->f_pos = offset; -+ filp->f_version = 0; -+ spin_unlock(&filp->f_lock); -+ } -+ -+ return (offset); -+} -+#endif /* SEEK_HOLE && SEEK_DATA && !HAVE_LSEEK_EXECUTE */ -+ - #endif /* _ZFS_VFS_H */ -diff --git a/include/sys/arc.h b/include/sys/arc.h -index dbc91ea..396144a 100644 ---- a/include/sys/arc.h -+++ b/include/sys/arc.h -@@ -20,6 +20,7 @@ - */ - /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2013 by Delphix. All rights reserved. - */ - - #ifndef _SYS_ARC_H -@@ -59,7 +60,6 @@ struct arc_buf { - arc_buf_hdr_t *b_hdr; - arc_buf_t *b_next; - kmutex_t b_evict_lock; -- krwlock_t b_data_lock; - void *b_data; - arc_evict_func_t *b_efunc; - void *b_private; -@@ -103,8 +103,6 @@ void arc_buf_add_ref(arc_buf_t *buf, void *tag); - int arc_buf_remove_ref(arc_buf_t *buf, void *tag); - int arc_buf_size(arc_buf_t *buf); - void arc_release(arc_buf_t *buf, void *tag); --int arc_release_bp(arc_buf_t *buf, void *tag, blkptr_t *bp, spa_t *spa, -- zbookmark_t *zb); - int arc_released(arc_buf_t *buf); - int arc_has_callback(arc_buf_t *buf); - void arc_buf_freeze(arc_buf_t *buf); -@@ -114,10 +112,7 @@ boolean_t arc_buf_eviction_needed(arc_buf_t *buf); - int arc_referenced(arc_buf_t *buf); - #endif - --int arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_buf_t *pbuf, -- arc_done_func_t *done, void *private, int priority, int zio_flags, -- uint32_t *arc_flags, const zbookmark_t *zb); --int arc_read_nolock(zio_t *pio, spa_t *spa, const blkptr_t *bp, -+int arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, - arc_done_func_t *done, void *private, int priority, int flags, - uint32_t *arc_flags, const zbookmark_t *zb); - zio_t *arc_write(zio_t *pio, spa_t *spa, uint64_t txg, -@@ -127,6 +122,7 @@ zio_t *arc_write(zio_t *pio, spa_t *spa, uint64_t txg, - - arc_prune_t *arc_add_prune_callback(arc_prune_func_t *func, void *private); - void arc_remove_prune_callback(arc_prune_t *p); -+void arc_freed(spa_t *spa, const blkptr_t *bp); - - void arc_set_callback(arc_buf_t *buf, arc_evict_func_t *func, void *private); - int arc_buf_evict(arc_buf_t *buf); -diff --git a/include/sys/dmu.h b/include/sys/dmu.h -index eb6a465..1785725 100644 ---- a/include/sys/dmu.h -+++ b/include/sys/dmu.h -@@ -410,7 +410,7 @@ void dmu_write_policy(objset_t *os, struct dnode *dn, int level, int wp, - * read db_data, dmu_buf_will_dirty() before modifying it, and the - * object must be held in an assigned transaction before calling - * dmu_buf_will_dirty. You may use dmu_buf_set_user() on the bonus -- * buffer as well. You must release your hold with dmu_buf_rele(). -+ * buffer as well. You must release what you hold with dmu_buf_rele(). - */ - int dmu_bonus_hold(objset_t *os, uint64_t object, void *tag, dmu_buf_t **); - int dmu_bonus_max(void); -@@ -432,8 +432,8 @@ int dmu_spill_hold_existing(dmu_buf_t *bonus, void *tag, dmu_buf_t **dbp); - * Obtain the DMU buffer from the specified object which contains the - * specified offset. dmu_buf_hold() puts a "hold" on the buffer, so - * that it will remain in memory. You must release the hold with -- * dmu_buf_rele(). You musn't access the dmu_buf_t after releasing your -- * hold. You must have a hold on any dmu_buf_t* you pass to the DMU. -+ * dmu_buf_rele(). You must not access the dmu_buf_t after releasing -+ * what you hold. You must have a hold on any dmu_buf_t* you pass to the DMU. - * - * You must call dmu_buf_read, dmu_buf_will_dirty, or dmu_buf_will_fill - * on the returned buffer before reading or writing the buffer's -diff --git a/include/sys/dmu_traverse.h b/include/sys/dmu_traverse.h -index 3cbf42f..bc1590b 100644 ---- a/include/sys/dmu_traverse.h -+++ b/include/sys/dmu_traverse.h -@@ -40,8 +40,7 @@ struct zilog; - struct arc_buf; - - typedef int (blkptr_cb_t)(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, -- struct arc_buf *pbuf, const zbookmark_t *zb, const struct dnode_phys *dnp, -- void *arg); -+ const zbookmark_t *zb, const struct dnode_phys *dnp, void *arg); - - #define TRAVERSE_PRE (1<<0) - #define TRAVERSE_POST (1<<1) -diff --git a/include/sys/dnode.h b/include/sys/dnode.h -index 9ad4be3..9f9134d 100644 ---- a/include/sys/dnode.h -+++ b/include/sys/dnode.h -@@ -20,6 +20,7 @@ - */ - /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2012 by Delphix. All rights reserved. - */ - - #ifndef _SYS_DNODE_H -@@ -276,7 +277,6 @@ void dnode_byteswap(dnode_phys_t *dnp); - void dnode_buf_byteswap(void *buf, size_t size); - void dnode_verify(dnode_t *dn); - int dnode_set_blksz(dnode_t *dn, uint64_t size, int ibs, dmu_tx_t *tx); --uint64_t dnode_current_max_length(dnode_t *dn); - void dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx); - void dnode_clear_range(dnode_t *dn, uint64_t blkid, - uint64_t nblks, dmu_tx_t *tx); -diff --git a/include/sys/dsl_pool.h b/include/sys/dsl_pool.h -index ff5df14..4a4bf76 100644 ---- a/include/sys/dsl_pool.h -+++ b/include/sys/dsl_pool.h -@@ -41,6 +41,8 @@ - extern "C" { - #endif - -+extern int zfs_txg_synctime_ms; -+ - struct objset; - struct dsl_dir; - struct dsl_dataset; -@@ -87,6 +89,7 @@ typedef struct dsl_pool { - uint64_t dp_root_dir_obj; - struct taskq *dp_iput_taskq; - kstat_t *dp_txg_kstat; -+ kstat_t *dp_tx_assign_kstat; - - /* No lock needed - sync context only */ - blkptr_t dp_meta_rootbp; -@@ -109,6 +112,8 @@ typedef struct dsl_pool { - uint64_t dp_mos_uncompressed_delta; - uint64_t dp_txg_history_size; - list_t dp_txg_history; -+ uint64_t dp_tx_assign_size; -+ kstat_named_t *dp_tx_assign_buckets; - - - /* Has its own locking */ -@@ -145,12 +150,6 @@ void dsl_pool_willuse_space(dsl_pool_t *dp, int64_t space, dmu_tx_t *tx); - void dsl_free(dsl_pool_t *dp, uint64_t txg, const blkptr_t *bpp); - void dsl_free_sync(zio_t *pio, dsl_pool_t *dp, uint64_t txg, - const blkptr_t *bpp); --int dsl_read(zio_t *pio, spa_t *spa, const blkptr_t *bpp, arc_buf_t *pbuf, -- arc_done_func_t *done, void *private, int priority, int zio_flags, -- uint32_t *arc_flags, const zbookmark_t *zb); --int dsl_read_nolock(zio_t *pio, spa_t *spa, const blkptr_t *bpp, -- arc_done_func_t *done, void *private, int priority, int zio_flags, -- uint32_t *arc_flags, const zbookmark_t *zb); - void dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx); - void dsl_pool_upgrade_clones(dsl_pool_t *dp, dmu_tx_t *tx); - void dsl_pool_upgrade_dir_clones(dsl_pool_t *dp, dmu_tx_t *tx); -@@ -166,6 +165,8 @@ extern int dsl_pool_user_release(dsl_pool_t *dp, uint64_t dsobj, - extern void dsl_pool_clean_tmp_userrefs(dsl_pool_t *dp); - int dsl_pool_open_special_dir(dsl_pool_t *dp, const char *name, dsl_dir_t **); - -+void dsl_pool_tx_assign_add_usecs(dsl_pool_t *dp, uint64_t usecs); -+ - txg_history_t *dsl_pool_txg_history_add(dsl_pool_t *dp, uint64_t txg); - txg_history_t *dsl_pool_txg_history_get(dsl_pool_t *dp, uint64_t txg); - void dsl_pool_txg_history_put(txg_history_t *th); -diff --git a/include/sys/fm/fs/zfs.h b/include/sys/fm/fs/zfs.h -index d5c6004..741b99e 100644 ---- a/include/sys/fm/fs/zfs.h -+++ b/include/sys/fm/fs/zfs.h -@@ -73,6 +73,8 @@ extern "C" { - #define FM_EREPORT_PAYLOAD_ZFS_VDEV_FRU "vdev_fru" - #define FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE "vdev_state" - #define FM_EREPORT_PAYLOAD_ZFS_VDEV_ASHIFT "vdev_ashift" -+#define FM_EREPORT_PAYLOAD_ZFS_VDEV_COMP_TS "vdev_complete_ts" -+#define FM_EREPORT_PAYLOAD_ZFS_VDEV_DELTA_TS "vdev_delta_ts" - #define FM_EREPORT_PAYLOAD_ZFS_PARENT_GUID "parent_guid" - #define FM_EREPORT_PAYLOAD_ZFS_PARENT_TYPE "parent_type" - #define FM_EREPORT_PAYLOAD_ZFS_PARENT_PATH "parent_path" -@@ -88,6 +90,9 @@ extern "C" { - #define FM_EREPORT_PAYLOAD_ZFS_ZIO_STAGE "zio_stage" - #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" -+#define FM_EREPORT_PAYLOAD_ZFS_ZIO_DEADLINE "zio_deadline" -+#define FM_EREPORT_PAYLOAD_ZFS_ZIO_DELTA "zio_delta" - #define FM_EREPORT_PAYLOAD_ZFS_PREV_STATE "prev_state" - #define FM_EREPORT_PAYLOAD_ZFS_CKSUM_EXPECTED "cksum_expected" - #define FM_EREPORT_PAYLOAD_ZFS_CKSUM_ACTUAL "cksum_actual" -diff --git a/include/sys/fs/zfs.h b/include/sys/fs/zfs.h -index 8c949e7..26c24fc 100644 ---- a/include/sys/fs/zfs.h -+++ b/include/sys/fs/zfs.h -@@ -63,7 +63,7 @@ typedef enum { - * Dataset properties are identified by these constants and must be added to - * the end of this list to ensure that external consumers are not affected - * by the change. If you make any changes to this list, be sure to update -- * the property table in usr/src/common/zfs/zfs_prop.c. -+ * the property table in module/zcommon/zfs_prop.c. - */ - typedef enum { - ZFS_PROP_TYPE, -@@ -146,7 +146,7 @@ extern const char *zfs_userquota_prop_prefixes[ZFS_NUM_USERQUOTA_PROPS]; - * Pool properties are identified by these constants and must be added to the - * end of this list to ensure that external consumers are not affected - * by the change. If you make any changes to this list, be sure to update -- * the property table in usr/src/common/zfs/zpool_prop.c. -+ * the property table in module/zcommon/zpool_prop.c. - */ - typedef enum { - ZPOOL_PROP_NAME, -diff --git a/include/sys/metaslab_impl.h b/include/sys/metaslab_impl.h -index 6583594..a36baed 100644 ---- a/include/sys/metaslab_impl.h -+++ b/include/sys/metaslab_impl.h -@@ -21,7 +21,10 @@ - /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. -- * Copyright (c) 2011 by Delphix. All rights reserved. -+ */ -+ -+/* -+ * Copyright (c) 2012 by Delphix. All rights reserved. - */ - - #ifndef _SYS_METASLAB_IMPL_H -@@ -64,20 +67,38 @@ struct metaslab_group { - }; - - /* -- * Each metaslab's free space is tracked in space map object in the MOS, -- * which is only updated in syncing context. Each time we sync a txg, -+ * Each metaslab maintains an in-core free map (ms_map) that contains the -+ * current list of free segments. As blocks are allocated, the allocated -+ * segment is removed from the ms_map and added to a per txg allocation map. -+ * As blocks are freed, they are added to the per txg free map. These per -+ * txg maps allow us to process all allocations and frees in syncing context -+ * where it is safe to update the on-disk space maps. -+ * -+ * Each metaslab's free space is tracked in a space map object in the MOS, -+ * which is only updated in syncing context. Each time we sync a txg, - * we append the allocs and frees from that txg to the space map object. - * When the txg is done syncing, metaslab_sync_done() updates ms_smo -- * to ms_smo_syncing. Everything in ms_smo is always safe to allocate. -+ * to ms_smo_syncing. Everything in ms_smo is always safe to allocate. -+ * -+ * To load the in-core free map we read the space map object from disk. -+ * This object contains a series of alloc and free records that are -+ * combined to make up the list of all free segments in this metaslab. These -+ * segments are represented in-core by the ms_map and are stored in an -+ * AVL tree. -+ * -+ * As the space map objects grows (as a result of the appends) it will -+ * eventually become space-inefficient. When the space map object is -+ * zfs_condense_pct/100 times the size of the minimal on-disk representation, -+ * we rewrite it in its minimized form. - */ - struct metaslab { - kmutex_t ms_lock; /* metaslab lock */ - space_map_obj_t ms_smo; /* synced space map object */ - space_map_obj_t ms_smo_syncing; /* syncing space map object */ -- space_map_t ms_allocmap[TXG_SIZE]; /* allocated this txg */ -- space_map_t ms_freemap[TXG_SIZE]; /* freed this txg */ -- space_map_t ms_defermap[TXG_DEFER_SIZE]; /* deferred frees */ -- space_map_t ms_map; /* in-core free space map */ -+ space_map_t *ms_allocmap[TXG_SIZE]; /* allocated this txg */ -+ space_map_t *ms_freemap[TXG_SIZE]; /* freed this txg */ -+ space_map_t *ms_defermap[TXG_DEFER_SIZE]; /* deferred frees */ -+ space_map_t *ms_map; /* in-core free space map */ - int64_t ms_deferspace; /* sum of ms_defermap[] space */ - uint64_t ms_weight; /* weight vs. others in group */ - metaslab_group_t *ms_group; /* metaslab group */ -diff --git a/include/sys/nvpair.h b/include/sys/nvpair.h -index cc399fd..c502568 100644 ---- a/include/sys/nvpair.h -+++ b/include/sys/nvpair.h -@@ -144,6 +144,7 @@ extern nv_alloc_t *nv_alloc_nosleep; - - #if defined(_KERNEL) && !defined(_BOOT) - extern nv_alloc_t *nv_alloc_sleep; -+extern nv_alloc_t *nv_alloc_pushpage; - #endif - - int nv_alloc_init(nv_alloc_t *, const nv_alloc_ops_t *, /* args */ ...); -diff --git a/include/sys/spa.h b/include/sys/spa.h -index 8211722..8f2af8a 100644 ---- a/include/sys/spa.h -+++ b/include/sys/spa.h -@@ -486,13 +486,7 @@ extern int spa_scan_stop(spa_t *spa); - extern void spa_sync(spa_t *spa, uint64_t txg); /* only for DMU use */ - extern void spa_sync_allpools(void); - --/* -- * DEFERRED_FREE must be large enough that regular blocks are not -- * deferred. XXX so can't we change it back to 1? -- */ --#define SYNC_PASS_DEFERRED_FREE 2 /* defer frees after this pass */ --#define SYNC_PASS_DONT_COMPRESS 4 /* don't compress after this pass */ --#define SYNC_PASS_REWRITE 1 /* rewrite new bps after this pass */ -+extern int zfs_sync_pass_deferred_free; - - /* spa namespace global mutex */ - extern kmutex_t spa_namespace_lock; -@@ -570,6 +564,7 @@ extern int spa_offline_log(spa_t *spa); - - /* Log claim callback */ - extern void spa_claim_notify(zio_t *zio); -+extern void spa_deadman(void *); - - /* Accessor functions */ - extern boolean_t spa_shutting_down(spa_t *spa); -@@ -604,6 +599,7 @@ extern boolean_t spa_suspended(spa_t *spa); - extern uint64_t spa_bootfs(spa_t *spa); - extern uint64_t spa_delegation(spa_t *spa); - extern objset_t *spa_meta_objset(spa_t *spa); -+extern uint64_t spa_deadman_synctime(spa_t *spa); - - /* Miscellaneous support routines */ - extern void spa_activate_mos_feature(spa_t *spa, const char *feature); -diff --git a/include/sys/spa_impl.h b/include/sys/spa_impl.h -index 65edc97..47dfe43 100644 ---- a/include/sys/spa_impl.h -+++ b/include/sys/spa_impl.h -@@ -80,16 +80,16 @@ typedef struct spa_config_dirent { - char *scd_path; - } spa_config_dirent_t; - --enum zio_taskq_type { -+typedef enum zio_taskq_type { - ZIO_TASKQ_ISSUE = 0, - ZIO_TASKQ_ISSUE_HIGH, - ZIO_TASKQ_INTERRUPT, - ZIO_TASKQ_INTERRUPT_HIGH, - ZIO_TASKQ_TYPES --}; -+} zio_taskq_type_t; - - /* -- * State machine for the zpool-pooname process. The states transitions -+ * State machine for the zpool-poolname process. The states transitions - * are done as follows: - * - * From To Routine -@@ -107,6 +107,11 @@ typedef enum spa_proc_state { - SPA_PROC_GONE /* spa_thread() is exiting, spa_proc = &p0 */ - } spa_proc_state_t; - -+typedef struct spa_taskqs { -+ uint_t stqs_count; -+ taskq_t **stqs_taskq; -+} spa_taskqs_t; -+ - struct spa { - /* - * Fields protected by spa_namespace_lock. -@@ -125,7 +130,7 @@ struct spa { - uint8_t spa_sync_on; /* sync threads are running */ - spa_load_state_t spa_load_state; /* current load operation */ - uint64_t spa_import_flags; /* import specific flags */ -- taskq_t *spa_zio_taskq[ZIO_TYPES][ZIO_TASKQ_TYPES]; -+ spa_taskqs_t spa_zio_taskq[ZIO_TYPES][ZIO_TASKQ_TYPES]; - dsl_pool_t *spa_dsl_pool; - boolean_t spa_is_initializing; /* true while opening pool */ - metaslab_class_t *spa_normal_class; /* normal data class */ -@@ -227,6 +232,10 @@ struct spa { - uint64_t spa_feat_for_write_obj; /* required to write to pool */ - uint64_t spa_feat_for_read_obj; /* required to read from pool */ - uint64_t spa_feat_desc_obj; /* Feature descriptions */ -+ taskqid_t spa_deadman_tqid; /* Task id */ -+ uint64_t spa_deadman_calls; /* number of deadman calls */ -+ uint64_t spa_sync_starttime; /* starting time fo spa_sync */ -+ uint64_t spa_deadman_synctime; /* deadman expiration timer */ - /* - * spa_refcnt & spa_config_lock must be the last elements - * because refcount_t changes size based on compilation options. -@@ -239,6 +248,12 @@ struct spa { - - extern char *spa_config_path; - -+extern void spa_taskq_dispatch_ent(spa_t *spa, zio_type_t t, zio_taskq_type_t q, -+ task_func_t *func, void *arg, uint_t flags, taskq_ent_t *ent); -+extern void spa_taskq_dispatch_sync(spa_t *, zio_type_t t, zio_taskq_type_t q, -+ task_func_t *func, void *arg, uint_t flags); -+ -+ - #ifdef __cplusplus - } - #endif -diff --git a/include/sys/space_map.h b/include/sys/space_map.h -index 3322997..2da80d2 100644 ---- a/include/sys/space_map.h -+++ b/include/sys/space_map.h -@@ -23,6 +23,10 @@ - * Use is subject to license terms. - */ - -+/* -+ * Copyright (c) 2012 by Delphix. All rights reserved. -+ */ -+ - #ifndef _SYS_SPACE_MAP_H - #define _SYS_SPACE_MAP_H - -@@ -36,17 +40,17 @@ extern "C" { - typedef const struct space_map_ops space_map_ops_t; - - typedef struct space_map { -- avl_tree_t sm_root; /* AVL tree of map segments */ -+ avl_tree_t sm_root; /* offset-ordered segment AVL tree */ - uint64_t sm_space; /* sum of all segments in the map */ - uint64_t sm_start; /* start of map */ - uint64_t sm_size; /* size of map */ - uint8_t sm_shift; /* unit shift */ -- uint8_t sm_pad[3]; /* unused */ - uint8_t sm_loaded; /* map loaded? */ - uint8_t sm_loading; /* map loading? */ -+ uint8_t sm_condensing; /* map condensing? */ - kcondvar_t sm_load_cv; /* map load completion */ - space_map_ops_t *sm_ops; /* space map block picker ops vector */ -- avl_tree_t *sm_pp_root; /* picker-private AVL tree */ -+ avl_tree_t *sm_pp_root; /* size-ordered, picker-private tree */ - void *sm_ppd; /* picker-private data */ - kmutex_t *sm_lock; /* pointer to lock that protects map */ - } space_map_t; -@@ -136,6 +140,8 @@ struct space_map_ops { - - typedef void space_map_func_t(space_map_t *sm, uint64_t start, uint64_t size); - -+extern void space_map_init(void); -+extern void space_map_fini(void); - extern void space_map_create(space_map_t *sm, uint64_t start, uint64_t size, - uint8_t shift, kmutex_t *lp); - extern void space_map_destroy(space_map_t *sm); -@@ -143,6 +149,7 @@ extern void space_map_add(space_map_t *sm, uint64_t start, uint64_t size); - extern void space_map_remove(space_map_t *sm, uint64_t start, uint64_t size); - extern boolean_t space_map_contains(space_map_t *sm, - uint64_t start, uint64_t size); -+extern void space_map_swap(space_map_t **msrc, space_map_t **mdest); - extern void space_map_vacate(space_map_t *sm, - space_map_func_t *func, space_map_t *mdest); - extern void space_map_walk(space_map_t *sm, -diff --git a/include/sys/vdev.h b/include/sys/vdev.h -index 8f297a9..f49086a 100644 ---- a/include/sys/vdev.h -+++ b/include/sys/vdev.h -@@ -78,6 +78,7 @@ extern void vdev_metaslab_fini(vdev_t *vd); - extern void vdev_metaslab_set_size(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); - - - extern void vdev_get_stats(vdev_t *vd, vdev_stat_t *vs); -diff --git a/include/sys/vdev_impl.h b/include/sys/vdev_impl.h -index 964ee24..711408e 100644 ---- a/include/sys/vdev_impl.h -+++ b/include/sys/vdev_impl.h -@@ -105,6 +105,8 @@ struct vdev_queue { - avl_tree_t vq_read_tree; - avl_tree_t vq_write_tree; - avl_tree_t vq_pending_tree; -+ uint64_t vq_io_complete_ts; -+ uint64_t vq_io_delta_ts; - list_t vq_io_list; - kmutex_t vq_lock; - }; -diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h -index 53080f3..4b34259 100644 ---- a/include/sys/zfs_context.h -+++ b/include/sys/zfs_context.h -@@ -25,6 +25,7 @@ - /* - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 2012, Joyent, Inc. All rights reserved. -+ * Copyright (c) 2012 by Delphix. All rights reserved. - */ - - #ifndef _SYS_ZFS_CONTEXT_H -@@ -71,7 +72,6 @@ - #define _SYS_RWLOCK_H - #define _SYS_CONDVAR_H - #define _SYS_SYSTM_H --#define _SYS_DEBUG_H - #define _SYS_T_LOCK_H - #define _SYS_VNODE_H - #define _SYS_VFS_H -@@ -111,6 +111,7 @@ - #include - #include - #include -+#include - - /* - * Stack -@@ -400,13 +401,17 @@ extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t); - #define taskq_create_sysdc(a, b, d, e, p, dc, f) \ - (taskq_create(a, b, maxclsyspri, d, e, f)) - extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t); -+extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *, uint_t, -+ clock_t); - extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t, - taskq_ent_t *); - extern int taskq_empty_ent(taskq_ent_t *); - extern void taskq_init_ent(taskq_ent_t *); - extern void taskq_destroy(taskq_t *); - extern void taskq_wait(taskq_t *); -+extern void taskq_wait_id(taskq_t *, taskqid_t); - extern int taskq_member(taskq_t *, kthread_t *); -+extern int taskq_cancel_id(taskq_t *, taskqid_t); - extern void system_taskq_init(void); - extern void system_taskq_fini(void); - -@@ -523,6 +528,11 @@ extern vnode_t *rootdir; - - 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 gethrestime_sec() time(NULL) - #define gethrestime(t) \ - do {\ -diff --git a/include/sys/zfs_ioctl.h b/include/sys/zfs_ioctl.h -index 740d8ed..c0cb470 100644 ---- a/include/sys/zfs_ioctl.h -+++ b/include/sys/zfs_ioctl.h -@@ -236,6 +236,8 @@ typedef struct zinject_record { - uint32_t zi_iotype; - int32_t zi_duration; - uint64_t zi_timer; -+ uint32_t zi_cmd; -+ uint32_t zi_pad; - } zinject_record_t; - - #define ZINJECT_NULL 0x1 -@@ -245,6 +247,16 @@ typedef struct zinject_record { - #define ZEVENT_NONBLOCK 0x1 - #define ZEVENT_SIZE 1024 - -+typedef enum zinject_type { -+ ZINJECT_UNINITIALIZED, -+ ZINJECT_DATA_FAULT, -+ ZINJECT_DEVICE_FAULT, -+ ZINJECT_LABEL_FAULT, -+ ZINJECT_IGNORED_WRITES, -+ ZINJECT_PANIC, -+ ZINJECT_DELAY_IO, -+} zinject_type_t; -+ - typedef struct zfs_share { - uint64_t z_exportdata; - uint64_t z_sharedata; -diff --git a/include/sys/zfs_vnops.h b/include/sys/zfs_vnops.h -index 5da5eaf..75f7c12 100644 ---- a/include/sys/zfs_vnops.h -+++ b/include/sys/zfs_vnops.h -@@ -38,6 +38,7 @@ extern "C" { - - extern int zfs_open(struct inode *ip, int mode, int flag, cred_t *cr); - extern int zfs_close(struct inode *ip, int flag, cred_t *cr); -+extern int zfs_holey(struct inode *ip, int cmd, loff_t *off); - extern int zfs_read(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr); - extern int zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr); - extern int zfs_access(struct inode *ip, int mode, int flag, cred_t *cr); -diff --git a/include/sys/zio.h b/include/sys/zio.h -index 64efde0..0353033 100644 ---- a/include/sys/zio.h -+++ b/include/sys/zio.h -@@ -21,8 +21,6 @@ - - /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. -- */ --/* - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. - * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. -@@ -411,7 +409,10 @@ struct zio { - const zio_vsd_ops_t *io_vsd_ops; - - uint64_t io_offset; -- uint64_t io_deadline; -+ uint64_t io_deadline; /* expires at timestamp + deadline */ -+ uint64_t io_timestamp; /* submitted at (ticks) */ -+ uint64_t io_delta; /* vdev queue service delta (ticks) */ -+ uint64_t io_delay; /* vdev disk service delta (ticks) */ - avl_node_t io_offset_node; - avl_node_t io_deadline_node; - avl_tree_t *io_vdev_tree; -@@ -423,7 +424,6 @@ struct zio { - enum zio_flag io_orig_flags; - enum zio_stage io_orig_stage; - enum zio_stage io_orig_pipeline; -- uint64_t io_delay; - int io_error; - int io_child_error[ZIO_CHILD_TYPES]; - uint64_t io_children[ZIO_CHILD_TYPES][ZIO_WAIT_TYPES]; -@@ -560,6 +560,7 @@ extern int zio_handle_fault_injection(zio_t *zio, int error); - extern int zio_handle_device_injection(vdev_t *vd, zio_t *zio, int error); - extern int zio_handle_label_injection(zio_t *zio, int error); - extern void zio_handle_ignored_writes(zio_t *zio); -+extern uint64_t zio_handle_io_delay(zio_t *zio); - - /* - * Checksum ereport functions -diff --git a/include/sys/zio_impl.h b/include/sys/zio_impl.h -index d90bd8b..2d062d0 100644 ---- a/include/sys/zio_impl.h -+++ b/include/sys/zio_impl.h -@@ -23,6 +23,10 @@ - * Use is subject to license terms. - */ - -+/* -+ * Copyright (c) 2012 by Delphix. All rights reserved. -+ */ -+ - #ifndef _ZIO_IMPL_H - #define _ZIO_IMPL_H - -@@ -143,6 +147,7 @@ enum zio_stage { - #define ZIO_FREE_PIPELINE \ - (ZIO_INTERLOCK_STAGES | \ - ZIO_STAGE_FREE_BP_INIT | \ -+ ZIO_STAGE_ISSUE_ASYNC | \ - ZIO_STAGE_DVA_FREE) - - #define ZIO_DDT_FREE_PIPELINE \ -diff --git a/lib/libshare/smb.c b/lib/libshare/smb.c -index e34d142..a545bfb 100644 ---- a/lib/libshare/smb.c -+++ b/lib/libshare/smb.c -@@ -423,7 +423,15 @@ static const sa_share_ops_t smb_shareops = { - static boolean_t - smb_available(void) - { -- /* TODO: Sanity check NET_CMD_PATH and SHARE_DIR */ -+ struct stat statbuf; -+ -+ if (lstat(SHARE_DIR, &statbuf) != 0 || -+ !S_ISDIR(statbuf.st_mode)) -+ return B_FALSE; -+ -+ if (access(NET_CMD_PATH, F_OK) != 0) -+ return B_FALSE; -+ - return B_TRUE; - } - -diff --git a/lib/libspl/include/assert.h b/lib/libspl/include/assert.h -index 7f145b8..3704165 100644 ---- a/lib/libspl/include/assert.h -+++ b/lib/libspl/include/assert.h -@@ -80,16 +80,19 @@ extern void __assert(const char *, const char *, int); - #define VERIFY3S(x, y, z) VERIFY3_IMPL(x, y, z, int64_t) - #define VERIFY3U(x, y, z) VERIFY3_IMPL(x, y, z, uint64_t) - #define VERIFY3P(x, y, z) VERIFY3_IMPL(x, y, z, uintptr_t) -+#define VERIFY0(x) VERIFY3_IMPL(x, ==, 0, uint64_t) - - #ifdef NDEBUG - #define ASSERT3S(x, y, z) ((void)0) - #define ASSERT3U(x, y, z) ((void)0) - #define ASSERT3P(x, y, z) ((void)0) -+#define ASSERT0(x) ((void)0) - #define ASSERTV(x) - #else - #define ASSERT3S(x, y, z) VERIFY3S(x, y, z) - #define ASSERT3U(x, y, z) VERIFY3U(x, y, z) - #define ASSERT3P(x, y, z) VERIFY3P(x, y, z) -+#define ASSERT0(x) VERIFY0(x) - #define ASSERTV(x) x - #endif /* NDEBUG */ - -diff --git a/lib/libspl/include/sys/mount.h b/lib/libspl/include/sys/mount.h -index 145e785..7b1e06b 100644 ---- a/lib/libspl/include/sys/mount.h -+++ b/lib/libspl/include/sys/mount.h -@@ -51,10 +51,10 @@ - #define MS_DIRSYNC S_WRITE - #endif - --#define MS_USERS 0x40000000 --#define MS_OWNER 0x10000000 --#define MS_GROUP 0x08000000 --#define MS_COMMENT 0x02000000 -+#define MS_USERS (MS_NOEXEC|MS_NOSUID|MS_NODEV) -+#define MS_OWNER (MS_NOSUID|MS_NODEV) -+#define MS_GROUP (MS_NOSUID|MS_NODEV) -+#define MS_COMMENT 0 - - /* - * Older glibc headers did not define all the available -diff --git a/lib/libspl/include/umem.h b/lib/libspl/include/umem.h -index 87db1f4..f102f66 100644 ---- a/lib/libspl/include/umem.h -+++ b/lib/libspl/include/umem.h -@@ -28,10 +28,10 @@ - #define _LIBSPL_UMEM_H - - /* XXX: We should use the real portable umem library if it is detected -- * at configure time. However, if the library is not available we can -+ * at configure time. However, if the library is not available, we can - * use a trivial malloc based implementation. This obviously impacts -- * performance but unless you using a full userspace build of zpool for -- * something other than ztest your likely not going to notice or care. -+ * performance, but unless you are using a full userspace build of zpool for -+ * something other than ztest, you are likely not going to notice or care. - * - * https://labs.omniti.com/trac/portableumem - */ -diff --git a/lib/libzfs/libzfs_import.c b/lib/libzfs/libzfs_import.c -index 3d80224..9e79bd9 100644 ---- a/lib/libzfs/libzfs_import.c -+++ b/lib/libzfs/libzfs_import.c -@@ -523,13 +523,12 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok) - * version - * pool guid - * name -- * pool txg (if available) - * comment (if available) - * pool state - * hostid (if available) - * hostname (if available) - */ -- uint64_t state, version, pool_txg; -+ uint64_t state, version; - char *comment = NULL; - - version = fnvlist_lookup_uint64(tmp, -@@ -545,11 +544,6 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok) - fnvlist_add_string(config, - ZPOOL_CONFIG_POOL_NAME, name); - -- if (nvlist_lookup_uint64(tmp, -- ZPOOL_CONFIG_POOL_TXG, &pool_txg) == 0) -- fnvlist_add_uint64(config, -- ZPOOL_CONFIG_POOL_TXG, pool_txg); -- - if (nvlist_lookup_string(tmp, - ZPOOL_CONFIG_COMMENT, &comment) == 0) - fnvlist_add_string(config, -@@ -868,7 +862,7 @@ zpool_read_label(int fd, nvlist_t **config) - - *config = NULL; - -- if (fstat64(fd, &statbuf) == -1) -+ if (fstat64_blk(fd, &statbuf) == -1) - return (0); - size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t); - -@@ -906,6 +900,36 @@ zpool_read_label(int fd, nvlist_t **config) - return (0); - } - -+/* -+ * Given a file descriptor, clear (zero) the label information. This function -+ * is used in the appliance stack as part of the ZFS sysevent module and -+ * to implement the "zpool labelclear" command. -+ */ -+int -+zpool_clear_label(int fd) -+{ -+ struct stat64 statbuf; -+ int l; -+ vdev_label_t *label; -+ uint64_t size; -+ -+ if (fstat64_blk(fd, &statbuf) == -1) -+ return (0); -+ size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t); -+ -+ if ((label = calloc(sizeof (vdev_label_t), 1)) == NULL) -+ return (-1); -+ -+ for (l = 0; l < VDEV_LABELS; l++) { -+ if (pwrite64(fd, label, sizeof (vdev_label_t), -+ label_offset(size, l)) != sizeof (vdev_label_t)) -+ return (-1); -+ } -+ -+ free(label); -+ return (0); -+} -+ - #ifdef HAVE_LIBBLKID - /* - * Use libblkid to quickly search for zfs devices -diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c -index eca1dc3..a6cacd3 100644 ---- a/lib/libzfs/libzfs_pool.c -+++ b/lib/libzfs/libzfs_pool.c -@@ -205,6 +205,36 @@ zpool_state_to_name(vdev_state_t state, vdev_aux_t aux) - } - - /* -+ * Map POOL STATE to printed strings. -+ */ -+const char * -+zpool_pool_state_to_name(pool_state_t state) -+{ -+ switch (state) { -+ default: -+ break; -+ case POOL_STATE_ACTIVE: -+ return (gettext("ACTIVE")); -+ case POOL_STATE_EXPORTED: -+ return (gettext("EXPORTED")); -+ case POOL_STATE_DESTROYED: -+ return (gettext("DESTROYED")); -+ case POOL_STATE_SPARE: -+ return (gettext("SPARE")); -+ case POOL_STATE_L2CACHE: -+ return (gettext("L2CACHE")); -+ case POOL_STATE_UNINITIALIZED: -+ return (gettext("UNINITIALIZED")); -+ case POOL_STATE_UNAVAIL: -+ return (gettext("UNAVAIL")); -+ case POOL_STATE_POTENTIALLY_ACTIVE: -+ return (gettext("POTENTIALLY_ACTIVE")); -+ } -+ -+ return (gettext("UNKNOWN")); -+} -+ -+/* - * Get a zpool property value for 'prop' and return the value in - * a pre-allocated buffer. - */ -diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c -index a4e1255..5bb88e9 100644 ---- a/lib/libzfs/libzfs_util.c -+++ b/lib/libzfs/libzfs_util.c -@@ -704,6 +704,8 @@ libzfs_init(void) - if ((hdl->libzfs_mnttab = fopen(MNTTAB, "r")) == NULL) { - #endif - (void) close(hdl->libzfs_fd); -+ (void) fprintf(stderr, -+ gettext("mtab is not present at %s.\n"), MNTTAB); - free(hdl); - return (NULL); - } -diff --git a/lib/libzpool/kernel.c b/lib/libzpool/kernel.c -index c1ce82d..f7aeeb4 100644 ---- a/lib/libzpool/kernel.c -+++ b/lib/libzpool/kernel.c -@@ -522,7 +522,7 @@ vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3) - { - int fd; - vnode_t *vp; -- int old_umask; -+ int old_umask = 0; - char *realpath; - struct stat64 st; - int err; -diff --git a/lib/libzpool/taskq.c b/lib/libzpool/taskq.c -index 803f7dc..96c0d5c 100644 ---- a/lib/libzpool/taskq.c -+++ b/lib/libzpool/taskq.c -@@ -147,6 +147,13 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags) - return (1); - } - -+taskqid_t -+taskq_dispatch_delay(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags, -+ clock_t expire_time) -+{ -+ return (0); -+} -+ - int - taskq_empty_ent(taskq_ent_t *t) - { -@@ -204,6 +211,12 @@ taskq_wait(taskq_t *tq) - mutex_exit(&tq->tq_lock); - } - -+void -+taskq_wait_id(taskq_t *tq, taskqid_t id) -+{ -+ taskq_wait(tq); -+} -+ - static void - taskq_thread(void *arg) - { -@@ -339,6 +352,12 @@ taskq_member(taskq_t *tq, kthread_t *t) - return (0); - } - -+int -+taskq_cancel_id(taskq_t *tq, taskqid_t id) -+{ -+ return (ENOENT); -+} -+ - void - system_taskq_init(void) - { -diff --git a/man/man8/zdb.8 b/man/man8/zdb.8 -index 3ce3265..364cf30 100644 ---- a/man/man8/zdb.8 -+++ b/man/man8/zdb.8 -@@ -11,6 +11,7 @@ - .\" - .\" - .\" Copyright 2012, Richard Lowe. -+.\" Copyright (c) 2012 by Delphix. All rights reserved. - .\" - .TH "ZDB" "8" "February 15, 2012" "" "" - -@@ -19,21 +20,23 @@ - - .SH "SYNOPSIS" - \fBzdb\fR [-CumdibcsDvhLXFPA] [-e [-p \fIpath\fR...]] [-t \fItxg\fR] -- \fIpoolname\fR [\fIobject\fR ...] -+ [-U \fIcache\fR] [-M \fIinflight I/Os\fR] [\fIpoolname\fR -+ [\fIobject\fR ...]] - - .P --\fBzdb\fR [-divPA] [-e [-p \fIpath\fR...]] \fIdataset\fR [\fIobject\fR ...] -+\fBzdb\fR [-divPA] [-e [-p \fIpath\fR...]] [-U \fIcache\fR] -+ \fIdataset\fR [\fIobject\fR ...] - - .P --\fBzdb\fR -m [-LXFPA] [-t \fItxg\fR] [-e [-p \fIpath\fR...]] \fIpoolname\fR -- [\fIvdev\fR [\fImetaslab\fR ...]] -+\fBzdb\fR -m [-LXFPA] [-t \fItxg\fR] [-e [-p \fIpath\fR...]] [-U \fIcache\fR] -+ \fIpoolname\fR [\fIvdev\fR [\fImetaslab\fR ...]] - - .P --\fBzdb\fR -R [-A] [-e [-p \fIpath\fR...]] \fIpoolname\fR -+\fBzdb\fR -R [-A] [-e [-p \fIpath\fR...]] [-U \fIcache\fR] \fIpoolname\fR - \fIvdev\fR:\fIoffset\fR:\fIsize\fR[:\fIflags\fR] - - .P --\fBzdb\fR -S [-AP] [-e [-p \fIpath\fR...]] \fIpoolname\fR -+\fBzdb\fR -S [-AP] [-e [-p \fIpath\fR...]] [-U \fIcache\fR] \fIpoolname\fR - - .P - \fBzdb\fR -l [-uA] \fIdevice\fR -@@ -357,6 +360,18 @@ transactions. - .sp - .ne 2 - .na -+\fB-M \fIinflight I/Os\fR \fR -+.ad -+.sp .6 -+.RS 4n -+Limit the number of outstanding checksum I/Os to the specified value. The -+default value is 200. This option affects the performance of the \fB-c\fR -+option. -+.RE -+ -+.sp -+.ne 2 -+.na - \fB-P\fR - .ad - .sp .6 -@@ -384,8 +399,7 @@ and their associated transaction numbers. - .ad - .sp .6 - .RS 4n --Use a cache file other than \fB/etc/zfs/zpool.cache\fR. This option is only --valid with \fB-C\fR -+Use a cache file other than \fB/etc/zfs/zpool.cache\fR. - .RE - - .sp -diff --git a/man/man8/zfs.8 b/man/man8/zfs.8 -index 3bf14e9..b91158e 100644 ---- a/man/man8/zfs.8 -+++ b/man/man8/zfs.8 -@@ -1042,7 +1042,17 @@ Because \fBSMB\fR shares requires a resource name, a unique resource name is con - .sp - If the \fBsharesmb\fR property is set to \fBoff\fR, the file systems are unshared. - .sp --In Linux, the share is created with the acl "Everyone:F" by default, meaning that everyone have read access. This however isn't the full truth: Any access control on the underlaying filesystem supersedes this. -+In Linux, the share is created with the ACL (Access Control List) "Everyone:F" ("F" stands for "full permissions", ie. read and write permissions) and no guest access (which means samba must be able to authenticate a real user, system passwd/shadow, ldap or smbpasswd based) by default. This means that any additional access control (dissalow specific user specific access etc) must be done on the underlaying filesystem. -+.sp -+.in +2 -+Example to mount a SMB filesystem shared through ZFS (share/tmp): -+.mk -+Note that a user and his/her password \fBmust\fR be given! -+.sp -+.in +2 -+smbmount //127.0.0.1/share_tmp /mnt/tmp -o user=workgroup/turbo,password=obrut,uid=1000 -+.in -2 -+.in -2 - .sp - .ne 2 - .mk -@@ -1052,7 +1062,9 @@ In Linux, the share is created with the acl "Everyone:F" by default, meaning tha - .in +2 - * Samba will need to listen to 'localhost' (127.0.0.1) for the zfs utilities to communitate with samba. This is the default behavior for most Linux distributions. - .sp --* See the \fBUSERSHARE\fR section of the \fBsmb.conf\fR(5) man page for all configuration options. -+* Samba must be able to authenticate a user. This can be done in a number of ways, depending on if using the system password file, LDAP or the Samba specific smbpasswd file. How to do this is outside the scope of this manual. Please refer to the smb.conf(5) manpage for more information. -+.sp -+* See the \fBUSERSHARE\fR section of the \fBsmb.conf\fR(5) man page for all configuration options in case you need to modify any options to the share afterwards. Do note that any changes done with the 'net' command will be undone if the share is every unshared (such as at a reboot etc). In the future, ZoL will be able to set specific options directly using sharesmb=