You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
archzfs/spl/spl_git_head.patch

1044 lines
34 KiB

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 <linux/vmalloc.h>
+ 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 <linux/proc_fs.h>
+ ], [
+ 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 <cdunlap@llnl.gov>.
-# Modified by Brian Behlendorf <behlendorf1@llnl.gov>.
-###############################################################################
-# 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 <cdunlap@llnl.gov>.
+dnl # Modified by Brian Behlendorf <behlendorf1@llnl.gov>.
+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 # <www.gnu.org/software/autoconf/manual/autoconf.html#Quadrigraphs>
+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 <sys/atomic.h>
#include <sys/thread.h>
+#include <linux/slab.h>
#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 <sys/thread.h>
#include <sys/random.h>
+#include <linux/slab.h>
#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 <sys/time.h>
+#include <linux/slab.h>
#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 <dir> -- look for our shared files in <dir>"
echo " --filterfile <file> -- filter the results with grep --file <file>"
echo " --for-kernels <list> -- created templates only for these kernels"
echo " --kmodname <file> -- name of the kmod (required)"
@@ -390,6 +390,7 @@ myprog_help ()
echo " --noakmod -- no akmod package"
echo " --repo <name> -- use buildsys-build-<name>-kerneldevpkgs"
echo " --target <arch> -- target-arch (required)"
+ echo " --buildroot <dir> -- 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