diff options
author | behlendo <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c> | 2008-03-11 20:54:40 +0000 |
---|---|---|
committer | behlendo <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c> | 2008-03-11 20:54:40 +0000 |
commit | 9490c148359332d797e4fc250812bd7a5fd131b1 (patch) | |
tree | bb7678f0216623d6a3743ac8c34c61215b6b97ab /include | |
parent | b123971fc2f951cc95c8f75db68adf05d3a1d1aa (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.h | 2 | ||||
-rw-r--r-- | include/sys/kidmap.h | 4 | ||||
-rw-r--r-- | include/sys/kobj.h | 29 | ||||
-rw-r--r-- | include/sys/rwlock.h | 71 | ||||
-rw-r--r-- | include/sys/sid.h | 4 | ||||
-rw-r--r-- | include/sys/sysmacros.h | 1 | ||||
-rw-r--r-- | include/sys/utsname.h | 8 | ||||
-rw-r--r-- | include/sys/vfs.h | 4 |
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 */ |