summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorbehlendo <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c>2008-03-11 20:54:40 +0000
committerbehlendo <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c>2008-03-11 20:54:40 +0000
commit9490c148359332d797e4fc250812bd7a5fd131b1 (patch)
treebb7678f0216623d6a3743ac8c34c61215b6b97ab /include
parentb123971fc2f951cc95c8f75db68adf05d3a1d1aa (diff)
Apply fix from bug239 for rwlock deadlock.
Update check.sh script to take V=1 env var so you can run it verbosely as follows if your chasing something: sudo make check V=1 Add new kobj api and needed regression tests to allow reading of files from within the kernel. Normally thats not something I support but the spa layer needs the support for its config file. Add some more missing stub headers git-svn-id: https://outreach.scidac.gov/svn/spl/trunk@38 7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c
Diffstat (limited to 'include')
-rw-r--r--include/sys/cred.h2
-rw-r--r--include/sys/kidmap.h4
-rw-r--r--include/sys/kobj.h29
-rw-r--r--include/sys/rwlock.h71
-rw-r--r--include/sys/sid.h4
-rw-r--r--include/sys/sysmacros.h1
-rw-r--r--include/sys/utsname.h8
-rw-r--r--include/sys/vfs.h4
8 files changed, 120 insertions, 3 deletions
diff --git a/include/sys/cred.h b/include/sys/cred.h
index 401f3130a..5ed233b0b 100644
--- a/include/sys/cred.h
+++ b/include/sys/cred.h
@@ -6,7 +6,7 @@ extern "C" {
#endif
#include <linux/module.h>
-#include <linux/types.h>
+#include <sys/types.h>
/* XXX - Portions commented out because we really just want to have the type
* defined and the contents aren't nearly so important at the moment. */
diff --git a/include/sys/kidmap.h b/include/sys/kidmap.h
new file mode 100644
index 000000000..d1c8d913f
--- /dev/null
+++ b/include/sys/kidmap.h
@@ -0,0 +1,4 @@
+#ifndef _SPL_KIDMAP_H
+#define _SPL_KIDMAP_H
+
+#endif /* SPL_KIDMAP_H */
diff --git a/include/sys/kobj.h b/include/sys/kobj.h
new file mode 100644
index 000000000..306fcdcfc
--- /dev/null
+++ b/include/sys/kobj.h
@@ -0,0 +1,29 @@
+#ifndef _SPL_KOBJ_H
+#define _SPL_KOBJ_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <sys/types.h>
+#include <sys/kmem.h>
+
+typedef struct _buf {
+ struct file *fp;
+} _buf_t;
+
+extern void *rootdir;
+
+extern struct _buf *kobj_open_file(const char *name);
+extern void kobj_close_file(struct _buf *file);
+extern int kobj_read_file(struct _buf *file, char *buf,
+ unsigned size, unsigned off);
+extern int kobj_get_filesize(struct _buf *file, uint64_t *size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SPL_KOBJ_H */
diff --git a/include/sys/rwlock.h b/include/sys/rwlock.h
index 4498e9562..ecee07948 100644
--- a/include/sys/rwlock.h
+++ b/include/sys/rwlock.h
@@ -36,6 +36,65 @@ typedef struct {
struct task_struct *rw_owner; /* holder of the write lock */
} krwlock_t;
+#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK
+struct rwsem_waiter {
+ struct list_head list;
+ struct task_struct *task;
+ unsigned int flags;
+#define RWSEM_WAITING_FOR_READ 0x00000001
+#define RWSEM_WAITING_FOR_WRITE 0x00000002
+};
+
+/*
+ * wake a single writer
+ */
+static inline struct rw_semaphore *
+__rwsem_wake_one_writer_locked(struct rw_semaphore *sem)
+{
+ struct rwsem_waiter *waiter;
+ struct task_struct *tsk;
+
+ sem->activity = -1;
+
+ waiter = list_entry(sem->wait_list.next, struct rwsem_waiter, list);
+ list_del(&waiter->list);
+
+ tsk = waiter->task;
+ smp_mb();
+ waiter->task = NULL;
+ wake_up_process(tsk);
+ put_task_struct(tsk);
+ return sem;
+}
+
+/*
+ * release a read lock on the semaphore
+ */
+static void fastcall
+__up_read_locked(struct rw_semaphore *sem)
+{
+ if (--sem->activity == 0 && !list_empty(&sem->wait_list))
+ sem = __rwsem_wake_one_writer_locked(sem);
+}
+
+/*
+ * trylock for writing -- returns 1 if successful, 0 if contention
+ */
+static int fastcall
+__down_write_trylock_locked(struct rw_semaphore *sem)
+{
+ int ret = 0;
+
+ if (sem->activity == 0 && list_empty(&sem->wait_list)) {
+ /* granted */
+ sem->activity = -1;
+ ret = 1;
+ }
+
+ return ret;
+}
+#endif
+
extern int __rw_read_held(krwlock_t *rwlp);
extern int __rw_write_held(krwlock_t *rwlp);
extern int __rw_lock_held(krwlock_t *rwlp);
@@ -168,7 +227,7 @@ rw_downgrade(krwlock_t *rwlp)
static __inline__ int
rw_tryupgrade(krwlock_t *rwlp)
{
- int result;
+ int result = 0;
BUG_ON(rwlp->rw_magic != RW_MAGIC);
spin_lock(&rwlp->rw_sem.wait_lock);
@@ -197,6 +256,15 @@ rw_tryupgrade(krwlock_t *rwlp)
return 0;
}
+#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK
+ /* Here it should be safe to drop the
+ * read lock and reacquire it for writing since
+ * we know there are no waiters */
+ __up_read_locked(&rwlp->rw_sem);
+
+ /* returns 1 if success, 0 if contention */
+ result = __down_write_trylock_locked(&rwlp->rw_sem);
+#else
/* Here it should be safe to drop the
* read lock and reacquire it for writing since
* we know there are no waiters */
@@ -204,6 +272,7 @@ rw_tryupgrade(krwlock_t *rwlp)
/* returns 1 if success, 0 if contention */
result = down_write_trylock(&rwlp->rw_sem);
+#endif
/* Check if upgrade failed. Should not ever happen
* if we got to this point */
diff --git a/include/sys/sid.h b/include/sys/sid.h
new file mode 100644
index 000000000..937a71ea8
--- /dev/null
+++ b/include/sys/sid.h
@@ -0,0 +1,4 @@
+#ifndef _SPL_SID_H
+#define _SPL_SID_H
+
+#endif /* SPL_SID_H */
diff --git a/include/sys/sysmacros.h b/include/sys/sysmacros.h
index 3f559bd0b..218f59567 100644
--- a/include/sys/sysmacros.h
+++ b/include/sys/sysmacros.h
@@ -135,7 +135,6 @@ extern int highbit(unsigned long i);
#define makedevice(maj,min) makedev(maj,min)
#define zone_dataset_visible(x, y) (1)
#define INGLOBALZONE(z) (1)
-#define utsname system_utsname
/* XXX - Borrowed from zfs project libsolcompat/include/sys/sysmacros.h */
/* common macros */
diff --git a/include/sys/utsname.h b/include/sys/utsname.h
new file mode 100644
index 000000000..7b1563d4b
--- /dev/null
+++ b/include/sys/utsname.h
@@ -0,0 +1,8 @@
+#ifndef _SPL_UTSNAME_H
+#define _SPL_UTSNAME_H
+
+#include <linux/utsname.h>
+
+#define utsname system_utsname
+
+#endif /* SPL_UTSNAME_H */
diff --git a/include/sys/vfs.h b/include/sys/vfs.h
index 134f4b6bf..6bc0a42ae 100644
--- a/include/sys/vfs.h
+++ b/include/sys/vfs.h
@@ -1,4 +1,8 @@
#ifndef _SPL_ZFS_H
#define _SPL_ZFS_H
+typedef struct vfs_s {
+ int foo;
+} vfs_t;
+
#endif /* SPL_ZFS_H */