-diff -ruN linux-2.4.19-dm/drivers/md/Makefile linux-2.4.19-dmbackport/drivers/md/Makefile
---- linux-2.4.19-dm/drivers/md/Makefile Wed Aug 14 11:51:06 2002
-+++ linux-2.4.19-dmbackport/drivers/md/Makefile Tue Nov 12 12:47:39 2002
+diff -ruN linux-2.4.19/drivers/md/Makefile linux-2.4.19-dm/drivers/md/Makefile
+--- linux-2.4.19/drivers/md/Makefile Wed Aug 14 11:51:06 2002
++++ linux-2.4.19-dm/drivers/md/Makefile Thu Nov 14 13:50:32 2002
@@ -4,9 +4,12 @@
O_TARGET := mddev.o
+
+dm-mod.o: $(dm-mod-objs)
+ $(LD) -r -o $@ $(dm-mod-objs)
-diff -ruN linux-2.4.19-dm/drivers/md/dm-exception-store.c linux-2.4.19-dmbackport/drivers/md/dm-exception-store.c
---- linux-2.4.19-dm/drivers/md/dm-exception-store.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dmbackport/drivers/md/dm-exception-store.c Wed Nov 13 17:29:01 2002
+diff -ruN linux-2.4.19/drivers/md/dm-exception-store.c linux-2.4.19-dm/drivers/md/dm-exception-store.c
+--- linux-2.4.19/drivers/md/dm-exception-store.c Thu Jan 1 01:00:00 1970
++++ linux-2.4.19-dm/drivers/md/dm-exception-store.c Thu Nov 14 13:50:32 2002
@@ -0,0 +1,701 @@
+/*
+ * dm-snapshot.c
+
+ return 0;
+}
-diff -ruN linux-2.4.19-dm/drivers/md/dm-ioctl.c linux-2.4.19-dmbackport/drivers/md/dm-ioctl.c
---- linux-2.4.19-dm/drivers/md/dm-ioctl.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dmbackport/drivers/md/dm-ioctl.c Wed Nov 13 17:38:50 2002
+diff -ruN linux-2.4.19/drivers/md/dm-ioctl.c linux-2.4.19-dm/drivers/md/dm-ioctl.c
+--- linux-2.4.19/drivers/md/dm-ioctl.c Thu Jan 1 01:00:00 1970
++++ linux-2.4.19-dm/drivers/md/dm-ioctl.c Thu Nov 14 13:50:32 2002
@@ -0,0 +1,1139 @@
+/*
+ * Copyright (C) 2001, 2002 Sistina Software (UK) Limited.
+ if (misc_deregister(&_dm_misc) < 0)
+ DMERR("misc_deregister failed for control device");
+}
-diff -ruN linux-2.4.19-dm/drivers/md/dm-linear.c linux-2.4.19-dmbackport/drivers/md/dm-linear.c
---- linux-2.4.19-dm/drivers/md/dm-linear.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dmbackport/drivers/md/dm-linear.c Wed Nov 13 17:39:17 2002
+diff -ruN linux-2.4.19/drivers/md/dm-linear.c linux-2.4.19-dm/drivers/md/dm-linear.c
+--- linux-2.4.19/drivers/md/dm-linear.c Thu Jan 1 01:00:00 1970
++++ linux-2.4.19-dm/drivers/md/dm-linear.c Thu Nov 14 13:50:32 2002
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2001 Sistina Software (UK) Limited.
+ if (r < 0)
+ DMERR("linear: unregister failed %d", r);
+}
-diff -ruN linux-2.4.19-dm/drivers/md/dm-snapshot.c linux-2.4.19-dmbackport/drivers/md/dm-snapshot.c
---- linux-2.4.19-dm/drivers/md/dm-snapshot.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dmbackport/drivers/md/dm-snapshot.c Wed Nov 13 17:44:55 2002
+diff -ruN linux-2.4.19/drivers/md/dm-snapshot.c linux-2.4.19-dm/drivers/md/dm-snapshot.c
+--- linux-2.4.19/drivers/md/dm-snapshot.c Thu Jan 1 01:00:00 1970
++++ linux-2.4.19-dm/drivers/md/dm-snapshot.c Thu Nov 14 13:50:32 2002
@@ -0,0 +1,1169 @@
+/*
+ * dm-snapshot.c
+ * c-file-style: "linux"
+ * End:
+ */
-diff -ruN linux-2.4.19-dm/drivers/md/dm-snapshot.h linux-2.4.19-dmbackport/drivers/md/dm-snapshot.h
---- linux-2.4.19-dm/drivers/md/dm-snapshot.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dmbackport/drivers/md/dm-snapshot.h Wed Nov 13 18:08:24 2002
+diff -ruN linux-2.4.19/drivers/md/dm-snapshot.h linux-2.4.19-dm/drivers/md/dm-snapshot.h
+--- linux-2.4.19/drivers/md/dm-snapshot.h Thu Jan 1 01:00:00 1970
++++ linux-2.4.19-dm/drivers/md/dm-snapshot.h Thu Nov 14 13:50:32 2002
@@ -0,0 +1,147 @@
+/*
+ * dm-snapshot.c
+}
+
+#endif
-diff -ruN linux-2.4.19-dm/drivers/md/dm-stripe.c linux-2.4.19-dmbackport/drivers/md/dm-stripe.c
---- linux-2.4.19-dm/drivers/md/dm-stripe.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dmbackport/drivers/md/dm-stripe.c Wed Nov 13 17:45:21 2002
+diff -ruN linux-2.4.19/drivers/md/dm-stripe.c linux-2.4.19-dm/drivers/md/dm-stripe.c
+--- linux-2.4.19/drivers/md/dm-stripe.c Thu Jan 1 01:00:00 1970
++++ linux-2.4.19-dm/drivers/md/dm-stripe.c Thu Nov 14 13:50:32 2002
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2001 Sistina Software (UK) Limited.
+
+ return;
+}
-diff -ruN linux-2.4.19-dm/drivers/md/dm-table.c linux-2.4.19-dmbackport/drivers/md/dm-table.c
---- linux-2.4.19-dm/drivers/md/dm-table.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dmbackport/drivers/md/dm-table.c Wed Nov 13 17:47:11 2002
+diff -ruN linux-2.4.19/drivers/md/dm-table.c linux-2.4.19-dm/drivers/md/dm-table.c
+--- linux-2.4.19/drivers/md/dm-table.c Thu Jan 1 01:00:00 1970
++++ linux-2.4.19-dm/drivers/md/dm-table.c Thu Nov 21 13:39:57 2002
@@ -0,0 +1,665 @@
+/*
+ * Copyright (C) 2001 Sistina Software (UK) Limited.
+ }
+
+ if (!S_ISBLK(inode->i_mode)) {
-+ r = -EINVAL;
++ r = -ENOTBLK;
+ goto out;
+ }
+
+EXPORT_SYMBOL(dm_get_device);
+EXPORT_SYMBOL(dm_put_device);
+EXPORT_SYMBOL(dm_table_event);
-diff -ruN linux-2.4.19-dm/drivers/md/dm-target.c linux-2.4.19-dmbackport/drivers/md/dm-target.c
---- linux-2.4.19-dm/drivers/md/dm-target.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dmbackport/drivers/md/dm-target.c Wed Nov 13 17:47:29 2002
+diff -ruN linux-2.4.19/drivers/md/dm-target.c linux-2.4.19-dm/drivers/md/dm-target.c
+--- linux-2.4.19/drivers/md/dm-target.c Thu Jan 1 01:00:00 1970
++++ linux-2.4.19-dm/drivers/md/dm-target.c Thu Nov 14 13:50:32 2002
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2001 Sistina Software (UK) Limited
+
+EXPORT_SYMBOL(dm_register_target);
+EXPORT_SYMBOL(dm_unregister_target);
-diff -ruN linux-2.4.19-dm/drivers/md/dm.c linux-2.4.19-dmbackport/drivers/md/dm.c
---- linux-2.4.19-dm/drivers/md/dm.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dmbackport/drivers/md/dm.c Wed Nov 13 19:15:43 2002
+diff -ruN linux-2.4.19/drivers/md/dm.c linux-2.4.19-dm/drivers/md/dm.c
+--- linux-2.4.19/drivers/md/dm.c Thu Jan 1 01:00:00 1970
++++ linux-2.4.19-dm/drivers/md/dm.c Thu Nov 21 13:40:03 2002
@@ -0,0 +1,868 @@
+/*
+ * Copyright (C) 2001, 2002 Sistina Software (UK) Limited.
+ if (major(dev) != _major)
+ return NULL;
+
-+ spin_lock(_minor_lock);
++ spin_lock(&_minor_lock);
+ md = _mds[minor(dev)];
+ if (md)
+ dm_get(md);
-+ spin_unlock(_minor_lock);
++ spin_unlock(&_minor_lock);
+
+ return md;
+}
+MODULE_DESCRIPTION(DM_NAME " driver");
+MODULE_AUTHOR("Joe Thornber <thornber@sistina.com>");
+MODULE_LICENSE("GPL");
-diff -ruN linux-2.4.19-dm/drivers/md/dm.h linux-2.4.19-dmbackport/drivers/md/dm.h
---- linux-2.4.19-dm/drivers/md/dm.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dmbackport/drivers/md/dm.h Wed Nov 13 18:08:20 2002
+diff -ruN linux-2.4.19/drivers/md/dm.h linux-2.4.19-dm/drivers/md/dm.h
+--- linux-2.4.19/drivers/md/dm.h Thu Jan 1 01:00:00 1970
++++ linux-2.4.19-dm/drivers/md/dm.h Thu Nov 14 13:50:32 2002
@@ -0,0 +1,150 @@
+/*
+ * Internal header file for device mapper
+void dm_snapshot_exit(void);
+
+#endif
-diff -ruN linux-2.4.19-dm/drivers/md/kcopyd.c linux-2.4.19-dmbackport/drivers/md/kcopyd.c
---- linux-2.4.19-dm/drivers/md/kcopyd.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dmbackport/drivers/md/kcopyd.c Wed Nov 13 17:52:16 2002
+diff -ruN linux-2.4.19/drivers/md/kcopyd.c linux-2.4.19-dm/drivers/md/kcopyd.c
+--- linux-2.4.19/drivers/md/kcopyd.c Thu Jan 1 01:00:00 1970
++++ linux-2.4.19-dm/drivers/md/kcopyd.c Thu Nov 14 13:50:32 2002
@@ -0,0 +1,843 @@
+/*
+ * Copyright (C) 2002 Sistina Software (UK) Limited.
+
+ up(&_client_count_sem);
+}
-diff -ruN linux-2.4.19-dm/drivers/md/kcopyd.h linux-2.4.19-dmbackport/drivers/md/kcopyd.h
---- linux-2.4.19-dm/drivers/md/kcopyd.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dmbackport/drivers/md/kcopyd.h Wed Nov 13 18:08:24 2002
+diff -ruN linux-2.4.19/drivers/md/kcopyd.h linux-2.4.19-dm/drivers/md/kcopyd.h
+--- linux-2.4.19/drivers/md/kcopyd.h Thu Jan 1 01:00:00 1970
++++ linux-2.4.19-dm/drivers/md/kcopyd.h Thu Nov 14 13:50:32 2002
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2001 Sistina Software
+void kcopyd_dec_client_count(void);
+
+#endif
-diff -ruN linux-2.4.19-dm/include/linux/device-mapper.h linux-2.4.19-dmbackport/include/linux/device-mapper.h
---- linux-2.4.19-dm/include/linux/device-mapper.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dmbackport/include/linux/device-mapper.h Wed Nov 13 17:54:29 2002
+diff -ruN linux-2.4.19/include/linux/device-mapper.h linux-2.4.19-dm/include/linux/device-mapper.h
+--- linux-2.4.19/include/linux/device-mapper.h Thu Jan 1 01:00:00 1970
++++ linux-2.4.19-dm/include/linux/device-mapper.h Thu Nov 14 13:50:32 2002
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2001 Sistina Software (UK) Limited.
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_DEVICE_MAPPER_H */
-diff -ruN linux-2.4.19-dm/include/linux/dm-ioctl.h linux-2.4.19-dmbackport/include/linux/dm-ioctl.h
---- linux-2.4.19-dm/include/linux/dm-ioctl.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dmbackport/include/linux/dm-ioctl.h Wed Nov 13 17:53:50 2002
+diff -ruN linux-2.4.19/include/linux/dm-ioctl.h linux-2.4.19-dm/include/linux/dm-ioctl.h
+--- linux-2.4.19/include/linux/dm-ioctl.h Thu Jan 1 01:00:00 1970
++++ linux-2.4.19-dm/include/linux/dm-ioctl.h Thu Nov 14 13:50:32 2002
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2001 Sistina Software (UK) Limited.
+
+#define DM_VERSION_MAJOR 1
+#define DM_VERSION_MINOR 0
-+#define DM_VERSION_PATCHLEVEL 7
-+#define DM_VERSION_EXTRA "-ioctl (2002-11-13)"
++#define DM_VERSION_PATCHLEVEL 8
++#define DM_VERSION_EXTRA "-ioctl (2002-11-21)"
+
+/* Status bits */
+#define DM_READONLY_FLAG 0x00000001
-diff -Nru linux-2.4.19/include/linux/mempool.h linux/include/linux/mempool.h
---- /dev/null Wed Dec 31 16:00:00 1969
-+++ linux/include/linux/mempool.h Tue Apr 23 20:55:52 2002
-@@ -0,0 +1,33 @@
+diff -ruN linux-2.4.19/include/linux/mempool.h linux-2.4.19-dm/include/linux/mempool.h
+--- linux-2.4.19/include/linux/mempool.h Thu Jan 1 01:00:00 1970
++++ linux-2.4.19-dm/include/linux/mempool.h Thu Nov 21 14:21:19 2002
+@@ -0,0 +1,23 @@
+/*
+ * memory buffer pool support
+ */
+typedef void * (mempool_alloc_t)(int gfp_mask, void *pool_data);
+typedef void (mempool_free_t)(void *element, void *pool_data);
+
-+struct mempool_s {
-+ spinlock_t lock;
-+ int min_nr, curr_nr;
-+ struct list_head elements;
-+
-+ void *pool_data;
-+ mempool_alloc_t *alloc;
-+ mempool_free_t *free;
-+ wait_queue_head_t wait;
-+};
+extern mempool_t * mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
+ mempool_free_t *free_fn, void *pool_data);
-+extern void mempool_resize(mempool_t *pool, int new_min_nr, int gfp_mask);
++extern int mempool_resize(mempool_t *pool, int new_min_nr, int gfp_mask);
+extern void mempool_destroy(mempool_t *pool);
+extern void * mempool_alloc(mempool_t *pool, int gfp_mask);
+extern void mempool_free(void *element, mempool_t *pool);
+
+#endif /* _LINUX_MEMPOOL_H */
-diff -Nru linux-2.4.19/mm/Makefile linux/mm/Makefile
---- linux-2.4.19/mm/Makefile Mon Mar 25 14:40:15 2002
-+++ linux/mm/Makefile Mon Mar 25 14:40:15 2002
+diff -ruN linux-2.4.19/mm/Makefile linux-2.4.19-dm/mm/Makefile
+--- linux-2.4.19/mm/Makefile Wed Aug 14 11:52:12 2002
++++ linux-2.4.19-dm/mm/Makefile Thu Nov 14 13:50:32 2002
@@ -9,12 +9,12 @@
O_TARGET := mm.o
obj-$(CONFIG_HIGHMEM) += highmem.o
-diff -Nru linux-2.4.19/mm/mempool.c b/mm/mempool.c
---- /dev/null Wed Dec 31 16:00:00 1969
-+++ linux/mm/mempool.c Tue Apr 23 20:55:52 2002
-@@ -0,0 +1,277 @@
+diff -ruN linux-2.4.19/mm/mempool.c linux-2.4.19-dm/mm/mempool.c
+--- linux-2.4.19/mm/mempool.c Thu Jan 1 01:00:00 1970
++++ linux-2.4.19-dm/mm/mempool.c Thu Nov 21 14:21:19 2002
+@@ -0,0 +1,281 @@
+/*
+ * linux/mm/mempool.c
+ *
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/mempool.h>
-+#include <linux/compiler.h>
++
++struct mempool_s {
++ spinlock_t lock;
++ int min_nr; /* nr of elements at *elements */
++ int curr_nr; /* Current nr of elements at *elements */
++ void **elements;
++
++ void *pool_data;
++ mempool_alloc_t *alloc;
++ mempool_free_t *free;
++ wait_queue_head_t wait;
++};
++
++static void add_element(mempool_t *pool, void *element)
++{
++ BUG_ON(pool->curr_nr >= pool->min_nr);
++ pool->elements[pool->curr_nr++] = element;
++}
++
++static void *remove_element(mempool_t *pool)
++{
++ BUG_ON(pool->curr_nr <= 0);
++ return pool->elements[--pool->curr_nr];
++}
++
++static void free_pool(mempool_t *pool)
++{
++ while (pool->curr_nr) {
++ void *element = remove_element(pool);
++ pool->free(element, pool->pool_data);
++ }
++ kfree(pool->elements);
++ kfree(pool);
++}
+
+/**
+ * mempool_create - create a memory pool
+ * memory pool. The pool can be used from the mempool_alloc and mempool_free
+ * functions. This function might sleep. Both the alloc_fn() and the free_fn()
+ * functions might sleep - as long as the mempool_alloc function is not called
-+ * from IRQ contexts. The element allocated by alloc_fn() must be able to
-+ * hold a struct list_head. (8 bytes on x86.)
++ * from IRQ contexts.
+ */
+mempool_t * mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
+ mempool_free_t *free_fn, void *pool_data)
+{
+ mempool_t *pool;
-+ int i;
+
+ pool = kmalloc(sizeof(*pool), GFP_KERNEL);
+ if (!pool)
+ return NULL;
+ memset(pool, 0, sizeof(*pool));
-+
++ pool->elements = kmalloc(min_nr * sizeof(void *), GFP_KERNEL);
++ if (!pool->elements) {
++ kfree(pool);
++ return NULL;
++ }
+ spin_lock_init(&pool->lock);
+ pool->min_nr = min_nr;
+ pool->pool_data = pool_data;
-+ INIT_LIST_HEAD(&pool->elements);
+ init_waitqueue_head(&pool->wait);
+ pool->alloc = alloc_fn;
+ pool->free = free_fn;
+ /*
+ * First pre-allocate the guaranteed number of buffers.
+ */
-+ for (i = 0; i < min_nr; i++) {
++ while (pool->curr_nr < pool->min_nr) {
+ void *element;
-+ struct list_head *tmp;
-+ element = pool->alloc(GFP_KERNEL, pool->pool_data);
+
++ element = pool->alloc(GFP_KERNEL, pool->pool_data);
+ if (unlikely(!element)) {
-+ /*
-+ * Not enough memory - free the allocated ones
-+ * and return:
-+ */
-+ list_for_each(tmp, &pool->elements) {
-+ element = tmp;
-+ pool->free(element, pool->pool_data);
-+ }
-+ kfree(pool);
-+
++ free_pool(pool);
+ return NULL;
+ }
-+ tmp = element;
-+ list_add(tmp, &pool->elements);
-+ pool->curr_nr++;
++ add_element(pool, element);
+ }
+ return pool;
+}
+ * while this function is running. mempool_alloc() & mempool_free()
+ * might be called (eg. from IRQ contexts) while this function executes.
+ */
-+void mempool_resize(mempool_t *pool, int new_min_nr, int gfp_mask)
++int mempool_resize(mempool_t *pool, int new_min_nr, int gfp_mask)
+{
-+ int delta;
+ void *element;
++ void **new_elements;
+ unsigned long flags;
-+ struct list_head *tmp;
+
-+ if (new_min_nr <= 0)
-+ BUG();
++ BUG_ON(new_min_nr <= 0);
+
+ spin_lock_irqsave(&pool->lock, flags);
+ if (new_min_nr < pool->min_nr) {
-+ pool->min_nr = new_min_nr;
-+ /*
-+ * Free possible excess elements.
-+ */
-+ while (pool->curr_nr > pool->min_nr) {
-+ tmp = pool->elements.next;
-+ if (tmp == &pool->elements)
-+ BUG();
-+ list_del(tmp);
-+ element = tmp;
-+ pool->curr_nr--;
++ while (pool->curr_nr > new_min_nr) {
++ element = remove_element(pool);
+ spin_unlock_irqrestore(&pool->lock, flags);
-+
+ pool->free(element, pool->pool_data);
-+
+ spin_lock_irqsave(&pool->lock, flags);
+ }
-+ spin_unlock_irqrestore(&pool->lock, flags);
-+ return;
++ pool->min_nr = new_min_nr;
++ goto out_unlock;
+ }
-+ delta = new_min_nr - pool->min_nr;
-+ pool->min_nr = new_min_nr;
+ spin_unlock_irqrestore(&pool->lock, flags);
+
-+ /*
-+ * We refill the pool up to the new treshold - but we dont
-+ * (cannot) guarantee that the refill succeeds.
-+ */
-+ while (delta) {
++ /* Grow the pool */
++ new_elements = kmalloc(new_min_nr * sizeof(*new_elements), gfp_mask);
++ if (!new_elements)
++ return -ENOMEM;
++
++ spin_lock_irqsave(&pool->lock, flags);
++ memcpy(new_elements, pool->elements,
++ pool->curr_nr * sizeof(*new_elements));
++ kfree(pool->elements);
++ pool->elements = new_elements;
++ pool->min_nr = new_min_nr;
++
++ while (pool->curr_nr < pool->min_nr) {
++ spin_unlock_irqrestore(&pool->lock, flags);
+ element = pool->alloc(gfp_mask, pool->pool_data);
+ if (!element)
-+ break;
-+ mempool_free(element, pool);
-+ delta--;
++ goto out;
++ spin_lock_irqsave(&pool->lock, flags);
++ if (pool->curr_nr < pool->min_nr)
++ add_element(pool, element);
++ else
++ kfree(element); /* Raced */
+ }
++out_unlock:
++ spin_unlock_irqrestore(&pool->lock, flags);
++out:
++ return 0;
+}
+
+/**
+ * mempool_create().
+ *
+ * this function only sleeps if the free_fn() function sleeps. The caller
-+ * has to guarantee that no mempool_alloc() nor mempool_free() happens in
-+ * this pool when calling this function.
++ * has to guarantee that all elements have been returned to the pool (ie:
++ * freed) prior to calling mempool_destroy().
+ */
+void mempool_destroy(mempool_t *pool)
+{
-+ void *element;
-+ struct list_head *head, *tmp;
-+
-+ if (!pool)
-+ return;
-+
-+ head = &pool->elements;
-+ for (tmp = head->next; tmp != head; ) {
-+ element = tmp;
-+ tmp = tmp->next;
-+ pool->free(element, pool->pool_data);
-+ pool->curr_nr--;
-+ }
-+ if (pool->curr_nr)
-+ BUG();
-+ kfree(pool);
++ if (pool->curr_nr != pool->min_nr)
++ BUG(); /* There were outstanding elements */
++ free_pool(pool);
+}
+
+/**
+{
+ void *element;
+ unsigned long flags;
-+ struct list_head *tmp;
+ int curr_nr;
+ DECLARE_WAITQUEUE(wait, current);
+ int gfp_nowait = gfp_mask & ~(__GFP_WAIT | __GFP_IO);
+
+ spin_lock_irqsave(&pool->lock, flags);
+ if (likely(pool->curr_nr)) {
-+ tmp = pool->elements.next;
-+ list_del(tmp);
-+ element = tmp;
-+ pool->curr_nr--;
++ element = remove_element(pool);
+ spin_unlock_irqrestore(&pool->lock, flags);
+ return element;
+ }
+ if (pool->curr_nr < pool->min_nr) {
+ spin_lock_irqsave(&pool->lock, flags);
+ if (pool->curr_nr < pool->min_nr) {
-+ list_add(element, &pool->elements);
-+ pool->curr_nr++;
++ add_element(pool, element);
+ spin_unlock_irqrestore(&pool->lock, flags);
+ wake_up(&pool->wait);
+ return;
+EXPORT_SYMBOL(mempool_destroy);
+EXPORT_SYMBOL(mempool_alloc);
+EXPORT_SYMBOL(mempool_free);
-+
diff -ruN linux-2.4.19/Documentation/Configure.help linux-2.4.19-dm/Documentation/Configure.help
--- linux-2.4.19/Documentation/Configure.help Wed Aug 14 11:49:48 2002
-+++ linux-2.4.19-dm/Documentation/Configure.help Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/Documentation/Configure.help Thu Nov 21 14:31:25 2002
@@ -1775,6 +1775,20 @@
want), say M here and read <file:Documentation/modules.txt>. The
module will be called lvm-mod.o.
Support multiple physical spindles through a single logical device.
diff -ruN linux-2.4.19/MAINTAINERS linux-2.4.19-dm/MAINTAINERS
--- linux-2.4.19/MAINTAINERS Wed Aug 14 11:49:45 2002
-+++ linux-2.4.19-dm/MAINTAINERS Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/MAINTAINERS Thu Nov 21 14:31:25 2002
@@ -426,6 +426,13 @@
W: http://www.debian.org/~dz/i8k/
S: Maintained
M: hpa@zytor.com
diff -ruN linux-2.4.19/arch/mips64/kernel/ioctl32.c linux-2.4.19-dm/arch/mips64/kernel/ioctl32.c
--- linux-2.4.19/arch/mips64/kernel/ioctl32.c Wed Aug 14 11:50:16 2002
-+++ linux-2.4.19-dm/arch/mips64/kernel/ioctl32.c Thu Nov 14 13:57:06 2002
++++ linux-2.4.19-dm/arch/mips64/kernel/ioctl32.c Thu Nov 21 14:31:14 2002
@@ -27,6 +27,7 @@
#include <linux/auto_fs.h>
#include <linux/ext2_fs.h>
IOCTL32_HANDLER(MTIOCGET32, mt_ioctl_trans),
diff -ruN linux-2.4.19/arch/ppc64/kernel/ioctl32.c linux-2.4.19-dm/arch/ppc64/kernel/ioctl32.c
--- linux-2.4.19/arch/ppc64/kernel/ioctl32.c Wed Aug 14 11:50:22 2002
-+++ linux-2.4.19-dm/arch/ppc64/kernel/ioctl32.c Thu Nov 14 13:57:07 2002
++++ linux-2.4.19-dm/arch/ppc64/kernel/ioctl32.c Thu Nov 21 14:31:14 2002
@@ -65,6 +65,7 @@
#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
#include <linux/lvm.h>
COMPATIBLE_IOCTL(SIOCDEVPRIVATE+1),
diff -ruN linux-2.4.19/arch/s390x/kernel/ioctl32.c linux-2.4.19-dm/arch/s390x/kernel/ioctl32.c
--- linux-2.4.19/arch/s390x/kernel/ioctl32.c Wed Aug 14 11:50:27 2002
-+++ linux-2.4.19-dm/arch/s390x/kernel/ioctl32.c Thu Nov 14 13:57:07 2002
++++ linux-2.4.19-dm/arch/s390x/kernel/ioctl32.c Thu Nov 21 14:31:14 2002
@@ -25,6 +25,7 @@
#include <linux/ext2_fs.h>
#include <linux/hdreg.h>
IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf),
diff -ruN linux-2.4.19/arch/sparc64/kernel/ioctl32.c linux-2.4.19-dm/arch/sparc64/kernel/ioctl32.c
--- linux-2.4.19/arch/sparc64/kernel/ioctl32.c Wed Aug 14 11:50:32 2002
-+++ linux-2.4.19-dm/arch/sparc64/kernel/ioctl32.c Thu Nov 14 13:57:07 2002
++++ linux-2.4.19-dm/arch/sparc64/kernel/ioctl32.c Thu Nov 21 14:31:14 2002
@@ -54,6 +54,7 @@
#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
#include <linux/lvm.h>
HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob)
diff -ruN linux-2.4.19/drivers/md/Config.in linux-2.4.19-dm/drivers/md/Config.in
--- linux-2.4.19/drivers/md/Config.in Wed Aug 14 11:51:06 2002
-+++ linux-2.4.19-dm/drivers/md/Config.in Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/drivers/md/Config.in Thu Nov 21 14:31:25 2002
@@ -14,5 +14,8 @@
dep_tristate ' Multipath I/O support' CONFIG_MD_MULTIPATH $CONFIG_BLK_DEV_MD
endmenu
diff -ruN linux-2.4.19/drivers/md/Makefile linux-2.4.19-dm/drivers/md/Makefile
--- linux-2.4.19/drivers/md/Makefile Wed Aug 14 11:51:06 2002
-+++ linux-2.4.19-dm/drivers/md/Makefile Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/drivers/md/Makefile Thu Nov 21 14:31:09 2002
@@ -4,9 +4,12 @@
O_TARGET := mddev.o
+ $(LD) -r -o $@ $(dm-mod-objs)
diff -ruN linux-2.4.19/drivers/md/dm-exception-store.c linux-2.4.19-dm/drivers/md/dm-exception-store.c
--- linux-2.4.19/drivers/md/dm-exception-store.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dm/drivers/md/dm-exception-store.c Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/drivers/md/dm-exception-store.c Thu Nov 21 14:31:09 2002
@@ -0,0 +1,701 @@
+/*
+ * dm-snapshot.c
+}
diff -ruN linux-2.4.19/drivers/md/dm-ioctl.c linux-2.4.19-dm/drivers/md/dm-ioctl.c
--- linux-2.4.19/drivers/md/dm-ioctl.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dm/drivers/md/dm-ioctl.c Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/drivers/md/dm-ioctl.c Thu Nov 21 14:31:09 2002
@@ -0,0 +1,1139 @@
+/*
+ * Copyright (C) 2001, 2002 Sistina Software (UK) Limited.
+}
diff -ruN linux-2.4.19/drivers/md/dm-linear.c linux-2.4.19-dm/drivers/md/dm-linear.c
--- linux-2.4.19/drivers/md/dm-linear.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dm/drivers/md/dm-linear.c Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/drivers/md/dm-linear.c Thu Nov 21 14:31:09 2002
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2001 Sistina Software (UK) Limited.
+}
diff -ruN linux-2.4.19/drivers/md/dm-snapshot.c linux-2.4.19-dm/drivers/md/dm-snapshot.c
--- linux-2.4.19/drivers/md/dm-snapshot.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dm/drivers/md/dm-snapshot.c Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/drivers/md/dm-snapshot.c Thu Nov 21 14:31:09 2002
@@ -0,0 +1,1169 @@
+/*
+ * dm-snapshot.c
+ */
diff -ruN linux-2.4.19/drivers/md/dm-snapshot.h linux-2.4.19-dm/drivers/md/dm-snapshot.h
--- linux-2.4.19/drivers/md/dm-snapshot.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dm/drivers/md/dm-snapshot.h Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/drivers/md/dm-snapshot.h Thu Nov 21 14:31:09 2002
@@ -0,0 +1,147 @@
+/*
+ * dm-snapshot.c
+#endif
diff -ruN linux-2.4.19/drivers/md/dm-stripe.c linux-2.4.19-dm/drivers/md/dm-stripe.c
--- linux-2.4.19/drivers/md/dm-stripe.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dm/drivers/md/dm-stripe.c Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/drivers/md/dm-stripe.c Thu Nov 21 14:31:09 2002
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2001 Sistina Software (UK) Limited.
+}
diff -ruN linux-2.4.19/drivers/md/dm-table.c linux-2.4.19-dm/drivers/md/dm-table.c
--- linux-2.4.19/drivers/md/dm-table.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dm/drivers/md/dm-table.c Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/drivers/md/dm-table.c Thu Nov 21 14:31:09 2002
@@ -0,0 +1,665 @@
+/*
+ * Copyright (C) 2001 Sistina Software (UK) Limited.
+ }
+
+ if (!S_ISBLK(inode->i_mode)) {
-+ r = -EINVAL;
++ r = -ENOTBLK;
+ goto out;
+ }
+
+EXPORT_SYMBOL(dm_table_event);
diff -ruN linux-2.4.19/drivers/md/dm-target.c linux-2.4.19-dm/drivers/md/dm-target.c
--- linux-2.4.19/drivers/md/dm-target.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dm/drivers/md/dm-target.c Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/drivers/md/dm-target.c Thu Nov 21 14:31:09 2002
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2001 Sistina Software (UK) Limited
+EXPORT_SYMBOL(dm_unregister_target);
diff -ruN linux-2.4.19/drivers/md/dm.c linux-2.4.19-dm/drivers/md/dm.c
--- linux-2.4.19/drivers/md/dm.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dm/drivers/md/dm.c Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/drivers/md/dm.c Thu Nov 21 14:31:09 2002
@@ -0,0 +1,868 @@
+/*
+ * Copyright (C) 2001, 2002 Sistina Software (UK) Limited.
+ if (major(dev) != _major)
+ return NULL;
+
-+ spin_lock(_minor_lock);
++ spin_lock(&_minor_lock);
+ md = _mds[minor(dev)];
+ if (md)
+ dm_get(md);
-+ spin_unlock(_minor_lock);
++ spin_unlock(&_minor_lock);
+
+ return md;
+}
+MODULE_LICENSE("GPL");
diff -ruN linux-2.4.19/drivers/md/dm.h linux-2.4.19-dm/drivers/md/dm.h
--- linux-2.4.19/drivers/md/dm.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dm/drivers/md/dm.h Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/drivers/md/dm.h Thu Nov 21 14:31:09 2002
@@ -0,0 +1,150 @@
+/*
+ * Internal header file for device mapper
+#endif
diff -ruN linux-2.4.19/drivers/md/kcopyd.c linux-2.4.19-dm/drivers/md/kcopyd.c
--- linux-2.4.19/drivers/md/kcopyd.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dm/drivers/md/kcopyd.c Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/drivers/md/kcopyd.c Thu Nov 21 14:31:09 2002
@@ -0,0 +1,843 @@
+/*
+ * Copyright (C) 2002 Sistina Software (UK) Limited.
+}
diff -ruN linux-2.4.19/drivers/md/kcopyd.h linux-2.4.19-dm/drivers/md/kcopyd.h
--- linux-2.4.19/drivers/md/kcopyd.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dm/drivers/md/kcopyd.h Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/drivers/md/kcopyd.h Thu Nov 21 14:31:09 2002
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2001 Sistina Software
+#endif
diff -ruN linux-2.4.19/fs/buffer.c linux-2.4.19-dm/fs/buffer.c
--- linux-2.4.19/fs/buffer.c Wed Aug 14 11:51:40 2002
-+++ linux-2.4.19-dm/fs/buffer.c Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/fs/buffer.c Thu Nov 21 14:31:23 2002
@@ -587,9 +587,10 @@
void buffer_insert_inode_queue(struct buffer_head *bh, struct inode *inode)
{
kmem_cache_free(bh_cachep, bh);
diff -ruN linux-2.4.19/fs/jbd/journal.c linux-2.4.19-dm/fs/jbd/journal.c
--- linux-2.4.19/fs/jbd/journal.c Wed Aug 14 11:51:43 2002
-+++ linux-2.4.19-dm/fs/jbd/journal.c Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/fs/jbd/journal.c Thu Nov 21 14:31:23 2002
@@ -1625,8 +1625,8 @@
*
* Whenever a buffer has an attached journal_head, its ->b_state:BH_JBD bit
__brelse(bh);
diff -ruN linux-2.4.19/include/linux/device-mapper.h linux-2.4.19-dm/include/linux/device-mapper.h
--- linux-2.4.19/include/linux/device-mapper.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dm/include/linux/device-mapper.h Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/include/linux/device-mapper.h Thu Nov 21 14:31:09 2002
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2001 Sistina Software (UK) Limited.
+#endif /* _LINUX_DEVICE_MAPPER_H */
diff -ruN linux-2.4.19/include/linux/dm-ioctl.h linux-2.4.19-dm/include/linux/dm-ioctl.h
--- linux-2.4.19/include/linux/dm-ioctl.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dm/include/linux/dm-ioctl.h Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/include/linux/dm-ioctl.h Thu Nov 21 14:31:09 2002
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2001 Sistina Software (UK) Limited.
+
+#define DM_VERSION_MAJOR 1
+#define DM_VERSION_MINOR 0
-+#define DM_VERSION_PATCHLEVEL 7
-+#define DM_VERSION_EXTRA "-ioctl (2002-11-13)"
++#define DM_VERSION_PATCHLEVEL 8
++#define DM_VERSION_EXTRA "-ioctl (2002-11-21)"
+
+/* Status bits */
+#define DM_READONLY_FLAG 0x00000001
+#endif /* _LINUX_DM_IOCTL_H */
diff -ruN linux-2.4.19/include/linux/fs.h linux-2.4.19-dm/include/linux/fs.h
--- linux-2.4.19/include/linux/fs.h Wed Aug 14 11:52:06 2002
-+++ linux-2.4.19-dm/include/linux/fs.h Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/include/linux/fs.h Thu Nov 21 14:31:23 2002
@@ -219,6 +219,7 @@
BH_Wait_IO, /* 1 if we should write out this buffer */
BH_Launder, /* 1 if we can throttle on this buffer */
/*
diff -ruN linux-2.4.19/include/linux/jbd.h linux-2.4.19-dm/include/linux/jbd.h
--- linux-2.4.19/include/linux/jbd.h Wed Aug 14 11:52:07 2002
-+++ linux-2.4.19-dm/include/linux/jbd.h Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/include/linux/jbd.h Thu Nov 21 14:31:23 2002
@@ -246,7 +246,7 @@
static inline struct journal_head *bh2jh(struct buffer_head *bh)
struct jbd_revoke_table_s;
diff -ruN linux-2.4.19/include/linux/mempool.h linux-2.4.19-dm/include/linux/mempool.h
--- linux-2.4.19/include/linux/mempool.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dm/include/linux/mempool.h Thu Nov 14 13:50:32 2002
-@@ -0,0 +1,41 @@
++++ linux-2.4.19-dm/include/linux/mempool.h Thu Nov 21 14:31:05 2002
+@@ -0,0 +1,30 @@
+/*
+ * memory buffer pool support
+ */
+typedef void * (mempool_alloc_t)(int gfp_mask, void *pool_data);
+typedef void (mempool_free_t)(void *element, void *pool_data);
+
-+struct mempool_s {
-+ spinlock_t lock;
-+ int min_nr, curr_nr;
-+ struct list_head elements;
-+
-+ void *pool_data;
-+ mempool_alloc_t *alloc;
-+ mempool_free_t *free;
-+ wait_queue_head_t wait;
-+};
+extern mempool_t * mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
+ mempool_free_t *free_fn, void *pool_data);
-+extern void mempool_resize(mempool_t *pool, int new_min_nr, int gfp_mask);
++extern int mempool_resize(mempool_t *pool, int new_min_nr, int gfp_mask);
+extern void mempool_destroy(mempool_t *pool);
+extern void * mempool_alloc(mempool_t *pool, int gfp_mask);
+extern void mempool_free(void *element, mempool_t *pool);
+
-+
+/*
+ * A mempool_alloc_t and mempool_free_t that get the memory from
+ * a slab that is passed in through pool_data.
+#endif /* _LINUX_MEMPOOL_H */
diff -ruN linux-2.4.19/include/linux/vmalloc.h linux-2.4.19-dm/include/linux/vmalloc.h
--- linux-2.4.19/include/linux/vmalloc.h Wed Aug 14 11:52:09 2002
-+++ linux-2.4.19-dm/include/linux/vmalloc.h Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/include/linux/vmalloc.h Thu Nov 21 14:31:19 2002
@@ -25,6 +25,7 @@
extern void vmfree_area_pages(unsigned long address, unsigned long size);
extern int vmalloc_area_pages(unsigned long address, unsigned long size,
* Allocate any pages
diff -ruN linux-2.4.19/kernel/ksyms.c linux-2.4.19-dm/kernel/ksyms.c
--- linux-2.4.19/kernel/ksyms.c Wed Aug 14 11:52:12 2002
-+++ linux-2.4.19-dm/kernel/ksyms.c Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/kernel/ksyms.c Thu Nov 21 14:31:19 2002
@@ -109,6 +109,7 @@
EXPORT_SYMBOL(vfree);
EXPORT_SYMBOL(__vmalloc);
EXPORT_SYMBOL(max_mapnr);
diff -ruN linux-2.4.19/mm/Makefile linux-2.4.19-dm/mm/Makefile
--- linux-2.4.19/mm/Makefile Wed Aug 14 11:52:12 2002
-+++ linux-2.4.19-dm/mm/Makefile Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/mm/Makefile Thu Nov 21 14:31:01 2002
@@ -9,12 +9,12 @@
O_TARGET := mm.o
diff -ruN linux-2.4.19/mm/mempool.c linux-2.4.19-dm/mm/mempool.c
--- linux-2.4.19/mm/mempool.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.19-dm/mm/mempool.c Thu Nov 14 13:50:32 2002
-@@ -0,0 +1,295 @@
++++ linux-2.4.19-dm/mm/mempool.c Thu Nov 21 14:31:05 2002
+@@ -0,0 +1,298 @@
+/*
+ * linux/mm/mempool.c
+ *
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/mempool.h>
-+#include <linux/compiler.h>
++
++struct mempool_s {
++ spinlock_t lock;
++ int min_nr; /* nr of elements at *elements */
++ int curr_nr; /* Current nr of elements at *elements */
++ void **elements;
++
++ void *pool_data;
++ mempool_alloc_t *alloc;
++ mempool_free_t *free;
++ wait_queue_head_t wait;
++};
++
++static void add_element(mempool_t *pool, void *element)
++{
++ BUG_ON(pool->curr_nr >= pool->min_nr);
++ pool->elements[pool->curr_nr++] = element;
++}
++
++static void *remove_element(mempool_t *pool)
++{
++ BUG_ON(pool->curr_nr <= 0);
++ return pool->elements[--pool->curr_nr];
++}
++
++static void free_pool(mempool_t *pool)
++{
++ while (pool->curr_nr) {
++ void *element = remove_element(pool);
++ pool->free(element, pool->pool_data);
++ }
++ kfree(pool->elements);
++ kfree(pool);
++}
+
+/**
+ * mempool_create - create a memory pool
+ * memory pool. The pool can be used from the mempool_alloc and mempool_free
+ * functions. This function might sleep. Both the alloc_fn() and the free_fn()
+ * functions might sleep - as long as the mempool_alloc function is not called
-+ * from IRQ contexts. The element allocated by alloc_fn() must be able to
-+ * hold a struct list_head. (8 bytes on x86.)
++ * from IRQ contexts.
+ */
+mempool_t * mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
+ mempool_free_t *free_fn, void *pool_data)
+{
+ mempool_t *pool;
-+ int i;
+
+ pool = kmalloc(sizeof(*pool), GFP_KERNEL);
+ if (!pool)
+ return NULL;
+ memset(pool, 0, sizeof(*pool));
-+
++ pool->elements = kmalloc(min_nr * sizeof(void *), GFP_KERNEL);
++ if (!pool->elements) {
++ kfree(pool);
++ return NULL;
++ }
+ spin_lock_init(&pool->lock);
+ pool->min_nr = min_nr;
+ pool->pool_data = pool_data;
-+ INIT_LIST_HEAD(&pool->elements);
+ init_waitqueue_head(&pool->wait);
+ pool->alloc = alloc_fn;
+ pool->free = free_fn;
+ /*
+ * First pre-allocate the guaranteed number of buffers.
+ */
-+ for (i = 0; i < min_nr; i++) {
++ while (pool->curr_nr < pool->min_nr) {
+ void *element;
-+ struct list_head *tmp;
-+ element = pool->alloc(GFP_KERNEL, pool->pool_data);
+
++ element = pool->alloc(GFP_KERNEL, pool->pool_data);
+ if (unlikely(!element)) {
-+ /*
-+ * Not enough memory - free the allocated ones
-+ * and return:
-+ */
-+ list_for_each(tmp, &pool->elements) {
-+ element = tmp;
-+ pool->free(element, pool->pool_data);
-+ }
-+ kfree(pool);
-+
++ free_pool(pool);
+ return NULL;
+ }
-+ tmp = element;
-+ list_add(tmp, &pool->elements);
-+ pool->curr_nr++;
++ add_element(pool, element);
+ }
+ return pool;
+}
+ * while this function is running. mempool_alloc() & mempool_free()
+ * might be called (eg. from IRQ contexts) while this function executes.
+ */
-+void mempool_resize(mempool_t *pool, int new_min_nr, int gfp_mask)
++int mempool_resize(mempool_t *pool, int new_min_nr, int gfp_mask)
+{
-+ int delta;
+ void *element;
++ void **new_elements;
+ unsigned long flags;
-+ struct list_head *tmp;
+
-+ if (new_min_nr <= 0)
-+ BUG();
++ BUG_ON(new_min_nr <= 0);
+
+ spin_lock_irqsave(&pool->lock, flags);
+ if (new_min_nr < pool->min_nr) {
-+ pool->min_nr = new_min_nr;
-+ /*
-+ * Free possible excess elements.
-+ */
-+ while (pool->curr_nr > pool->min_nr) {
-+ tmp = pool->elements.next;
-+ if (tmp == &pool->elements)
-+ BUG();
-+ list_del(tmp);
-+ element = tmp;
-+ pool->curr_nr--;
++ while (pool->curr_nr > new_min_nr) {
++ element = remove_element(pool);
+ spin_unlock_irqrestore(&pool->lock, flags);
-+
+ pool->free(element, pool->pool_data);
-+
+ spin_lock_irqsave(&pool->lock, flags);
+ }
-+ spin_unlock_irqrestore(&pool->lock, flags);
-+ return;
++ pool->min_nr = new_min_nr;
++ goto out_unlock;
+ }
-+ delta = new_min_nr - pool->min_nr;
-+ pool->min_nr = new_min_nr;
+ spin_unlock_irqrestore(&pool->lock, flags);
+
-+ /*
-+ * We refill the pool up to the new treshold - but we dont
-+ * (cannot) guarantee that the refill succeeds.
-+ */
-+ while (delta) {
++ /* Grow the pool */
++ new_elements = kmalloc(new_min_nr * sizeof(*new_elements), gfp_mask);
++ if (!new_elements)
++ return -ENOMEM;
++
++ spin_lock_irqsave(&pool->lock, flags);
++ memcpy(new_elements, pool->elements,
++ pool->curr_nr * sizeof(*new_elements));
++ kfree(pool->elements);
++ pool->elements = new_elements;
++ pool->min_nr = new_min_nr;
++
++ while (pool->curr_nr < pool->min_nr) {
++ spin_unlock_irqrestore(&pool->lock, flags);
+ element = pool->alloc(gfp_mask, pool->pool_data);
+ if (!element)
-+ break;
-+ mempool_free(element, pool);
-+ delta--;
++ goto out;
++ spin_lock_irqsave(&pool->lock, flags);
++ if (pool->curr_nr < pool->min_nr)
++ add_element(pool, element);
++ else
++ kfree(element); /* Raced */
+ }
++out_unlock:
++ spin_unlock_irqrestore(&pool->lock, flags);
++out:
++ return 0;
+}
+
+/**
+ * mempool_create().
+ *
+ * this function only sleeps if the free_fn() function sleeps. The caller
-+ * has to guarantee that no mempool_alloc() nor mempool_free() happens in
-+ * this pool when calling this function.
++ * has to guarantee that all elements have been returned to the pool (ie:
++ * freed) prior to calling mempool_destroy().
+ */
+void mempool_destroy(mempool_t *pool)
+{
-+ void *element;
-+ struct list_head *head, *tmp;
-+
-+ if (!pool)
-+ return;
-+
-+ head = &pool->elements;
-+ for (tmp = head->next; tmp != head; ) {
-+ element = tmp;
-+ tmp = tmp->next;
-+ pool->free(element, pool->pool_data);
-+ pool->curr_nr--;
-+ }
-+ if (pool->curr_nr)
-+ BUG();
-+ kfree(pool);
++ if (pool->curr_nr != pool->min_nr)
++ BUG(); /* There were outstanding elements */
++ free_pool(pool);
+}
+
+/**
+{
+ void *element;
+ unsigned long flags;
-+ struct list_head *tmp;
+ int curr_nr;
+ DECLARE_WAITQUEUE(wait, current);
+ int gfp_nowait = gfp_mask & ~(__GFP_WAIT | __GFP_IO);
+
+ spin_lock_irqsave(&pool->lock, flags);
+ if (likely(pool->curr_nr)) {
-+ tmp = pool->elements.next;
-+ list_del(tmp);
-+ element = tmp;
-+ pool->curr_nr--;
++ element = remove_element(pool);
+ spin_unlock_irqrestore(&pool->lock, flags);
+ return element;
+ }
+ if (pool->curr_nr < pool->min_nr) {
+ spin_lock_irqsave(&pool->lock, flags);
+ if (pool->curr_nr < pool->min_nr) {
-+ list_add(element, &pool->elements);
-+ pool->curr_nr++;
++ add_element(pool, element);
+ spin_unlock_irqrestore(&pool->lock, flags);
+ wake_up(&pool->wait);
+ return;
+ kmem_cache_free(mem, element);
+}
+
-+
+EXPORT_SYMBOL(mempool_create);
+EXPORT_SYMBOL(mempool_resize);
+EXPORT_SYMBOL(mempool_destroy);
+EXPORT_SYMBOL(mempool_free);
+EXPORT_SYMBOL(mempool_alloc_slab);
+EXPORT_SYMBOL(mempool_free_slab);
-+
diff -ruN linux-2.4.19/mm/vmalloc.c linux-2.4.19-dm/mm/vmalloc.c
--- linux-2.4.19/mm/vmalloc.c Wed Aug 14 11:52:13 2002
-+++ linux-2.4.19-dm/mm/vmalloc.c Thu Nov 14 13:50:32 2002
++++ linux-2.4.19-dm/mm/vmalloc.c Thu Nov 21 14:31:19 2002
@@ -321,3 +321,22 @@
read_unlock(&vmlist_lock);
return buf - buf_start;