From: wangdi Date: Sat, 21 Oct 2006 05:12:46 +0000 (+0000) Subject: Branch b_new_cmd X-Git-Tag: v1_8_0_110~486^2~409 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=af725bfa77c9804180029dd5253e631058cf3ceb;p=fs%2Flustre-release.git Branch b_new_cmd add dynamic-locks to 2.6-fc3 series --- diff --git a/lustre/kernel_patches/patches/dynamic-locks-2.6-fc3.patch b/lustre/kernel_patches/patches/dynamic-locks-2.6-fc3.patch new file mode 100644 index 0000000..426af25 --- /dev/null +++ b/lustre/kernel_patches/patches/dynamic-locks-2.6-fc3.patch @@ -0,0 +1,288 @@ + include/linux/dynlocks.h | 33 ++++++++++ + lib/Makefile | 4 - + lib/dynlocks.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 187 insertions(+), 2 deletions(-) + +Index: linux-2.6.10/fs/dcache.c +=================================================================== +--- linux-2.6.10.orig/fs/dcache.c 2006-10-21 11:52:54.000000000 +0800 ++++ linux-2.6.10/fs/dcache.c 2006-10-21 13:04:55.000000000 +0800 +@@ -1664,6 +1664,7 @@ + + extern void bdev_cache_init(void); + extern void chrdev_init(void); ++extern void dynlock_cache_init(void); + + void __init vfs_caches_init_early(void) + { +@@ -1693,6 +1694,7 @@ + mnt_init(mempages); + bdev_cache_init(); + chrdev_init(); ++ dynlock_cache_init(); + } + + EXPORT_SYMBOL(d_alloc); +Index: linux-2.6.10/include/linux/dynlocks.h +=================================================================== +--- linux-2.6.10.orig/include/linux/dynlocks.h 2006-05-31 09:15:07.000000000 +0800 ++++ linux-2.6.10/include/linux/dynlocks.h 2006-10-21 13:04:55.000000000 +0800 +@@ -0,0 +1,37 @@ ++#ifndef _LINUX_DYNLOCKS_H ++#define _LINUX_DYNLOCKS_H ++ ++#include ++#include ++ ++#define DYNLOCK_MAGIC 0xd19a10c ++#define DYNLOCK_MAGIC2 0xd1956ee ++ ++struct dynlock; ++struct dynlock_handle; ++ ++/* ++ * lock's namespace: ++ * - list of locks ++ * - lock to protect this list ++ */ ++ ++struct dynlock { ++ unsigned dl_magic; ++ struct list_head dl_list; ++ spinlock_t dl_list_lock; ++}; ++ ++enum dynlock_type { ++ DLT_NONE, ++ DLT_WRITE, ++ DLT_READ ++}; ++ ++void dynlock_init(struct dynlock *dl); ++struct dynlock_handle *dynlock_lock(struct dynlock *dl, unsigned long value, ++ enum dynlock_type lt, int gfp); ++void dynlock_unlock(struct dynlock *dl, struct dynlock_handle *lock); ++ ++#endif ++ +Index: linux-2.6.10/lib/Makefile +=================================================================== +--- linux-2.6.10.orig/lib/Makefile 2004-12-25 05:33:50.000000000 +0800 ++++ linux-2.6.10/lib/Makefile 2006-10-21 13:08:20.000000000 +0800 +@@ -5,7 +5,7 @@ + lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \ + bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \ + kobject.o kref.o idr.o div64.o parser.o int_sqrt.o \ +- bitmap.o extable.o kobject_uevent.o ++ bitmap.o extable.o kobject_uevent.o dynlocks.o + + ifeq ($(CONFIG_DEBUG_KOBJECT),y) + CFLAGS_kobject.o += -DDEBUG +Index: linux-2.6.10/lib/dynlocks.c +=================================================================== +--- linux-2.6.10.orig/lib/dynlocks.c 2006-05-31 09:15:07.000000000 +0800 ++++ linux-2.6.10/lib/dynlocks.c 2006-10-21 13:04:55.000000000 +0800 +@@ -0,0 +1,203 @@ ++/* ++ * Dynamic Locks ++ * ++ * struct dynlock is lockspace ++ * one may request lock (exclusive or shared) for some value ++ * in that lockspace ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++static kmem_cache_t * dynlock_cachep = NULL; ++ ++struct dynlock_handle { ++ unsigned dl_magic; ++ struct list_head dl_list; ++ unsigned long dl_value; /* lock value */ ++ int dl_refcount; /* number of users */ ++ int dl_readers; ++ int dl_writers; ++ int dl_pid; /* holder of the lock */ ++ wait_queue_head_t dl_wait; ++}; ++ ++#define DYNLOCK_LIST_MAGIC 0x11ee91e6 ++ ++void __init dynlock_cache_init(void) ++{ ++ printk(KERN_INFO "init dynlocks cache\n"); ++ dynlock_cachep = kmem_cache_create("dynlock_cache", ++ sizeof(struct dynlock_handle), ++ 0, ++ SLAB_HWCACHE_ALIGN, ++ NULL, NULL); ++ if (dynlock_cachep == NULL) ++ panic("Can't create dynlock cache"); ++} ++ ++/* ++ * dynlock_init ++ * ++ * initialize lockspace ++ * ++ */ ++void dynlock_init(struct dynlock *dl) ++{ ++ spin_lock_init(&dl->dl_list_lock); ++ INIT_LIST_HEAD(&dl->dl_list); ++ dl->dl_magic = DYNLOCK_LIST_MAGIC; ++} ++ ++/* ++ * dynlock_lock ++ * ++ * acquires lock (exclusive or shared) in specified lockspace ++ * each lock in lockspace is allocated separately, so user have ++ * to specify GFP flags. ++ * routine returns pointer to lock. this pointer is intended to ++ * be passed to dynlock_unlock ++ * ++ */ ++struct dynlock_handle *dynlock_lock(struct dynlock *dl, unsigned long value, ++ enum dynlock_type lt, int gfp) ++{ ++ struct dynlock_handle *nhl = NULL; ++ struct dynlock_handle *hl; ++ struct list_head *cur; ++ int num = 0; ++ ++ BUG_ON(dl == NULL); ++ BUG_ON(dl->dl_magic != DYNLOCK_LIST_MAGIC); ++ ++ if (lt == DLT_NONE) ++ return NULL; ++repeat: ++ /* find requested lock in lockspace */ ++ spin_lock(&dl->dl_list_lock); ++ BUG_ON(dl->dl_list.next == NULL); ++ BUG_ON(dl->dl_list.prev == NULL); ++ list_for_each(cur, &dl->dl_list) { ++ BUG_ON(cur->next == NULL); ++ BUG_ON(cur->prev == NULL); ++ hl = list_entry(cur, struct dynlock_handle, dl_list); ++ BUG_ON(hl->dl_magic != DYNLOCK_MAGIC); ++ if (hl->dl_value == value) { ++ /* lock is found */ ++ if (nhl) { ++ /* someone else just allocated ++ * lock we didn't find and just created ++ * so, we drop our lock ++ */ ++ kmem_cache_free(dynlock_cachep, nhl); ++ nhl = NULL; ++ } ++ hl->dl_refcount++; ++ goto found; ++ } ++ num++; ++ } ++ /* lock not found */ ++ if (nhl) { ++ /* we already have allocated lock. use it */ ++ hl = nhl; ++ nhl = NULL; ++ list_add(&hl->dl_list, &dl->dl_list); ++ goto found; ++ } ++ spin_unlock(&dl->dl_list_lock); ++ ++ /* lock not found and we haven't allocated lock yet. allocate it */ ++ nhl = kmem_cache_alloc(dynlock_cachep, gfp); ++ if (nhl == NULL) ++ return NULL; ++ nhl->dl_refcount = 1; ++ nhl->dl_value = value; ++ nhl->dl_readers = 0; ++ nhl->dl_writers = 0; ++ nhl->dl_magic = DYNLOCK_MAGIC; ++ init_waitqueue_head(&nhl->dl_wait); ++ ++ /* while lock is being allocated, someone else may allocate it ++ * and put onto to list. check this situation ++ */ ++ goto repeat; ++ ++found: ++ if (lt == DLT_WRITE) { ++ /* exclusive lock: user don't want to share lock at all ++ * NOTE: one process may take the same lock several times ++ * this functionaly is useful for rename operations */ ++ while ((hl->dl_writers && hl->dl_pid != current->pid) || ++ hl->dl_readers) { ++ spin_unlock(&dl->dl_list_lock); ++ wait_event(hl->dl_wait, ++ hl->dl_writers == 0 && hl->dl_readers == 0); ++ spin_lock(&dl->dl_list_lock); ++ } ++ hl->dl_writers++; ++ } else { ++ /* shared lock: user do not want to share lock with writer */ ++ while (hl->dl_writers) { ++ spin_unlock(&dl->dl_list_lock); ++ wait_event(hl->dl_wait, hl->dl_writers == 0); ++ spin_lock(&dl->dl_list_lock); ++ } ++ hl->dl_readers++; ++ } ++ hl->dl_pid = current->pid; ++ spin_unlock(&dl->dl_list_lock); ++ ++ return hl; ++} ++ ++ ++/* ++ * dynlock_unlock ++ * ++ * user have to specify lockspace (dl) and pointer to lock structure ++ * returned by dynlock_lock() ++ * ++ */ ++void dynlock_unlock(struct dynlock *dl, struct dynlock_handle *hl) ++{ ++ int wakeup = 0; ++ ++ BUG_ON(dl == NULL); ++ BUG_ON(hl == NULL); ++ BUG_ON(dl->dl_magic != DYNLOCK_LIST_MAGIC); ++ BUG_ON(hl->dl_magic != DYNLOCK_MAGIC); ++ BUG_ON(current->pid != hl->dl_pid); ++ ++ spin_lock(&dl->dl_list_lock); ++ if (hl->dl_writers) { ++ BUG_ON(hl->dl_readers > 0 || hl->dl_readers < 0); ++ hl->dl_writers--; ++ if (hl->dl_writers == 0) ++ wakeup = 1; ++ } else if (hl->dl_readers) { ++ hl->dl_readers--; ++ if (hl->dl_readers == 0) ++ wakeup = 1; ++ } else { ++ BUG_ON(1); ++ } ++ if (wakeup) { ++ hl->dl_pid = 0; ++ wake_up(&hl->dl_wait); ++ } ++ if (--(hl->dl_refcount) == 0) { ++ hl->dl_magic = DYNLOCK_MAGIC2; ++ list_del(&hl->dl_list); ++ kmem_cache_free(dynlock_cachep, hl); ++ } ++ spin_unlock(&dl->dl_list_lock); ++} ++ ++EXPORT_SYMBOL(dynlock_init); ++EXPORT_SYMBOL(dynlock_lock); ++EXPORT_SYMBOL(dynlock_unlock); ++ diff --git a/lustre/kernel_patches/series/2.6-fc3.series b/lustre/kernel_patches/series/2.6-fc3.series index 7204056..d21108e 100644 --- a/lustre/kernel_patches/series/2.6-fc3.series +++ b/lustre/kernel_patches/series/2.6-fc3.series @@ -22,4 +22,4 @@ uml-exprt-clearuser.patch fsprivate-2.6.patch linux-2.6.9-ext3-sub-second-timestamp.patch bitops_ext2_find_next_le_bit-2.6.patch -dynamic-locks-2.6.9.patch +dynamic-locks-2.6-fc3.patch