X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=ldiskfs%2Fkernel_patches%2Fpatches%2Frhel6.3%2Fext4-dynlocks-common.patch;fp=ldiskfs%2Fkernel_patches%2Fpatches%2Frhel6.3%2Fext4-dynlocks-common.patch;h=0000000000000000000000000000000000000000;hb=08fbadcfe1b62ba46e721eca2d0c5309ca95273c;hp=c91c8bcdef14a38b9d2641b86f8c5826d42700b5;hpb=28254f0b2726bc540d57dac1dbb16e8a3e45b411;p=fs%2Flustre-release.git diff --git a/ldiskfs/kernel_patches/patches/rhel6.3/ext4-dynlocks-common.patch b/ldiskfs/kernel_patches/patches/rhel6.3/ext4-dynlocks-common.patch deleted file mode 100644 index c91c8bc..0000000 --- a/ldiskfs/kernel_patches/patches/rhel6.3/ext4-dynlocks-common.patch +++ /dev/null @@ -1,355 +0,0 @@ -Index: linux-stage/fs/ext4/dynlocks.c -=================================================================== ---- /dev/null -+++ linux-stage/fs/ext4/dynlocks.c -@@ -0,0 +1,236 @@ -+/* -+ * Dynamic Locks -+ * -+ * struct dynlock is lockspace -+ * one may request lock (exclusive or shared) for some value -+ * in that lockspace -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#define DYNLOCK_HANDLE_MAGIC 0xd19a10c -+#define DYNLOCK_HANDLE_DEAD 0xd1956ee -+#define DYNLOCK_LIST_MAGIC 0x11ee91e6 -+ -+static struct kmem_cache * dynlock_cachep = NULL; -+ -+struct dynlock_handle { -+ unsigned dh_magic; -+ struct list_head dh_list; -+ unsigned long dh_value; /* lock value */ -+ int dh_refcount; /* number of users */ -+ int dh_readers; -+ int dh_writers; -+ int dh_pid; /* holder of the lock */ -+ wait_queue_head_t dh_wait; -+}; -+ -+int __init dynlock_cache_init(void) -+{ -+ int rc = 0; -+ -+ /* printk(KERN_INFO "init dynlocks cache\n"); */ -+ dynlock_cachep = kmem_cache_create("dynlock_cache", -+ sizeof(struct dynlock_handle), -+ 0, -+ SLAB_HWCACHE_ALIGN, -+ NULL); -+ if (dynlock_cachep == NULL) { -+ printk(KERN_ERR "Not able to create dynlock cache"); -+ rc = -ENOMEM; -+ } -+ return rc; -+} -+ -+void dynlock_cache_exit(void) -+{ -+ /* printk(KERN_INFO "exit dynlocks cache\n"); */ -+ kmem_cache_destroy(dynlock_cachep); -+} -+ -+/* -+ * 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; -+} -+EXPORT_SYMBOL(dynlock_init); -+ -+/* -+ * 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, gfp_t gfp) -+{ -+ struct dynlock_handle *nhl = NULL; -+ struct dynlock_handle *hl; -+ -+ BUG_ON(dl == NULL); -+ BUG_ON(dl->dl_magic != DYNLOCK_LIST_MAGIC); -+ -+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_entry(hl, &dl->dl_list, dh_list) { -+ BUG_ON(hl->dh_list.next == NULL); -+ BUG_ON(hl->dh_list.prev == NULL); -+ BUG_ON(hl->dh_magic != DYNLOCK_HANDLE_MAGIC); -+ if (hl->dh_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->dh_refcount++; -+ goto found; -+ } -+ } -+ /* lock not found */ -+ if (nhl) { -+ /* we already have allocated lock. use it */ -+ hl = nhl; -+ nhl = NULL; -+ list_add(&hl->dh_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->dh_refcount = 1; -+ nhl->dh_value = value; -+ nhl->dh_readers = 0; -+ nhl->dh_writers = 0; -+ nhl->dh_magic = DYNLOCK_HANDLE_MAGIC; -+ init_waitqueue_head(&nhl->dh_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->dh_writers && hl->dh_pid != current->pid) || -+ hl->dh_readers) { -+ spin_unlock(&dl->dl_list_lock); -+ wait_event(hl->dh_wait, -+ hl->dh_writers == 0 && hl->dh_readers == 0); -+ spin_lock(&dl->dl_list_lock); -+ } -+ hl->dh_writers++; -+ } else { -+ /* shared lock: user do not want to share lock with writer */ -+ while (hl->dh_writers) { -+ spin_unlock(&dl->dl_list_lock); -+ wait_event(hl->dh_wait, hl->dh_writers == 0); -+ spin_lock(&dl->dl_list_lock); -+ } -+ hl->dh_readers++; -+ } -+ hl->dh_pid = current->pid; -+ spin_unlock(&dl->dl_list_lock); -+ -+ return hl; -+} -+EXPORT_SYMBOL(dynlock_lock); -+ -+ -+/* -+ * 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); -+ -+ if (hl->dh_magic != DYNLOCK_HANDLE_MAGIC) -+ printk(KERN_EMERG "wrong lock magic: %#x\n", hl->dh_magic); -+ -+ BUG_ON(hl->dh_magic != DYNLOCK_HANDLE_MAGIC); -+ BUG_ON(hl->dh_writers != 0 && current->pid != hl->dh_pid); -+ -+ spin_lock(&dl->dl_list_lock); -+ if (hl->dh_writers) { -+ BUG_ON(hl->dh_readers != 0); -+ hl->dh_writers--; -+ if (hl->dh_writers == 0) -+ wakeup = 1; -+ } else if (hl->dh_readers) { -+ hl->dh_readers--; -+ if (hl->dh_readers == 0) -+ wakeup = 1; -+ } else { -+ BUG(); -+ } -+ if (wakeup) { -+ hl->dh_pid = 0; -+ wake_up(&hl->dh_wait); -+ } -+ if (--(hl->dh_refcount) == 0) { -+ hl->dh_magic = DYNLOCK_HANDLE_DEAD; -+ list_del(&hl->dh_list); -+ kmem_cache_free(dynlock_cachep, hl); -+ } -+ spin_unlock(&dl->dl_list_lock); -+} -+EXPORT_SYMBOL(dynlock_unlock); -+ -+int dynlock_is_locked(struct dynlock *dl, unsigned long value) -+{ -+ struct dynlock_handle *hl; -+ int result = 0; -+ -+ /* 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_entry(hl, &dl->dl_list, dh_list) { -+ BUG_ON(hl->dh_list.next == NULL); -+ BUG_ON(hl->dh_list.prev == NULL); -+ BUG_ON(hl->dh_magic != DYNLOCK_HANDLE_MAGIC); -+ if (hl->dh_value == value && hl->dh_pid == current->pid) { -+ /* lock is found */ -+ result = 1; -+ break; -+ } -+ } -+ spin_unlock(&dl->dl_list_lock); -+ return result; -+} -+EXPORT_SYMBOL(dynlock_is_locked); -Index: linux-stage/include/linux/dynlocks.h -=================================================================== ---- /dev/null -+++ linux-stage/include/linux/dynlocks.h -@@ -0,0 +1,34 @@ -+#ifndef _LINUX_DYNLOCKS_H -+#define _LINUX_DYNLOCKS_H -+ -+#include -+#include -+ -+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_WRITE, -+ DLT_READ -+}; -+ -+int dynlock_cache_init(void); -+void dynlock_cache_exit(void); -+void dynlock_init(struct dynlock *dl); -+struct dynlock_handle *dynlock_lock(struct dynlock *dl, unsigned long value, -+ enum dynlock_type lt, gfp_t gfp); -+void dynlock_unlock(struct dynlock *dl, struct dynlock_handle *lock); -+int dynlock_is_locked(struct dynlock *dl, unsigned long value); -+ -+#endif -+ -Index: linux-stage/fs/ext4/Makefile -=================================================================== ---- linux-stage.orig/fs/ext4/Makefile -+++ linux-stage/fs/ext4/Makefile -@@ -7,7 +7,7 @@ obj-$(CONFIG_EXT4_FS) += ext4.o - ext4-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ - ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \ - ext4_jbd2.o migrate.o mballoc.o block_validity.o move_extent.o \ -- mmp.o -+ mmp.o dynlocks.o - - ext4-$(CONFIG_EXT4_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o - ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o -Index: linux-stage/fs/ext4/super.c -=================================================================== ---- linux-stage.orig/fs/ext4/super.c -+++ linux-stage/fs/ext4/super.c -@@ -4620,20 +4620,23 @@ static int __init init_ext4_fs(void) - return err; - ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj); - if (!ext4_kset) -- goto out4; -+ goto out5; - ext4_proc_root = proc_mkdir("fs/ext4", NULL); - - err = ext4_init_feat_adverts(); - - err = init_ext4_mballoc(); - if (err) -- goto out3; -+ goto out4; - - err = init_ext4_xattr(); - if (err) -- goto out2; -+ goto out3; - err = init_inodecache(); - if (err) -+ goto out2; -+ err = dynlock_cache_init(); -+ if (err) - goto out1; - err = register_filesystem(&ext4_fs_type); - if (err) -@@ -4643,16 +4646,18 @@ static int __init init_ext4_fs(void) - mutex_init(&ext4_li_mtx); - return 0; - out: -- destroy_inodecache(); -+ dynlock_cache_exit(); - out1: -- exit_ext4_xattr(); -+ destroy_inodecache(); - out2: -- exit_ext4_mballoc(); -+ exit_ext4_xattr(); - out3: -+ exit_ext4_mballoc(); -+out4: - ext4_exit_feat_adverts(); - remove_proc_entry("fs/ext4", NULL); - kset_unregister(ext4_kset); --out4: -+out5: - exit_ext4_system_zone(); - return err; - } -@@ -4661,6 +4666,7 @@ static void __exit exit_ext4_fs(void) - { - ext4_destroy_lazyinit_thread(); - unregister_filesystem(&ext4_fs_type); -+ dynlock_cache_exit(); - destroy_inodecache(); - exit_ext4_xattr(); - exit_ext4_mballoc();