From 3f370ffcbd84aea4903f16420e773c2592d417c0 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Fri, 21 Nov 2003 18:09:38 +0000 Subject: [PATCH] 2.4.20/2.4.21 updates --- patches/common/linux-2.4.20-devmapper.patch | 417 +++++++++--------- patches/common/linux-2.4.21-devmapper.patch | 417 +++++++++--------- patches/linux-2.4.20-devmapper-ioctl.patch | 459 ++++++++++---------- patches/linux-2.4.21-devmapper-ioctl.patch | 459 ++++++++++---------- 4 files changed, 850 insertions(+), 902 deletions(-) diff --git a/patches/common/linux-2.4.20-devmapper.patch b/patches/common/linux-2.4.20-devmapper.patch index 789214a..63a84cb 100644 --- a/patches/common/linux-2.4.20-devmapper.patch +++ b/patches/common/linux-2.4.20-devmapper.patch @@ -1,5 +1,5 @@ --- linux-2.4.20/drivers/md/dm-daemon.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-daemon.c Mon Sep 1 16:32:01 2003 ++++ linux/drivers/md/dm-daemon.c Fri Nov 21 17:38:18 2003 @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2003 Sistina Software @@ -115,7 +115,7 @@ +EXPORT_SYMBOL(dm_daemon_stop); +EXPORT_SYMBOL(dm_daemon_wake); --- linux-2.4.20/drivers/md/dm-daemon.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-daemon.h Mon Sep 1 16:32:01 2003 ++++ linux/drivers/md/dm-daemon.h Fri Nov 21 17:38:18 2003 @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2003 Sistina Software @@ -147,7 +147,7 @@ + +#endif --- linux-2.4.20/drivers/md/dm-exception-store.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-exception-store.c Mon Sep 1 16:32:01 2003 ++++ linux/drivers/md/dm-exception-store.c Fri Nov 21 17:38:18 2003 @@ -0,0 +1,673 @@ +/* + * dm-snapshot.c @@ -823,8 +823,8 @@ + return 0; +} --- linux-2.4.20/drivers/md/dm-io.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-io.c Mon Sep 1 16:32:01 2003 -@@ -0,0 +1,360 @@ ++++ linux/drivers/md/dm-io.c Fri Nov 21 17:38:18 2003 +@@ -0,0 +1,361 @@ +/* + * Copyright (C) 2003 Sistina Software + * @@ -837,6 +837,7 @@ +#include +#include +#include ++#include + +/* FIXME: can we shrink this ? */ +struct io_context { @@ -1186,7 +1187,7 @@ +EXPORT_SYMBOL(dm_io_sync); +EXPORT_SYMBOL(dm_io_async); --- linux-2.4.20/drivers/md/dm-io.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-io.h Mon Sep 1 16:32:01 2003 ++++ linux/drivers/md/dm-io.h Fri Nov 21 17:38:18 2003 @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2003 Sistina Software @@ -1275,7 +1276,7 @@ + +#endif --- linux-2.4.20/drivers/md/dm-ioctl.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-ioctl.c Mon Sep 1 16:32:01 2003 ++++ linux/drivers/md/dm-ioctl.c Fri Nov 21 17:38:18 2003 @@ -0,0 +1,1284 @@ +/* + * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. @@ -1977,6 +1978,113 @@ + return r; +} + ++/* ++ * Build up the status struct for each target ++ */ ++static void retrieve_status(struct dm_table *table, struct dm_ioctl *param, ++ size_t param_size) ++{ ++ unsigned int i, num_targets; ++ struct dm_target_spec *spec; ++ char *outbuf, *outptr; ++ status_type_t type; ++ size_t remaining, len, used = 0; ++ ++ outptr = outbuf = get_result_buffer(param, param_size, &len); ++ ++ if (param->flags & DM_STATUS_TABLE_FLAG) ++ type = STATUSTYPE_TABLE; ++ else ++ type = STATUSTYPE_INFO; ++ ++ /* Get all the target info */ ++ num_targets = dm_table_get_num_targets(table); ++ for (i = 0; i < num_targets; i++) { ++ struct dm_target *ti = dm_table_get_target(table, i); ++ ++ remaining = len - (outptr - outbuf); ++ if (remaining < sizeof(struct dm_target_spec)) { ++ param->flags |= DM_BUFFER_FULL_FLAG; ++ break; ++ } ++ ++ spec = (struct dm_target_spec *) outptr; ++ ++ spec->status = 0; ++ spec->sector_start = ti->begin; ++ spec->length = ti->len; ++ strncpy(spec->target_type, ti->type->name, ++ sizeof(spec->target_type)); ++ ++ outptr += sizeof(struct dm_target_spec); ++ remaining = len - (outptr - outbuf); ++ ++ /* Get the status/table string from the target driver */ ++ if (ti->type->status) { ++ if (ti->type->status(ti, type, outptr, remaining)) { ++ param->flags |= DM_BUFFER_FULL_FLAG; ++ break; ++ } ++ } else ++ outptr[0] = '\0'; ++ ++ outptr += strlen(outptr) + 1; ++ used = param->data_start + (outptr - outbuf); ++ ++ align_ptr(outptr); ++ spec->next = outptr - outbuf; ++ } ++ ++ if (used) ++ param->data_size = used; ++ ++ param->target_count = num_targets; ++} ++ ++/* ++ * Wait for a device to report an event ++ */ ++static int dev_wait(struct dm_ioctl *param, size_t param_size) ++{ ++ int r; ++ struct mapped_device *md; ++ struct dm_table *table; ++ DECLARE_WAITQUEUE(wq, current); ++ ++ md = find_device(param); ++ if (!md) ++ return -ENXIO; ++ ++ /* ++ * Wait for a notification event ++ */ ++ set_current_state(TASK_INTERRUPTIBLE); ++ if (!dm_add_wait_queue(md, &wq, param->event_nr)) { ++ schedule(); ++ dm_remove_wait_queue(md, &wq); ++ } ++ set_current_state(TASK_RUNNING); ++ ++ /* ++ * The userland program is going to want to know what ++ * changed to trigger the event, so we may as well tell ++ * him and save an ioctl. ++ */ ++ r = __dev_status(md, param); ++ if (r) ++ goto out; ++ ++ table = dm_get_table(md); ++ if (table) { ++ retrieve_status(table, param, param_size); ++ dm_table_put(table); ++ } ++ ++ out: ++ dm_put(md); ++ return r; ++} ++ +static inline int get_mode(struct dm_ioctl *param) +{ + int mode = FMODE_READ | FMODE_WRITE; @@ -2164,69 +2272,6 @@ +} + +/* -+ * Build up the status struct for each target -+ */ -+static void retrieve_status(struct dm_table *table, struct dm_ioctl *param, -+ size_t param_size) -+{ -+ unsigned int i, num_targets; -+ struct dm_target_spec *spec; -+ char *outbuf, *outptr; -+ status_type_t type; -+ size_t remaining, len, used = 0; -+ -+ outptr = outbuf = get_result_buffer(param, param_size, &len); -+ -+ if (param->flags & DM_STATUS_TABLE_FLAG) -+ type = STATUSTYPE_TABLE; -+ else -+ type = STATUSTYPE_INFO; -+ -+ /* Get all the target info */ -+ num_targets = dm_table_get_num_targets(table); -+ for (i = 0; i < num_targets; i++) { -+ struct dm_target *ti = dm_table_get_target(table, i); -+ -+ remaining = len - (outptr - outbuf); -+ if (remaining < sizeof(struct dm_target_spec)) { -+ param->flags |= DM_BUFFER_FULL_FLAG; -+ break; -+ } -+ -+ spec = (struct dm_target_spec *) outptr; -+ -+ spec->status = 0; -+ spec->sector_start = ti->begin; -+ spec->length = ti->len; -+ strncpy(spec->target_type, ti->type->name, -+ sizeof(spec->target_type)); -+ -+ outptr += sizeof(struct dm_target_spec); -+ remaining = len - (outptr - outbuf); -+ -+ /* Get the status/table string from the target driver */ -+ if (ti->type->status) { -+ if (ti->type->status(ti, type, outptr, remaining)) { -+ param->flags |= DM_BUFFER_FULL_FLAG; -+ break; -+ } -+ } else -+ outptr[0] = '\0'; -+ -+ outptr += strlen(outptr) + 1; -+ used = param->data_start + (outptr - outbuf); -+ -+ align_ptr(outptr); -+ spec->next = outptr - outbuf; -+ } -+ -+ if (used) -+ param->data_size = used; -+ -+ param->target_count = num_targets; -+} -+ -+/* + * Return the status of a device as a text string for each + * target. + */ @@ -2255,50 +2300,6 @@ + return r; +} + -+/* -+ * Wait for a device to report an event -+ */ -+static int dev_wait(struct dm_ioctl *param, size_t param_size) -+{ -+ int r; -+ struct mapped_device *md; -+ struct dm_table *table; -+ DECLARE_WAITQUEUE(wq, current); -+ -+ md = find_device(param); -+ if (!md) -+ return -ENXIO; -+ -+ /* -+ * Wait for a notification event -+ */ -+ set_current_state(TASK_INTERRUPTIBLE); -+ if (!dm_add_wait_queue(md, &wq, param->event_nr)) { -+ schedule(); -+ dm_remove_wait_queue(md, &wq); -+ } -+ set_current_state(TASK_RUNNING); -+ -+ /* -+ * The userland program is going to want to know what -+ * changed to trigger the event, so we may as well tell -+ * him and save an ioctl. -+ */ -+ r = __dev_status(md, param); -+ if (r) -+ goto out; -+ -+ table = dm_get_table(md); -+ if (table) { -+ retrieve_status(table, param, param_size); -+ dm_table_put(table); -+ } -+ -+ out: -+ dm_put(md); -+ return r; -+} -+ +/*----------------------------------------------------------------- + * Implementation of open/close/ioctl on the special char + * device. @@ -2562,7 +2563,7 @@ + dm_hash_exit(); +} --- linux-2.4.20/drivers/md/dm-linear.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-linear.c Mon Sep 1 16:32:01 2003 ++++ linux/drivers/md/dm-linear.c Fri Nov 21 17:38:18 2003 @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. @@ -2688,8 +2689,8 @@ + DMERR("linear: unregister failed %d", r); +} --- linux-2.4.20/drivers/md/dm-log.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-log.c Mon Sep 1 16:32:01 2003 -@@ -0,0 +1,303 @@ ++++ linux/drivers/md/dm-log.c Fri Nov 21 17:38:18 2003 +@@ -0,0 +1,310 @@ +/* + * Copyright (C) 2003 Sistina Software + * @@ -2816,6 +2817,8 @@ + int sync_search; +}; + ++#define BYTE_SHIFT 3 ++ +static int core_ctr(struct dirty_log *log, sector_t dev_size, + unsigned int argc, char **argv) +{ @@ -2845,8 +2848,13 @@ + clog->region_size = region_size; + clog->region_count = region_count; + -+ bitset_size = dm_round_up((region_count + 7) >> 3, -+ sizeof(*clog->clean_bits)); ++ /* ++ * Work out how many words we need to hold the bitset. ++ */ ++ bitset_size = dm_round_up(region_count, ++ sizeof(*clog->clean_bits) << BYTE_SHIFT); ++ bitset_size >>= BYTE_SHIFT; ++ + clog->clean_bits = vmalloc(bitset_size); + if (!clog->clean_bits) { + DMWARN("couldn't allocate clean bitset"); @@ -2994,7 +3002,7 @@ +EXPORT_SYMBOL(dm_create_dirty_log); +EXPORT_SYMBOL(dm_destroy_dirty_log); --- linux-2.4.20/drivers/md/dm-log.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-log.h Mon Sep 1 16:32:01 2003 ++++ linux/drivers/md/dm-log.h Fri Nov 21 17:38:18 2003 @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2003 Sistina Software @@ -3109,7 +3117,7 @@ + +#endif --- linux-2.4.20/drivers/md/dm-raid1.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-raid1.c Mon Sep 1 16:32:01 2003 ++++ linux/drivers/md/dm-raid1.c Fri Nov 21 17:38:18 2003 @@ -0,0 +1,1294 @@ +/* + * Copyright (C) 2003 Sistina Software Limited. @@ -4158,7 +4166,7 @@ + * For now, #log_params = 1, log_type = "core" + * + */ -+#define DM_IO_PAGES 256 ++#define DM_IO_PAGES 64 +static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) +{ + int r; @@ -4406,7 +4414,7 @@ +MODULE_AUTHOR("Heinz Mauelshagen "); +MODULE_LICENSE("GPL"); --- linux-2.4.20/drivers/md/dm-snapshot.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-snapshot.c Mon Sep 1 16:32:01 2003 ++++ linux/drivers/md/dm-snapshot.c Fri Nov 21 17:38:18 2003 @@ -0,0 +1,1235 @@ +/* + * dm-snapshot.c @@ -5644,7 +5652,7 @@ + kmem_cache_destroy(exception_cache); +} --- linux-2.4.20/drivers/md/dm-snapshot.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-snapshot.h Mon Sep 1 16:32:01 2003 ++++ linux/drivers/md/dm-snapshot.h Fri Nov 21 17:38:18 2003 @@ -0,0 +1,158 @@ +/* + * dm-snapshot.c @@ -5805,7 +5813,7 @@ + +#endif --- linux-2.4.20/drivers/md/dm-stripe.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-stripe.c Mon Sep 1 16:32:01 2003 ++++ linux/drivers/md/dm-stripe.c Fri Nov 21 17:38:18 2003 @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. @@ -6066,8 +6074,8 @@ + return; +} --- linux-2.4.20/drivers/md/dm-table.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-table.c Mon Sep 1 16:32:01 2003 -@@ -0,0 +1,710 @@ ++++ linux/drivers/md/dm-table.c Fri Nov 21 17:38:18 2003 +@@ -0,0 +1,679 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * @@ -6087,7 +6095,6 @@ +#define NODE_SIZE L1_CACHE_BYTES +#define KEYS_PER_NODE (NODE_SIZE / sizeof(sector_t)) +#define CHILDREN_PER_NODE (KEYS_PER_NODE + 1) -+#define MAX_TARGET_ARGS 64 + +struct dm_table { + atomic_t holders; @@ -6183,44 +6190,11 @@ + return 0; +} + -+/* -+ * highs, and targets are managed as dynamic arrays during a -+ * table load. -+ */ -+static int alloc_targets(struct dm_table *t, unsigned int num) -+{ -+ sector_t *n_highs; -+ struct dm_target *n_targets; -+ int n = t->num_targets; -+ -+ /* -+ * Allocate both the target array and offset array at once. -+ */ -+ n_highs = (sector_t *) vcalloc(sizeof(struct dm_target) + -+ sizeof(sector_t), num); -+ if (!n_highs) -+ return -ENOMEM; -+ -+ n_targets = (struct dm_target *) (n_highs + num); -+ -+ if (n) { -+ memcpy(n_highs, t->highs, sizeof(*n_highs) * n); -+ memcpy(n_targets, t->targets, sizeof(*n_targets) * n); -+ } -+ -+ memset(n_highs + n, -1, sizeof(*n_highs) * (num - n)); -+ vfree(t->highs); -+ -+ t->num_allocated = num; -+ t->highs = n_highs; -+ t->targets = n_targets; + -+ return 0; -+} + +int dm_table_create(struct dm_table **result, int mode, unsigned num_targets) +{ -+ struct dm_table *t = kmalloc(sizeof(*t), GFP_NOIO); ++ struct dm_table *t = kmalloc(sizeof(*t), GFP_KERNEL); + + if (!t) + return -ENOMEM; @@ -6229,15 +6203,20 @@ + INIT_LIST_HEAD(&t->devices); + atomic_set(&t->holders, 1); + -+ if (!num_targets) -+ num_targets = KEYS_PER_NODE; ++ num_targets = dm_round_up(num_targets, KEYS_PER_NODE); + -+ if (alloc_targets(t, num_targets)) { ++ /* Allocate both the target array and offset array at once. */ ++ t->highs = (sector_t *) vcalloc(sizeof(struct dm_target) + ++ sizeof(sector_t), num_targets); ++ if (!t->highs) { + kfree(t); -+ t = NULL; + return -ENOMEM; + } + ++ memset(t->highs, -1, sizeof(*t->highs) * num_targets); ++ ++ t->targets = (struct dm_target *) (t->highs + num_targets); ++ t->num_allocated = num_targets; + t->mode = mode; + *result = t; + return 0; @@ -6297,17 +6276,6 @@ +} + +/* -+ * Checks to see if we need to extend highs or targets. -+ */ -+static inline int check_space(struct dm_table *t) -+{ -+ if (t->num_targets >= t->num_allocated) -+ return alloc_targets(t, t->num_allocated * 2); -+ -+ return 0; -+} -+ -+/* + * Convert a device path to a dev_t. + */ +static int lookup_device(const char *path, kdev_t *dev) @@ -6514,16 +6482,34 @@ +} + +/* ++ * Used to dynamically allocate the arg array. ++ */ ++static char **realloc_argv(unsigned *array_size, char **old_argv) ++{ ++ char **argv; ++ unsigned new_size; ++ ++ new_size = *array_size ? *array_size * 2 : 64; ++ argv = kmalloc(new_size * sizeof(*argv), GFP_KERNEL); ++ if (argv) { ++ memcpy(argv, old_argv, *array_size * sizeof(*argv)); ++ *array_size = new_size; ++ } ++ ++ kfree(old_argv); ++ return argv; ++} ++ ++/* + * Destructively splits up the argument list to pass to ctr. + */ +static int split_args(int *argc, char ***argvp, char *input) +{ -+ char *start, *end = input, *out; -+ char **argv; -+ int max_args = MAX_TARGET_ARGS; ++ char *start, *end = input, *out, **argv = NULL; ++ unsigned array_size = 0; + + *argc = 0; -+ argv = kmalloc(sizeof(*argv) * max_args, GFP_NOIO); ++ argv = realloc_argv(&array_size, argv); + if (!argv) + return -ENOMEM; + @@ -6554,19 +6540,10 @@ + } + + /* have we already filled the array ? */ -+ if ((*argc + 1) > max_args) { -+ char **argv2; -+ -+ max_args *= 2; -+ argv2 = kmalloc(sizeof(*argv2) * max_args, GFP_NOIO); -+ if (!argv2) { -+ kfree(argv); ++ if ((*argc + 1) > array_size) { ++ argv = realloc_argv(&array_size, argv); ++ if (!argv) + return -ENOMEM; -+ } -+ -+ memcpy(argv2, argv, sizeof(*argv) * *argc); -+ kfree(argv); -+ argv = argv2; + } + + /* we know this is whitespace */ @@ -6590,8 +6567,8 @@ + char **argv; + struct dm_target *tgt; + -+ if ((r = check_space(t))) -+ return r; ++ if (t->num_targets >= t->num_allocated) ++ return -ENOMEM; + + tgt = t->targets + t->num_targets; + memset(tgt, 0, sizeof(*tgt)); @@ -6779,7 +6756,7 @@ +EXPORT_SYMBOL(dm_table_event); +EXPORT_SYMBOL(dm_table_get_mode); --- linux-2.4.20/drivers/md/dm-target.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-target.c Mon Sep 1 16:32:01 2003 ++++ linux/drivers/md/dm-target.c Fri Nov 21 17:38:18 2003 @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited @@ -6970,7 +6947,7 @@ +EXPORT_SYMBOL(dm_register_target); +EXPORT_SYMBOL(dm_unregister_target); --- linux-2.4.20/drivers/md/dm.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm.c Mon Sep 1 16:32:01 2003 ++++ linux/drivers/md/dm.c Fri Nov 21 17:38:18 2003 @@ -0,0 +1,1115 @@ +/* + * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. @@ -8088,7 +8065,7 @@ + +EXPORT_SYMBOL(dm_kdevname); --- linux-2.4.20/drivers/md/dm.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm.h Mon Sep 1 16:32:01 2003 ++++ linux/drivers/md/dm.h Fri Nov 21 17:38:18 2003 @@ -0,0 +1,175 @@ +/* + * Internal header file for device mapper @@ -8266,8 +8243,8 @@ + +#endif --- linux-2.4.20/drivers/md/kcopyd.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/kcopyd.c Mon Sep 1 16:32:01 2003 -@@ -0,0 +1,656 @@ ++++ linux/drivers/md/kcopyd.c Fri Nov 21 17:38:18 2003 +@@ -0,0 +1,666 @@ +/* + * Copyright (C) 2002 Sistina Software (UK) Limited. + * @@ -8297,6 +8274,11 @@ + +static struct dm_daemon _kcopyd; + ++#define SECTORS_PER_PAGE (PAGE_SIZE / SECTOR_SIZE) ++#define SUB_JOB_SIZE 128 ++#define PAGES_PER_SUB_JOB (SUB_JOB_SIZE / SECTORS_PER_PAGE) ++#define SUB_JOB_COUNT 8 ++ +/*----------------------------------------------------------------- + * Each kcopyd client has its own little pool of preallocated + * pages for kcopyd io. @@ -8308,6 +8290,7 @@ + struct list_head pages; + unsigned int nr_pages; + unsigned int nr_free_pages; ++ unsigned int max_split; +}; + +static inline void __push_page(struct kcopyd_client *kc, struct page *p) @@ -8392,6 +8375,10 @@ + + kcopyd_put_pages(kc, &new); + kc->nr_pages += nr; ++ kc->max_split = kc->nr_pages / PAGES_PER_SUB_JOB; ++ if (kc->max_split > SUB_JOB_COUNT) ++ kc->max_split = SUB_JOB_COUNT; ++ + return 0; +} + @@ -8604,7 +8591,6 @@ + return r; +} + -+#define SECTORS_PER_PAGE (PAGE_SIZE / SECTOR_SIZE) +static int run_pages_job(struct kcopyd_job *job) +{ + int r; @@ -8692,7 +8678,6 @@ + dm_daemon_wake(&_kcopyd); +} + -+#define SUB_JOB_SIZE 128 +static void segment_complete(int read_err, + unsigned int write_err, void *context) +{ @@ -8761,17 +8746,19 @@ + * Create some little jobs that will do the move between + * them. + */ -+#define SPLIT_COUNT 8 +static void split_job(struct kcopyd_job *job) +{ -+ int i; ++ int nr; ++ ++ nr = dm_div_up(job->source.count, SUB_JOB_SIZE); ++ if (nr > job->kc->max_split) ++ nr = job->kc->max_split; + -+ atomic_set(&job->sub_jobs, SPLIT_COUNT); -+ for (i = 0; i < SPLIT_COUNT; i++) ++ atomic_set(&job->sub_jobs, nr); ++ while (nr--) + segment_complete(0, 0u, job); +} + -+#define SUB_JOB_THRESHOLD (SPLIT_COUNT * SUB_JOB_SIZE) +int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from, + unsigned int num_dests, struct io_region *dests, + unsigned int flags, kcopyd_notify_fn fn, void *context) @@ -8804,7 +8791,7 @@ + job->fn = fn; + job->context = context; + -+ if (job->source.count < SUB_JOB_THRESHOLD) ++ if (job->source.count < SUB_JOB_SIZE) + dispatch_job(job); + + else { @@ -8852,9 +8839,9 @@ + int r = 0; + struct kcopyd_client *kc; + -+ if (nr_pages * SECTORS_PER_PAGE < SUB_JOB_SIZE * SPLIT_COUNT) { ++ if (nr_pages * SECTORS_PER_PAGE < SUB_JOB_SIZE) { + DMERR("kcopyd client requested %u pages: minimum is %lu", -+ nr_pages, SUB_JOB_SIZE * SPLIT_COUNT / SECTORS_PER_PAGE); ++ nr_pages, SUB_JOB_SIZE / SECTORS_PER_PAGE); + return -ENOMEM; + } + @@ -8925,7 +8912,7 @@ +EXPORT_SYMBOL(kcopyd_copy); +EXPORT_SYMBOL(kcopyd_cancel); --- linux-2.4.20/drivers/md/kcopyd.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/kcopyd.h Mon Sep 1 16:32:01 2003 ++++ linux/drivers/md/kcopyd.h Fri Nov 21 17:38:18 2003 @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2001 Sistina Software @@ -8975,7 +8962,7 @@ + +#endif --- linux-2.4.20/include/linux/device-mapper.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/include/linux/device-mapper.h Mon Sep 1 16:32:01 2003 ++++ linux/include/linux/device-mapper.h Fri Nov 21 17:38:18 2003 @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. @@ -9082,7 +9069,7 @@ + +#endif /* _LINUX_DEVICE_MAPPER_H */ --- linux-2.4.20/include/linux/dm-ioctl.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/include/linux/dm-ioctl.h Mon Sep 1 16:32:01 2003 ++++ linux/include/linux/dm-ioctl.h Fri Nov 21 17:38:18 2003 @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2001 - 2003 Sistina Software (UK) Limited. @@ -9293,8 +9280,8 @@ + +#define DM_VERSION_MAJOR 4 +#define DM_VERSION_MINOR 0 -+#define DM_VERSION_PATCHLEVEL 4 -+#define DM_VERSION_EXTRA "-ioctl (2003-08-30)" ++#define DM_VERSION_PATCHLEVEL 5 ++#define DM_VERSION_EXTRA "-ioctl (2003-11-18)" + +/* Status bits */ +#define DM_READONLY_FLAG (1 << 0) /* In/Out */ diff --git a/patches/common/linux-2.4.21-devmapper.patch b/patches/common/linux-2.4.21-devmapper.patch index a55847f..5dc74ca 100644 --- a/patches/common/linux-2.4.21-devmapper.patch +++ b/patches/common/linux-2.4.21-devmapper.patch @@ -1,5 +1,5 @@ --- linux-2.4.21/drivers/md/dm-daemon.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-daemon.c Mon Sep 1 16:28:55 2003 ++++ linux/drivers/md/dm-daemon.c Fri Nov 21 13:31:18 2003 @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2003 Sistina Software @@ -115,7 +115,7 @@ +EXPORT_SYMBOL(dm_daemon_stop); +EXPORT_SYMBOL(dm_daemon_wake); --- linux-2.4.21/drivers/md/dm-daemon.h Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-daemon.h Mon Sep 1 16:28:55 2003 ++++ linux/drivers/md/dm-daemon.h Fri Nov 21 13:31:18 2003 @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2003 Sistina Software @@ -147,7 +147,7 @@ + +#endif --- linux-2.4.21/drivers/md/dm-exception-store.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-exception-store.c Mon Sep 1 16:28:55 2003 ++++ linux/drivers/md/dm-exception-store.c Fri Nov 21 13:31:18 2003 @@ -0,0 +1,673 @@ +/* + * dm-snapshot.c @@ -823,8 +823,8 @@ + return 0; +} --- linux-2.4.21/drivers/md/dm-io.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-io.c Mon Sep 1 16:28:55 2003 -@@ -0,0 +1,360 @@ ++++ linux/drivers/md/dm-io.c Fri Nov 21 13:31:18 2003 +@@ -0,0 +1,361 @@ +/* + * Copyright (C) 2003 Sistina Software + * @@ -837,6 +837,7 @@ +#include +#include +#include ++#include + +/* FIXME: can we shrink this ? */ +struct io_context { @@ -1186,7 +1187,7 @@ +EXPORT_SYMBOL(dm_io_sync); +EXPORT_SYMBOL(dm_io_async); --- linux-2.4.21/drivers/md/dm-io.h Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-io.h Mon Sep 1 16:28:55 2003 ++++ linux/drivers/md/dm-io.h Fri Nov 21 13:31:18 2003 @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2003 Sistina Software @@ -1275,7 +1276,7 @@ + +#endif --- linux-2.4.21/drivers/md/dm-ioctl.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-ioctl.c Mon Sep 1 16:28:55 2003 ++++ linux/drivers/md/dm-ioctl.c Fri Nov 21 13:31:18 2003 @@ -0,0 +1,1284 @@ +/* + * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. @@ -1977,6 +1978,113 @@ + return r; +} + ++/* ++ * Build up the status struct for each target ++ */ ++static void retrieve_status(struct dm_table *table, struct dm_ioctl *param, ++ size_t param_size) ++{ ++ unsigned int i, num_targets; ++ struct dm_target_spec *spec; ++ char *outbuf, *outptr; ++ status_type_t type; ++ size_t remaining, len, used = 0; ++ ++ outptr = outbuf = get_result_buffer(param, param_size, &len); ++ ++ if (param->flags & DM_STATUS_TABLE_FLAG) ++ type = STATUSTYPE_TABLE; ++ else ++ type = STATUSTYPE_INFO; ++ ++ /* Get all the target info */ ++ num_targets = dm_table_get_num_targets(table); ++ for (i = 0; i < num_targets; i++) { ++ struct dm_target *ti = dm_table_get_target(table, i); ++ ++ remaining = len - (outptr - outbuf); ++ if (remaining < sizeof(struct dm_target_spec)) { ++ param->flags |= DM_BUFFER_FULL_FLAG; ++ break; ++ } ++ ++ spec = (struct dm_target_spec *) outptr; ++ ++ spec->status = 0; ++ spec->sector_start = ti->begin; ++ spec->length = ti->len; ++ strncpy(spec->target_type, ti->type->name, ++ sizeof(spec->target_type)); ++ ++ outptr += sizeof(struct dm_target_spec); ++ remaining = len - (outptr - outbuf); ++ ++ /* Get the status/table string from the target driver */ ++ if (ti->type->status) { ++ if (ti->type->status(ti, type, outptr, remaining)) { ++ param->flags |= DM_BUFFER_FULL_FLAG; ++ break; ++ } ++ } else ++ outptr[0] = '\0'; ++ ++ outptr += strlen(outptr) + 1; ++ used = param->data_start + (outptr - outbuf); ++ ++ align_ptr(outptr); ++ spec->next = outptr - outbuf; ++ } ++ ++ if (used) ++ param->data_size = used; ++ ++ param->target_count = num_targets; ++} ++ ++/* ++ * Wait for a device to report an event ++ */ ++static int dev_wait(struct dm_ioctl *param, size_t param_size) ++{ ++ int r; ++ struct mapped_device *md; ++ struct dm_table *table; ++ DECLARE_WAITQUEUE(wq, current); ++ ++ md = find_device(param); ++ if (!md) ++ return -ENXIO; ++ ++ /* ++ * Wait for a notification event ++ */ ++ set_current_state(TASK_INTERRUPTIBLE); ++ if (!dm_add_wait_queue(md, &wq, param->event_nr)) { ++ schedule(); ++ dm_remove_wait_queue(md, &wq); ++ } ++ set_current_state(TASK_RUNNING); ++ ++ /* ++ * The userland program is going to want to know what ++ * changed to trigger the event, so we may as well tell ++ * him and save an ioctl. ++ */ ++ r = __dev_status(md, param); ++ if (r) ++ goto out; ++ ++ table = dm_get_table(md); ++ if (table) { ++ retrieve_status(table, param, param_size); ++ dm_table_put(table); ++ } ++ ++ out: ++ dm_put(md); ++ return r; ++} ++ +static inline int get_mode(struct dm_ioctl *param) +{ + int mode = FMODE_READ | FMODE_WRITE; @@ -2164,69 +2272,6 @@ +} + +/* -+ * Build up the status struct for each target -+ */ -+static void retrieve_status(struct dm_table *table, struct dm_ioctl *param, -+ size_t param_size) -+{ -+ unsigned int i, num_targets; -+ struct dm_target_spec *spec; -+ char *outbuf, *outptr; -+ status_type_t type; -+ size_t remaining, len, used = 0; -+ -+ outptr = outbuf = get_result_buffer(param, param_size, &len); -+ -+ if (param->flags & DM_STATUS_TABLE_FLAG) -+ type = STATUSTYPE_TABLE; -+ else -+ type = STATUSTYPE_INFO; -+ -+ /* Get all the target info */ -+ num_targets = dm_table_get_num_targets(table); -+ for (i = 0; i < num_targets; i++) { -+ struct dm_target *ti = dm_table_get_target(table, i); -+ -+ remaining = len - (outptr - outbuf); -+ if (remaining < sizeof(struct dm_target_spec)) { -+ param->flags |= DM_BUFFER_FULL_FLAG; -+ break; -+ } -+ -+ spec = (struct dm_target_spec *) outptr; -+ -+ spec->status = 0; -+ spec->sector_start = ti->begin; -+ spec->length = ti->len; -+ strncpy(spec->target_type, ti->type->name, -+ sizeof(spec->target_type)); -+ -+ outptr += sizeof(struct dm_target_spec); -+ remaining = len - (outptr - outbuf); -+ -+ /* Get the status/table string from the target driver */ -+ if (ti->type->status) { -+ if (ti->type->status(ti, type, outptr, remaining)) { -+ param->flags |= DM_BUFFER_FULL_FLAG; -+ break; -+ } -+ } else -+ outptr[0] = '\0'; -+ -+ outptr += strlen(outptr) + 1; -+ used = param->data_start + (outptr - outbuf); -+ -+ align_ptr(outptr); -+ spec->next = outptr - outbuf; -+ } -+ -+ if (used) -+ param->data_size = used; -+ -+ param->target_count = num_targets; -+} -+ -+/* + * Return the status of a device as a text string for each + * target. + */ @@ -2255,50 +2300,6 @@ + return r; +} + -+/* -+ * Wait for a device to report an event -+ */ -+static int dev_wait(struct dm_ioctl *param, size_t param_size) -+{ -+ int r; -+ struct mapped_device *md; -+ struct dm_table *table; -+ DECLARE_WAITQUEUE(wq, current); -+ -+ md = find_device(param); -+ if (!md) -+ return -ENXIO; -+ -+ /* -+ * Wait for a notification event -+ */ -+ set_current_state(TASK_INTERRUPTIBLE); -+ if (!dm_add_wait_queue(md, &wq, param->event_nr)) { -+ schedule(); -+ dm_remove_wait_queue(md, &wq); -+ } -+ set_current_state(TASK_RUNNING); -+ -+ /* -+ * The userland program is going to want to know what -+ * changed to trigger the event, so we may as well tell -+ * him and save an ioctl. -+ */ -+ r = __dev_status(md, param); -+ if (r) -+ goto out; -+ -+ table = dm_get_table(md); -+ if (table) { -+ retrieve_status(table, param, param_size); -+ dm_table_put(table); -+ } -+ -+ out: -+ dm_put(md); -+ return r; -+} -+ +/*----------------------------------------------------------------- + * Implementation of open/close/ioctl on the special char + * device. @@ -2562,7 +2563,7 @@ + dm_hash_exit(); +} --- linux-2.4.21/drivers/md/dm-linear.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-linear.c Mon Sep 1 16:28:55 2003 ++++ linux/drivers/md/dm-linear.c Fri Nov 21 13:31:18 2003 @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. @@ -2688,8 +2689,8 @@ + DMERR("linear: unregister failed %d", r); +} --- linux-2.4.21/drivers/md/dm-log.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-log.c Mon Sep 1 16:28:55 2003 -@@ -0,0 +1,303 @@ ++++ linux/drivers/md/dm-log.c Fri Nov 21 13:31:18 2003 +@@ -0,0 +1,310 @@ +/* + * Copyright (C) 2003 Sistina Software + * @@ -2816,6 +2817,8 @@ + int sync_search; +}; + ++#define BYTE_SHIFT 3 ++ +static int core_ctr(struct dirty_log *log, sector_t dev_size, + unsigned int argc, char **argv) +{ @@ -2845,8 +2848,13 @@ + clog->region_size = region_size; + clog->region_count = region_count; + -+ bitset_size = dm_round_up((region_count + 7) >> 3, -+ sizeof(*clog->clean_bits)); ++ /* ++ * Work out how many words we need to hold the bitset. ++ */ ++ bitset_size = dm_round_up(region_count, ++ sizeof(*clog->clean_bits) << BYTE_SHIFT); ++ bitset_size >>= BYTE_SHIFT; ++ + clog->clean_bits = vmalloc(bitset_size); + if (!clog->clean_bits) { + DMWARN("couldn't allocate clean bitset"); @@ -2994,7 +3002,7 @@ +EXPORT_SYMBOL(dm_create_dirty_log); +EXPORT_SYMBOL(dm_destroy_dirty_log); --- linux-2.4.21/drivers/md/dm-log.h Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-log.h Mon Sep 1 16:28:55 2003 ++++ linux/drivers/md/dm-log.h Fri Nov 21 13:31:18 2003 @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2003 Sistina Software @@ -3109,7 +3117,7 @@ + +#endif --- linux-2.4.21/drivers/md/dm-raid1.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-raid1.c Mon Sep 1 16:28:55 2003 ++++ linux/drivers/md/dm-raid1.c Fri Nov 21 13:31:18 2003 @@ -0,0 +1,1294 @@ +/* + * Copyright (C) 2003 Sistina Software Limited. @@ -4158,7 +4166,7 @@ + * For now, #log_params = 1, log_type = "core" + * + */ -+#define DM_IO_PAGES 256 ++#define DM_IO_PAGES 64 +static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) +{ + int r; @@ -4406,7 +4414,7 @@ +MODULE_AUTHOR("Heinz Mauelshagen "); +MODULE_LICENSE("GPL"); --- linux-2.4.21/drivers/md/dm-snapshot.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-snapshot.c Mon Sep 1 16:28:55 2003 ++++ linux/drivers/md/dm-snapshot.c Fri Nov 21 13:31:18 2003 @@ -0,0 +1,1235 @@ +/* + * dm-snapshot.c @@ -5644,7 +5652,7 @@ + kmem_cache_destroy(exception_cache); +} --- linux-2.4.21/drivers/md/dm-snapshot.h Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-snapshot.h Mon Sep 1 16:28:55 2003 ++++ linux/drivers/md/dm-snapshot.h Fri Nov 21 13:31:18 2003 @@ -0,0 +1,158 @@ +/* + * dm-snapshot.c @@ -5805,7 +5813,7 @@ + +#endif --- linux-2.4.21/drivers/md/dm-stripe.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-stripe.c Mon Sep 1 16:28:55 2003 ++++ linux/drivers/md/dm-stripe.c Fri Nov 21 13:31:18 2003 @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. @@ -6066,8 +6074,8 @@ + return; +} --- linux-2.4.21/drivers/md/dm-table.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-table.c Mon Sep 1 16:28:55 2003 -@@ -0,0 +1,710 @@ ++++ linux/drivers/md/dm-table.c Fri Nov 21 13:31:18 2003 +@@ -0,0 +1,679 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * @@ -6087,7 +6095,6 @@ +#define NODE_SIZE L1_CACHE_BYTES +#define KEYS_PER_NODE (NODE_SIZE / sizeof(sector_t)) +#define CHILDREN_PER_NODE (KEYS_PER_NODE + 1) -+#define MAX_TARGET_ARGS 64 + +struct dm_table { + atomic_t holders; @@ -6183,44 +6190,11 @@ + return 0; +} + -+/* -+ * highs, and targets are managed as dynamic arrays during a -+ * table load. -+ */ -+static int alloc_targets(struct dm_table *t, unsigned int num) -+{ -+ sector_t *n_highs; -+ struct dm_target *n_targets; -+ int n = t->num_targets; -+ -+ /* -+ * Allocate both the target array and offset array at once. -+ */ -+ n_highs = (sector_t *) vcalloc(sizeof(struct dm_target) + -+ sizeof(sector_t), num); -+ if (!n_highs) -+ return -ENOMEM; -+ -+ n_targets = (struct dm_target *) (n_highs + num); -+ -+ if (n) { -+ memcpy(n_highs, t->highs, sizeof(*n_highs) * n); -+ memcpy(n_targets, t->targets, sizeof(*n_targets) * n); -+ } -+ -+ memset(n_highs + n, -1, sizeof(*n_highs) * (num - n)); -+ vfree(t->highs); -+ -+ t->num_allocated = num; -+ t->highs = n_highs; -+ t->targets = n_targets; + -+ return 0; -+} + +int dm_table_create(struct dm_table **result, int mode, unsigned num_targets) +{ -+ struct dm_table *t = kmalloc(sizeof(*t), GFP_NOIO); ++ struct dm_table *t = kmalloc(sizeof(*t), GFP_KERNEL); + + if (!t) + return -ENOMEM; @@ -6229,15 +6203,20 @@ + INIT_LIST_HEAD(&t->devices); + atomic_set(&t->holders, 1); + -+ if (!num_targets) -+ num_targets = KEYS_PER_NODE; ++ num_targets = dm_round_up(num_targets, KEYS_PER_NODE); + -+ if (alloc_targets(t, num_targets)) { ++ /* Allocate both the target array and offset array at once. */ ++ t->highs = (sector_t *) vcalloc(sizeof(struct dm_target) + ++ sizeof(sector_t), num_targets); ++ if (!t->highs) { + kfree(t); -+ t = NULL; + return -ENOMEM; + } + ++ memset(t->highs, -1, sizeof(*t->highs) * num_targets); ++ ++ t->targets = (struct dm_target *) (t->highs + num_targets); ++ t->num_allocated = num_targets; + t->mode = mode; + *result = t; + return 0; @@ -6297,17 +6276,6 @@ +} + +/* -+ * Checks to see if we need to extend highs or targets. -+ */ -+static inline int check_space(struct dm_table *t) -+{ -+ if (t->num_targets >= t->num_allocated) -+ return alloc_targets(t, t->num_allocated * 2); -+ -+ return 0; -+} -+ -+/* + * Convert a device path to a dev_t. + */ +static int lookup_device(const char *path, kdev_t *dev) @@ -6514,16 +6482,34 @@ +} + +/* ++ * Used to dynamically allocate the arg array. ++ */ ++static char **realloc_argv(unsigned *array_size, char **old_argv) ++{ ++ char **argv; ++ unsigned new_size; ++ ++ new_size = *array_size ? *array_size * 2 : 64; ++ argv = kmalloc(new_size * sizeof(*argv), GFP_KERNEL); ++ if (argv) { ++ memcpy(argv, old_argv, *array_size * sizeof(*argv)); ++ *array_size = new_size; ++ } ++ ++ kfree(old_argv); ++ return argv; ++} ++ ++/* + * Destructively splits up the argument list to pass to ctr. + */ +static int split_args(int *argc, char ***argvp, char *input) +{ -+ char *start, *end = input, *out; -+ char **argv; -+ int max_args = MAX_TARGET_ARGS; ++ char *start, *end = input, *out, **argv = NULL; ++ unsigned array_size = 0; + + *argc = 0; -+ argv = kmalloc(sizeof(*argv) * max_args, GFP_NOIO); ++ argv = realloc_argv(&array_size, argv); + if (!argv) + return -ENOMEM; + @@ -6554,19 +6540,10 @@ + } + + /* have we already filled the array ? */ -+ if ((*argc + 1) > max_args) { -+ char **argv2; -+ -+ max_args *= 2; -+ argv2 = kmalloc(sizeof(*argv2) * max_args, GFP_NOIO); -+ if (!argv2) { -+ kfree(argv); ++ if ((*argc + 1) > array_size) { ++ argv = realloc_argv(&array_size, argv); ++ if (!argv) + return -ENOMEM; -+ } -+ -+ memcpy(argv2, argv, sizeof(*argv) * *argc); -+ kfree(argv); -+ argv = argv2; + } + + /* we know this is whitespace */ @@ -6590,8 +6567,8 @@ + char **argv; + struct dm_target *tgt; + -+ if ((r = check_space(t))) -+ return r; ++ if (t->num_targets >= t->num_allocated) ++ return -ENOMEM; + + tgt = t->targets + t->num_targets; + memset(tgt, 0, sizeof(*tgt)); @@ -6779,7 +6756,7 @@ +EXPORT_SYMBOL(dm_table_event); +EXPORT_SYMBOL(dm_table_get_mode); --- linux-2.4.21/drivers/md/dm-target.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-target.c Mon Sep 1 16:28:55 2003 ++++ linux/drivers/md/dm-target.c Fri Nov 21 13:31:18 2003 @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited @@ -6970,7 +6947,7 @@ +EXPORT_SYMBOL(dm_register_target); +EXPORT_SYMBOL(dm_unregister_target); --- linux-2.4.21/drivers/md/dm.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm.c Mon Sep 1 16:28:55 2003 ++++ linux/drivers/md/dm.c Fri Nov 21 13:31:18 2003 @@ -0,0 +1,1115 @@ +/* + * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. @@ -8088,7 +8065,7 @@ + +EXPORT_SYMBOL(dm_kdevname); --- linux-2.4.21/drivers/md/dm.h Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm.h Mon Sep 1 16:28:55 2003 ++++ linux/drivers/md/dm.h Fri Nov 21 13:31:18 2003 @@ -0,0 +1,175 @@ +/* + * Internal header file for device mapper @@ -8266,8 +8243,8 @@ + +#endif --- linux-2.4.21/drivers/md/kcopyd.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/kcopyd.c Mon Sep 1 16:28:55 2003 -@@ -0,0 +1,656 @@ ++++ linux/drivers/md/kcopyd.c Fri Nov 21 13:31:18 2003 +@@ -0,0 +1,666 @@ +/* + * Copyright (C) 2002 Sistina Software (UK) Limited. + * @@ -8297,6 +8274,11 @@ + +static struct dm_daemon _kcopyd; + ++#define SECTORS_PER_PAGE (PAGE_SIZE / SECTOR_SIZE) ++#define SUB_JOB_SIZE 128 ++#define PAGES_PER_SUB_JOB (SUB_JOB_SIZE / SECTORS_PER_PAGE) ++#define SUB_JOB_COUNT 8 ++ +/*----------------------------------------------------------------- + * Each kcopyd client has its own little pool of preallocated + * pages for kcopyd io. @@ -8308,6 +8290,7 @@ + struct list_head pages; + unsigned int nr_pages; + unsigned int nr_free_pages; ++ unsigned int max_split; +}; + +static inline void __push_page(struct kcopyd_client *kc, struct page *p) @@ -8392,6 +8375,10 @@ + + kcopyd_put_pages(kc, &new); + kc->nr_pages += nr; ++ kc->max_split = kc->nr_pages / PAGES_PER_SUB_JOB; ++ if (kc->max_split > SUB_JOB_COUNT) ++ kc->max_split = SUB_JOB_COUNT; ++ + return 0; +} + @@ -8604,7 +8591,6 @@ + return r; +} + -+#define SECTORS_PER_PAGE (PAGE_SIZE / SECTOR_SIZE) +static int run_pages_job(struct kcopyd_job *job) +{ + int r; @@ -8692,7 +8678,6 @@ + dm_daemon_wake(&_kcopyd); +} + -+#define SUB_JOB_SIZE 128 +static void segment_complete(int read_err, + unsigned int write_err, void *context) +{ @@ -8761,17 +8746,19 @@ + * Create some little jobs that will do the move between + * them. + */ -+#define SPLIT_COUNT 8 +static void split_job(struct kcopyd_job *job) +{ -+ int i; ++ int nr; ++ ++ nr = dm_div_up(job->source.count, SUB_JOB_SIZE); ++ if (nr > job->kc->max_split) ++ nr = job->kc->max_split; + -+ atomic_set(&job->sub_jobs, SPLIT_COUNT); -+ for (i = 0; i < SPLIT_COUNT; i++) ++ atomic_set(&job->sub_jobs, nr); ++ while (nr--) + segment_complete(0, 0u, job); +} + -+#define SUB_JOB_THRESHOLD (SPLIT_COUNT * SUB_JOB_SIZE) +int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from, + unsigned int num_dests, struct io_region *dests, + unsigned int flags, kcopyd_notify_fn fn, void *context) @@ -8804,7 +8791,7 @@ + job->fn = fn; + job->context = context; + -+ if (job->source.count < SUB_JOB_THRESHOLD) ++ if (job->source.count < SUB_JOB_SIZE) + dispatch_job(job); + + else { @@ -8852,9 +8839,9 @@ + int r = 0; + struct kcopyd_client *kc; + -+ if (nr_pages * SECTORS_PER_PAGE < SUB_JOB_SIZE * SPLIT_COUNT) { ++ if (nr_pages * SECTORS_PER_PAGE < SUB_JOB_SIZE) { + DMERR("kcopyd client requested %u pages: minimum is %lu", -+ nr_pages, SUB_JOB_SIZE * SPLIT_COUNT / SECTORS_PER_PAGE); ++ nr_pages, SUB_JOB_SIZE / SECTORS_PER_PAGE); + return -ENOMEM; + } + @@ -8925,7 +8912,7 @@ +EXPORT_SYMBOL(kcopyd_copy); +EXPORT_SYMBOL(kcopyd_cancel); --- linux-2.4.21/drivers/md/kcopyd.h Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/kcopyd.h Mon Sep 1 16:28:55 2003 ++++ linux/drivers/md/kcopyd.h Fri Nov 21 13:31:18 2003 @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2001 Sistina Software @@ -8975,7 +8962,7 @@ + +#endif --- linux-2.4.21/include/linux/device-mapper.h Thu Jan 1 01:00:00 1970 -+++ linux/include/linux/device-mapper.h Mon Sep 1 16:28:55 2003 ++++ linux/include/linux/device-mapper.h Fri Nov 21 13:31:18 2003 @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. @@ -9082,7 +9069,7 @@ + +#endif /* _LINUX_DEVICE_MAPPER_H */ --- linux-2.4.21/include/linux/dm-ioctl.h Thu Jan 1 01:00:00 1970 -+++ linux/include/linux/dm-ioctl.h Mon Sep 1 16:28:55 2003 ++++ linux/include/linux/dm-ioctl.h Fri Nov 21 13:31:18 2003 @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2001 - 2003 Sistina Software (UK) Limited. @@ -9293,8 +9280,8 @@ + +#define DM_VERSION_MAJOR 4 +#define DM_VERSION_MINOR 0 -+#define DM_VERSION_PATCHLEVEL 4 -+#define DM_VERSION_EXTRA "-ioctl (2003-08-30)" ++#define DM_VERSION_PATCHLEVEL 5 ++#define DM_VERSION_EXTRA "-ioctl (2003-11-18)" + +/* Status bits */ +#define DM_READONLY_FLAG (1 << 0) /* In/Out */ diff --git a/patches/linux-2.4.20-devmapper-ioctl.patch b/patches/linux-2.4.20-devmapper-ioctl.patch index 8111515..af52a7e 100644 --- a/patches/linux-2.4.20-devmapper-ioctl.patch +++ b/patches/linux-2.4.20-devmapper-ioctl.patch @@ -1,5 +1,5 @@ --- linux-2.4.20/Documentation/Configure.help Fri Jan 10 16:33:55 2003 -+++ linux-2.4.20-dm-release4/Documentation/Configure.help Mon Sep 1 16:33:46 2003 ++++ linux/Documentation/Configure.help Fri Nov 21 18:01:11 2003 @@ -1822,6 +1822,20 @@ want), say M here and read . The module will be called lvm-mod.o. @@ -22,7 +22,7 @@ CONFIG_MD Support multiple physical spindles through a single logical device. --- linux-2.4.20/MAINTAINERS Fri Jan 10 16:33:49 2003 -+++ linux-2.4.20-dm-release4/MAINTAINERS Mon Sep 1 16:33:46 2003 ++++ linux/MAINTAINERS Fri Nov 21 18:01:11 2003 @@ -439,6 +439,13 @@ W: http://www.debian.org/~dz/i8k/ S: Maintained @@ -38,7 +38,7 @@ P: H. Peter Anvin M: hpa@zytor.com --- linux-2.4.20/arch/mips64/kernel/ioctl32.c Fri Jan 10 16:34:18 2003 -+++ linux-2.4.20-dm-release4/arch/mips64/kernel/ioctl32.c Mon Sep 1 16:33:46 2003 ++++ linux/arch/mips64/kernel/ioctl32.c Fri Nov 21 18:00:58 2003 @@ -33,6 +33,7 @@ #include #include @@ -71,7 +71,7 @@ IOCTL32_DEFAULT(MTIOCTOP), /* mtio.h ioctls */ IOCTL32_HANDLER(MTIOCGET32, mt_ioctl_trans), --- linux-2.4.20/arch/parisc/kernel/ioctl32.c Fri Jan 10 16:34:19 2003 -+++ linux-2.4.20-dm-release4/arch/parisc/kernel/ioctl32.c Mon Sep 1 16:33:46 2003 ++++ linux/arch/parisc/kernel/ioctl32.c Fri Nov 21 18:00:58 2003 @@ -55,6 +55,7 @@ #define max max */ #include @@ -104,7 +104,7 @@ COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC) COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID) --- linux-2.4.20/arch/ppc64/kernel/ioctl32.c Fri Jan 10 16:34:24 2003 -+++ linux-2.4.20-dm-release4/arch/ppc64/kernel/ioctl32.c Mon Sep 1 16:33:46 2003 ++++ linux/arch/ppc64/kernel/ioctl32.c Fri Nov 21 18:00:58 2003 @@ -66,6 +66,7 @@ #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) #include @@ -137,7 +137,7 @@ COMPATIBLE_IOCTL(SIOCDEVPRIVATE), COMPATIBLE_IOCTL(SIOCDEVPRIVATE+1), --- linux-2.4.20/arch/s390x/kernel/ioctl32.c Fri Jan 10 16:34:26 2003 -+++ linux-2.4.20-dm-release4/arch/s390x/kernel/ioctl32.c Mon Sep 1 16:33:46 2003 ++++ linux/arch/s390x/kernel/ioctl32.c Fri Nov 21 18:00:58 2003 @@ -25,6 +25,7 @@ #include #include @@ -168,7 +168,7 @@ IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32), IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf), --- linux-2.4.20/arch/sparc64/kernel/ioctl32.c Fri Jan 10 16:34:30 2003 -+++ linux-2.4.20-dm-release4/arch/sparc64/kernel/ioctl32.c Mon Sep 1 16:33:46 2003 ++++ linux/arch/sparc64/kernel/ioctl32.c Fri Nov 21 18:00:58 2003 @@ -55,6 +55,7 @@ #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) #include @@ -202,7 +202,7 @@ HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob) HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob) --- linux-2.4.20/arch/x86_64/ia32/ia32_ioctl.c Fri Jan 10 16:34:32 2003 -+++ linux-2.4.20-dm-release4/arch/x86_64/ia32/ia32_ioctl.c Mon Sep 1 16:33:46 2003 ++++ linux/arch/x86_64/ia32/ia32_ioctl.c Fri Nov 21 18:00:58 2003 @@ -62,6 +62,7 @@ #define max max #include @@ -235,7 +235,7 @@ COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC) COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID) --- linux-2.4.20/drivers/md/Config.in Fri Jan 10 16:34:50 2003 -+++ linux-2.4.20-dm-release4/drivers/md/Config.in Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/Config.in Fri Nov 21 18:01:11 2003 @@ -14,5 +14,7 @@ dep_tristate ' Multipath I/O support' CONFIG_MD_MULTIPATH $CONFIG_BLK_DEV_MD @@ -245,7 +245,7 @@ endmenu --- linux-2.4.20/drivers/md/Makefile Fri Jan 10 16:34:50 2003 -+++ linux-2.4.20-dm-release4/drivers/md/Makefile Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/Makefile Fri Nov 21 18:01:19 2003 @@ -4,24 +4,41 @@ O_TARGET := mddev.o @@ -298,7 +298,7 @@ + $(LD) -r -o $@ $(dm-mirror-mod-objs) + --- linux-2.4.20/drivers/md/dm-daemon.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-daemon.c Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/dm-daemon.c Fri Nov 21 18:01:15 2003 @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2003 Sistina Software @@ -414,7 +414,7 @@ +EXPORT_SYMBOL(dm_daemon_stop); +EXPORT_SYMBOL(dm_daemon_wake); --- linux-2.4.20/drivers/md/dm-daemon.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-daemon.h Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/dm-daemon.h Fri Nov 21 18:01:15 2003 @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2003 Sistina Software @@ -446,7 +446,7 @@ + +#endif --- linux-2.4.20/drivers/md/dm-exception-store.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-exception-store.c Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/dm-exception-store.c Fri Nov 21 18:01:15 2003 @@ -0,0 +1,673 @@ +/* + * dm-snapshot.c @@ -1122,8 +1122,8 @@ + return 0; +} --- linux-2.4.20/drivers/md/dm-io.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-io.c Mon Sep 1 16:33:46 2003 -@@ -0,0 +1,360 @@ ++++ linux/drivers/md/dm-io.c Fri Nov 21 18:01:15 2003 +@@ -0,0 +1,361 @@ +/* + * Copyright (C) 2003 Sistina Software + * @@ -1136,6 +1136,7 @@ +#include +#include +#include ++#include + +/* FIXME: can we shrink this ? */ +struct io_context { @@ -1485,7 +1486,7 @@ +EXPORT_SYMBOL(dm_io_sync); +EXPORT_SYMBOL(dm_io_async); --- linux-2.4.20/drivers/md/dm-io.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-io.h Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/dm-io.h Fri Nov 21 18:01:15 2003 @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2003 Sistina Software @@ -1574,7 +1575,7 @@ + +#endif --- linux-2.4.20/drivers/md/dm-ioctl.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-ioctl.c Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/dm-ioctl.c Fri Nov 21 18:01:15 2003 @@ -0,0 +1,1284 @@ +/* + * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. @@ -2276,6 +2277,113 @@ + return r; +} + ++/* ++ * Build up the status struct for each target ++ */ ++static void retrieve_status(struct dm_table *table, struct dm_ioctl *param, ++ size_t param_size) ++{ ++ unsigned int i, num_targets; ++ struct dm_target_spec *spec; ++ char *outbuf, *outptr; ++ status_type_t type; ++ size_t remaining, len, used = 0; ++ ++ outptr = outbuf = get_result_buffer(param, param_size, &len); ++ ++ if (param->flags & DM_STATUS_TABLE_FLAG) ++ type = STATUSTYPE_TABLE; ++ else ++ type = STATUSTYPE_INFO; ++ ++ /* Get all the target info */ ++ num_targets = dm_table_get_num_targets(table); ++ for (i = 0; i < num_targets; i++) { ++ struct dm_target *ti = dm_table_get_target(table, i); ++ ++ remaining = len - (outptr - outbuf); ++ if (remaining < sizeof(struct dm_target_spec)) { ++ param->flags |= DM_BUFFER_FULL_FLAG; ++ break; ++ } ++ ++ spec = (struct dm_target_spec *) outptr; ++ ++ spec->status = 0; ++ spec->sector_start = ti->begin; ++ spec->length = ti->len; ++ strncpy(spec->target_type, ti->type->name, ++ sizeof(spec->target_type)); ++ ++ outptr += sizeof(struct dm_target_spec); ++ remaining = len - (outptr - outbuf); ++ ++ /* Get the status/table string from the target driver */ ++ if (ti->type->status) { ++ if (ti->type->status(ti, type, outptr, remaining)) { ++ param->flags |= DM_BUFFER_FULL_FLAG; ++ break; ++ } ++ } else ++ outptr[0] = '\0'; ++ ++ outptr += strlen(outptr) + 1; ++ used = param->data_start + (outptr - outbuf); ++ ++ align_ptr(outptr); ++ spec->next = outptr - outbuf; ++ } ++ ++ if (used) ++ param->data_size = used; ++ ++ param->target_count = num_targets; ++} ++ ++/* ++ * Wait for a device to report an event ++ */ ++static int dev_wait(struct dm_ioctl *param, size_t param_size) ++{ ++ int r; ++ struct mapped_device *md; ++ struct dm_table *table; ++ DECLARE_WAITQUEUE(wq, current); ++ ++ md = find_device(param); ++ if (!md) ++ return -ENXIO; ++ ++ /* ++ * Wait for a notification event ++ */ ++ set_current_state(TASK_INTERRUPTIBLE); ++ if (!dm_add_wait_queue(md, &wq, param->event_nr)) { ++ schedule(); ++ dm_remove_wait_queue(md, &wq); ++ } ++ set_current_state(TASK_RUNNING); ++ ++ /* ++ * The userland program is going to want to know what ++ * changed to trigger the event, so we may as well tell ++ * him and save an ioctl. ++ */ ++ r = __dev_status(md, param); ++ if (r) ++ goto out; ++ ++ table = dm_get_table(md); ++ if (table) { ++ retrieve_status(table, param, param_size); ++ dm_table_put(table); ++ } ++ ++ out: ++ dm_put(md); ++ return r; ++} ++ +static inline int get_mode(struct dm_ioctl *param) +{ + int mode = FMODE_READ | FMODE_WRITE; @@ -2463,69 +2571,6 @@ +} + +/* -+ * Build up the status struct for each target -+ */ -+static void retrieve_status(struct dm_table *table, struct dm_ioctl *param, -+ size_t param_size) -+{ -+ unsigned int i, num_targets; -+ struct dm_target_spec *spec; -+ char *outbuf, *outptr; -+ status_type_t type; -+ size_t remaining, len, used = 0; -+ -+ outptr = outbuf = get_result_buffer(param, param_size, &len); -+ -+ if (param->flags & DM_STATUS_TABLE_FLAG) -+ type = STATUSTYPE_TABLE; -+ else -+ type = STATUSTYPE_INFO; -+ -+ /* Get all the target info */ -+ num_targets = dm_table_get_num_targets(table); -+ for (i = 0; i < num_targets; i++) { -+ struct dm_target *ti = dm_table_get_target(table, i); -+ -+ remaining = len - (outptr - outbuf); -+ if (remaining < sizeof(struct dm_target_spec)) { -+ param->flags |= DM_BUFFER_FULL_FLAG; -+ break; -+ } -+ -+ spec = (struct dm_target_spec *) outptr; -+ -+ spec->status = 0; -+ spec->sector_start = ti->begin; -+ spec->length = ti->len; -+ strncpy(spec->target_type, ti->type->name, -+ sizeof(spec->target_type)); -+ -+ outptr += sizeof(struct dm_target_spec); -+ remaining = len - (outptr - outbuf); -+ -+ /* Get the status/table string from the target driver */ -+ if (ti->type->status) { -+ if (ti->type->status(ti, type, outptr, remaining)) { -+ param->flags |= DM_BUFFER_FULL_FLAG; -+ break; -+ } -+ } else -+ outptr[0] = '\0'; -+ -+ outptr += strlen(outptr) + 1; -+ used = param->data_start + (outptr - outbuf); -+ -+ align_ptr(outptr); -+ spec->next = outptr - outbuf; -+ } -+ -+ if (used) -+ param->data_size = used; -+ -+ param->target_count = num_targets; -+} -+ -+/* + * Return the status of a device as a text string for each + * target. + */ @@ -2554,50 +2599,6 @@ + return r; +} + -+/* -+ * Wait for a device to report an event -+ */ -+static int dev_wait(struct dm_ioctl *param, size_t param_size) -+{ -+ int r; -+ struct mapped_device *md; -+ struct dm_table *table; -+ DECLARE_WAITQUEUE(wq, current); -+ -+ md = find_device(param); -+ if (!md) -+ return -ENXIO; -+ -+ /* -+ * Wait for a notification event -+ */ -+ set_current_state(TASK_INTERRUPTIBLE); -+ if (!dm_add_wait_queue(md, &wq, param->event_nr)) { -+ schedule(); -+ dm_remove_wait_queue(md, &wq); -+ } -+ set_current_state(TASK_RUNNING); -+ -+ /* -+ * The userland program is going to want to know what -+ * changed to trigger the event, so we may as well tell -+ * him and save an ioctl. -+ */ -+ r = __dev_status(md, param); -+ if (r) -+ goto out; -+ -+ table = dm_get_table(md); -+ if (table) { -+ retrieve_status(table, param, param_size); -+ dm_table_put(table); -+ } -+ -+ out: -+ dm_put(md); -+ return r; -+} -+ +/*----------------------------------------------------------------- + * Implementation of open/close/ioctl on the special char + * device. @@ -2861,7 +2862,7 @@ + dm_hash_exit(); +} --- linux-2.4.20/drivers/md/dm-linear.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-linear.c Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/dm-linear.c Fri Nov 21 18:01:15 2003 @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. @@ -2987,8 +2988,8 @@ + DMERR("linear: unregister failed %d", r); +} --- linux-2.4.20/drivers/md/dm-log.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-log.c Mon Sep 1 16:33:46 2003 -@@ -0,0 +1,303 @@ ++++ linux/drivers/md/dm-log.c Fri Nov 21 18:01:15 2003 +@@ -0,0 +1,310 @@ +/* + * Copyright (C) 2003 Sistina Software + * @@ -3115,6 +3116,8 @@ + int sync_search; +}; + ++#define BYTE_SHIFT 3 ++ +static int core_ctr(struct dirty_log *log, sector_t dev_size, + unsigned int argc, char **argv) +{ @@ -3144,8 +3147,13 @@ + clog->region_size = region_size; + clog->region_count = region_count; + -+ bitset_size = dm_round_up((region_count + 7) >> 3, -+ sizeof(*clog->clean_bits)); ++ /* ++ * Work out how many words we need to hold the bitset. ++ */ ++ bitset_size = dm_round_up(region_count, ++ sizeof(*clog->clean_bits) << BYTE_SHIFT); ++ bitset_size >>= BYTE_SHIFT; ++ + clog->clean_bits = vmalloc(bitset_size); + if (!clog->clean_bits) { + DMWARN("couldn't allocate clean bitset"); @@ -3293,7 +3301,7 @@ +EXPORT_SYMBOL(dm_create_dirty_log); +EXPORT_SYMBOL(dm_destroy_dirty_log); --- linux-2.4.20/drivers/md/dm-log.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-log.h Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/dm-log.h Fri Nov 21 18:01:15 2003 @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2003 Sistina Software @@ -3408,7 +3416,7 @@ + +#endif --- linux-2.4.20/drivers/md/dm-raid1.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-raid1.c Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/dm-raid1.c Fri Nov 21 18:01:15 2003 @@ -0,0 +1,1294 @@ +/* + * Copyright (C) 2003 Sistina Software Limited. @@ -4457,7 +4465,7 @@ + * For now, #log_params = 1, log_type = "core" + * + */ -+#define DM_IO_PAGES 256 ++#define DM_IO_PAGES 64 +static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) +{ + int r; @@ -4705,7 +4713,7 @@ +MODULE_AUTHOR("Heinz Mauelshagen "); +MODULE_LICENSE("GPL"); --- linux-2.4.20/drivers/md/dm-snapshot.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-snapshot.c Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/dm-snapshot.c Fri Nov 21 18:01:15 2003 @@ -0,0 +1,1235 @@ +/* + * dm-snapshot.c @@ -5943,7 +5951,7 @@ + kmem_cache_destroy(exception_cache); +} --- linux-2.4.20/drivers/md/dm-snapshot.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-snapshot.h Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/dm-snapshot.h Fri Nov 21 18:01:15 2003 @@ -0,0 +1,158 @@ +/* + * dm-snapshot.c @@ -6104,7 +6112,7 @@ + +#endif --- linux-2.4.20/drivers/md/dm-stripe.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-stripe.c Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/dm-stripe.c Fri Nov 21 18:01:15 2003 @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. @@ -6365,8 +6373,8 @@ + return; +} --- linux-2.4.20/drivers/md/dm-table.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-table.c Mon Sep 1 16:33:46 2003 -@@ -0,0 +1,710 @@ ++++ linux/drivers/md/dm-table.c Fri Nov 21 18:01:15 2003 +@@ -0,0 +1,679 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * @@ -6386,7 +6394,6 @@ +#define NODE_SIZE L1_CACHE_BYTES +#define KEYS_PER_NODE (NODE_SIZE / sizeof(sector_t)) +#define CHILDREN_PER_NODE (KEYS_PER_NODE + 1) -+#define MAX_TARGET_ARGS 64 + +struct dm_table { + atomic_t holders; @@ -6482,44 +6489,11 @@ + return 0; +} + -+/* -+ * highs, and targets are managed as dynamic arrays during a -+ * table load. -+ */ -+static int alloc_targets(struct dm_table *t, unsigned int num) -+{ -+ sector_t *n_highs; -+ struct dm_target *n_targets; -+ int n = t->num_targets; -+ -+ /* -+ * Allocate both the target array and offset array at once. -+ */ -+ n_highs = (sector_t *) vcalloc(sizeof(struct dm_target) + -+ sizeof(sector_t), num); -+ if (!n_highs) -+ return -ENOMEM; -+ -+ n_targets = (struct dm_target *) (n_highs + num); -+ -+ if (n) { -+ memcpy(n_highs, t->highs, sizeof(*n_highs) * n); -+ memcpy(n_targets, t->targets, sizeof(*n_targets) * n); -+ } -+ -+ memset(n_highs + n, -1, sizeof(*n_highs) * (num - n)); -+ vfree(t->highs); -+ -+ t->num_allocated = num; -+ t->highs = n_highs; -+ t->targets = n_targets; + -+ return 0; -+} + +int dm_table_create(struct dm_table **result, int mode, unsigned num_targets) +{ -+ struct dm_table *t = kmalloc(sizeof(*t), GFP_NOIO); ++ struct dm_table *t = kmalloc(sizeof(*t), GFP_KERNEL); + + if (!t) + return -ENOMEM; @@ -6528,15 +6502,20 @@ + INIT_LIST_HEAD(&t->devices); + atomic_set(&t->holders, 1); + -+ if (!num_targets) -+ num_targets = KEYS_PER_NODE; ++ num_targets = dm_round_up(num_targets, KEYS_PER_NODE); + -+ if (alloc_targets(t, num_targets)) { ++ /* Allocate both the target array and offset array at once. */ ++ t->highs = (sector_t *) vcalloc(sizeof(struct dm_target) + ++ sizeof(sector_t), num_targets); ++ if (!t->highs) { + kfree(t); -+ t = NULL; + return -ENOMEM; + } + ++ memset(t->highs, -1, sizeof(*t->highs) * num_targets); ++ ++ t->targets = (struct dm_target *) (t->highs + num_targets); ++ t->num_allocated = num_targets; + t->mode = mode; + *result = t; + return 0; @@ -6596,17 +6575,6 @@ +} + +/* -+ * Checks to see if we need to extend highs or targets. -+ */ -+static inline int check_space(struct dm_table *t) -+{ -+ if (t->num_targets >= t->num_allocated) -+ return alloc_targets(t, t->num_allocated * 2); -+ -+ return 0; -+} -+ -+/* + * Convert a device path to a dev_t. + */ +static int lookup_device(const char *path, kdev_t *dev) @@ -6813,16 +6781,34 @@ +} + +/* ++ * Used to dynamically allocate the arg array. ++ */ ++static char **realloc_argv(unsigned *array_size, char **old_argv) ++{ ++ char **argv; ++ unsigned new_size; ++ ++ new_size = *array_size ? *array_size * 2 : 64; ++ argv = kmalloc(new_size * sizeof(*argv), GFP_KERNEL); ++ if (argv) { ++ memcpy(argv, old_argv, *array_size * sizeof(*argv)); ++ *array_size = new_size; ++ } ++ ++ kfree(old_argv); ++ return argv; ++} ++ ++/* + * Destructively splits up the argument list to pass to ctr. + */ +static int split_args(int *argc, char ***argvp, char *input) +{ -+ char *start, *end = input, *out; -+ char **argv; -+ int max_args = MAX_TARGET_ARGS; ++ char *start, *end = input, *out, **argv = NULL; ++ unsigned array_size = 0; + + *argc = 0; -+ argv = kmalloc(sizeof(*argv) * max_args, GFP_NOIO); ++ argv = realloc_argv(&array_size, argv); + if (!argv) + return -ENOMEM; + @@ -6853,19 +6839,10 @@ + } + + /* have we already filled the array ? */ -+ if ((*argc + 1) > max_args) { -+ char **argv2; -+ -+ max_args *= 2; -+ argv2 = kmalloc(sizeof(*argv2) * max_args, GFP_NOIO); -+ if (!argv2) { -+ kfree(argv); ++ if ((*argc + 1) > array_size) { ++ argv = realloc_argv(&array_size, argv); ++ if (!argv) + return -ENOMEM; -+ } -+ -+ memcpy(argv2, argv, sizeof(*argv) * *argc); -+ kfree(argv); -+ argv = argv2; + } + + /* we know this is whitespace */ @@ -6889,8 +6866,8 @@ + char **argv; + struct dm_target *tgt; + -+ if ((r = check_space(t))) -+ return r; ++ if (t->num_targets >= t->num_allocated) ++ return -ENOMEM; + + tgt = t->targets + t->num_targets; + memset(tgt, 0, sizeof(*tgt)); @@ -7078,7 +7055,7 @@ +EXPORT_SYMBOL(dm_table_event); +EXPORT_SYMBOL(dm_table_get_mode); --- linux-2.4.20/drivers/md/dm-target.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm-target.c Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/dm-target.c Fri Nov 21 18:01:15 2003 @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited @@ -7269,7 +7246,7 @@ +EXPORT_SYMBOL(dm_register_target); +EXPORT_SYMBOL(dm_unregister_target); --- linux-2.4.20/drivers/md/dm.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm.c Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/dm.c Fri Nov 21 18:01:15 2003 @@ -0,0 +1,1115 @@ +/* + * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. @@ -8387,7 +8364,7 @@ + +EXPORT_SYMBOL(dm_kdevname); --- linux-2.4.20/drivers/md/dm.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/dm.h Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/dm.h Fri Nov 21 18:01:15 2003 @@ -0,0 +1,175 @@ +/* + * Internal header file for device mapper @@ -8565,8 +8542,8 @@ + +#endif --- linux-2.4.20/drivers/md/kcopyd.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/kcopyd.c Mon Sep 1 16:33:46 2003 -@@ -0,0 +1,656 @@ ++++ linux/drivers/md/kcopyd.c Fri Nov 21 18:01:15 2003 +@@ -0,0 +1,666 @@ +/* + * Copyright (C) 2002 Sistina Software (UK) Limited. + * @@ -8596,6 +8573,11 @@ + +static struct dm_daemon _kcopyd; + ++#define SECTORS_PER_PAGE (PAGE_SIZE / SECTOR_SIZE) ++#define SUB_JOB_SIZE 128 ++#define PAGES_PER_SUB_JOB (SUB_JOB_SIZE / SECTORS_PER_PAGE) ++#define SUB_JOB_COUNT 8 ++ +/*----------------------------------------------------------------- + * Each kcopyd client has its own little pool of preallocated + * pages for kcopyd io. @@ -8607,6 +8589,7 @@ + struct list_head pages; + unsigned int nr_pages; + unsigned int nr_free_pages; ++ unsigned int max_split; +}; + +static inline void __push_page(struct kcopyd_client *kc, struct page *p) @@ -8691,6 +8674,10 @@ + + kcopyd_put_pages(kc, &new); + kc->nr_pages += nr; ++ kc->max_split = kc->nr_pages / PAGES_PER_SUB_JOB; ++ if (kc->max_split > SUB_JOB_COUNT) ++ kc->max_split = SUB_JOB_COUNT; ++ + return 0; +} + @@ -8903,7 +8890,6 @@ + return r; +} + -+#define SECTORS_PER_PAGE (PAGE_SIZE / SECTOR_SIZE) +static int run_pages_job(struct kcopyd_job *job) +{ + int r; @@ -8991,7 +8977,6 @@ + dm_daemon_wake(&_kcopyd); +} + -+#define SUB_JOB_SIZE 128 +static void segment_complete(int read_err, + unsigned int write_err, void *context) +{ @@ -9060,17 +9045,19 @@ + * Create some little jobs that will do the move between + * them. + */ -+#define SPLIT_COUNT 8 +static void split_job(struct kcopyd_job *job) +{ -+ int i; ++ int nr; ++ ++ nr = dm_div_up(job->source.count, SUB_JOB_SIZE); ++ if (nr > job->kc->max_split) ++ nr = job->kc->max_split; + -+ atomic_set(&job->sub_jobs, SPLIT_COUNT); -+ for (i = 0; i < SPLIT_COUNT; i++) ++ atomic_set(&job->sub_jobs, nr); ++ while (nr--) + segment_complete(0, 0u, job); +} + -+#define SUB_JOB_THRESHOLD (SPLIT_COUNT * SUB_JOB_SIZE) +int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from, + unsigned int num_dests, struct io_region *dests, + unsigned int flags, kcopyd_notify_fn fn, void *context) @@ -9103,7 +9090,7 @@ + job->fn = fn; + job->context = context; + -+ if (job->source.count < SUB_JOB_THRESHOLD) ++ if (job->source.count < SUB_JOB_SIZE) + dispatch_job(job); + + else { @@ -9151,9 +9138,9 @@ + int r = 0; + struct kcopyd_client *kc; + -+ if (nr_pages * SECTORS_PER_PAGE < SUB_JOB_SIZE * SPLIT_COUNT) { ++ if (nr_pages * SECTORS_PER_PAGE < SUB_JOB_SIZE) { + DMERR("kcopyd client requested %u pages: minimum is %lu", -+ nr_pages, SUB_JOB_SIZE * SPLIT_COUNT / SECTORS_PER_PAGE); ++ nr_pages, SUB_JOB_SIZE / SECTORS_PER_PAGE); + return -ENOMEM; + } + @@ -9224,7 +9211,7 @@ +EXPORT_SYMBOL(kcopyd_copy); +EXPORT_SYMBOL(kcopyd_cancel); --- linux-2.4.20/drivers/md/kcopyd.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/drivers/md/kcopyd.h Mon Sep 1 16:33:46 2003 ++++ linux/drivers/md/kcopyd.h Fri Nov 21 18:01:15 2003 @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2001 Sistina Software @@ -9274,7 +9261,7 @@ + +#endif --- linux-2.4.20/fs/buffer.c Fri Jan 10 16:35:24 2003 -+++ linux-2.4.20-dm-release4/fs/buffer.c Mon Sep 1 16:33:46 2003 ++++ linux/fs/buffer.c Fri Nov 21 18:01:05 2003 @@ -586,9 +586,10 @@ void buffer_insert_inode_queue(struct buffer_head *bh, struct inode *inode) { @@ -9347,7 +9334,7 @@ if (nr_unused_buffer_heads >= MAX_UNUSED_BUFFERS) { kmem_cache_free(bh_cachep, bh); --- linux-2.4.20/fs/jbd/journal.c Fri Jan 10 16:35:27 2003 -+++ linux-2.4.20-dm-release4/fs/jbd/journal.c Mon Sep 1 16:33:46 2003 ++++ linux/fs/jbd/journal.c Fri Nov 21 18:01:05 2003 @@ -1664,8 +1664,8 @@ * * Whenever a buffer has an attached journal_head, its ->b_state:BH_JBD bit @@ -9399,7 +9386,7 @@ clear_bit(BH_JBD, &bh->b_state); __brelse(bh); --- linux-2.4.20/include/linux/device-mapper.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/include/linux/device-mapper.h Mon Sep 1 16:33:46 2003 ++++ linux/include/linux/device-mapper.h Fri Nov 21 18:01:15 2003 @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. @@ -9506,7 +9493,7 @@ + +#endif /* _LINUX_DEVICE_MAPPER_H */ --- linux-2.4.20/include/linux/dm-ioctl.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/include/linux/dm-ioctl.h Mon Sep 1 16:33:46 2003 ++++ linux/include/linux/dm-ioctl.h Fri Nov 21 18:01:15 2003 @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2001 - 2003 Sistina Software (UK) Limited. @@ -9717,8 +9704,8 @@ + +#define DM_VERSION_MAJOR 4 +#define DM_VERSION_MINOR 0 -+#define DM_VERSION_PATCHLEVEL 4 -+#define DM_VERSION_EXTRA "-ioctl (2003-08-30)" ++#define DM_VERSION_PATCHLEVEL 5 ++#define DM_VERSION_EXTRA "-ioctl (2003-11-18)" + +/* Status bits */ +#define DM_READONLY_FLAG (1 << 0) /* In/Out */ @@ -9746,7 +9733,7 @@ + +#endif /* _LINUX_DM_IOCTL_H */ --- linux-2.4.20/include/linux/fs.h Fri Jan 10 16:35:55 2003 -+++ linux-2.4.20-dm-release4/include/linux/fs.h Mon Sep 1 16:33:46 2003 ++++ linux/include/linux/fs.h Fri Nov 21 18:01:05 2003 @@ -220,6 +220,7 @@ BH_Wait_IO, /* 1 if we should write out this buffer */ BH_Launder, /* 1 if we can throttle on this buffer */ @@ -9791,7 +9778,7 @@ /* --- linux-2.4.20/include/linux/jbd.h Fri Jan 10 16:35:55 2003 -+++ linux-2.4.20-dm-release4/include/linux/jbd.h Mon Sep 1 16:33:46 2003 ++++ linux/include/linux/jbd.h Fri Nov 21 18:01:05 2003 @@ -254,7 +254,7 @@ static inline struct journal_head *bh2jh(struct buffer_head *bh) @@ -9802,7 +9789,7 @@ #define HAVE_JOURNAL_CALLBACK_STATUS --- linux-2.4.20/include/linux/mempool.h Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/include/linux/mempool.h Mon Sep 1 16:33:46 2003 ++++ linux/include/linux/mempool.h Fri Nov 21 18:01:23 2003 @@ -0,0 +1,31 @@ +/* + * memory buffer pool support @@ -9836,7 +9823,7 @@ + +#endif /* _LINUX_MEMPOOL_H */ --- linux-2.4.20/include/linux/vmalloc.h Fri Jan 10 16:35:58 2003 -+++ linux-2.4.20-dm-release4/include/linux/vmalloc.h Mon Sep 1 16:33:46 2003 ++++ linux/include/linux/vmalloc.h Fri Nov 21 18:01:29 2003 @@ -26,6 +26,7 @@ extern void vmfree_area_pages(unsigned long address, unsigned long size); extern int vmalloc_area_pages(unsigned long address, unsigned long size, @@ -9846,7 +9833,7 @@ /* * Allocate any pages --- linux-2.4.20/kernel/ksyms.c Fri Jan 10 16:36:02 2003 -+++ linux-2.4.20-dm-release4/kernel/ksyms.c Mon Sep 1 16:33:46 2003 ++++ linux/kernel/ksyms.c Fri Nov 21 18:01:29 2003 @@ -111,6 +111,7 @@ EXPORT_SYMBOL(vfree); EXPORT_SYMBOL(__vmalloc); @@ -9856,7 +9843,7 @@ EXPORT_SYMBOL(remap_page_range); EXPORT_SYMBOL(max_mapnr); --- linux-2.4.20/mm/Makefile Fri Jan 10 16:36:02 2003 -+++ linux-2.4.20-dm-release4/mm/Makefile Mon Sep 1 16:33:46 2003 ++++ linux/mm/Makefile Fri Nov 21 18:01:23 2003 @@ -9,12 +9,12 @@ O_TARGET := mm.o @@ -9873,7 +9860,7 @@ obj-$(CONFIG_HIGHMEM) += highmem.o --- linux-2.4.20/mm/filemap.c Fri Jan 10 16:36:03 2003 -+++ linux-2.4.20-dm-release4/mm/filemap.c Mon Sep 1 16:33:46 2003 ++++ linux/mm/filemap.c Fri Nov 21 18:01:26 2003 @@ -1700,8 +1700,10 @@ retval = generic_file_direct_IO(READ, filp, buf, count, pos); if (retval > 0) @@ -9902,7 +9889,7 @@ if (file->f_flags & O_DIRECT) goto o_direct; --- linux-2.4.20/mm/mempool.c Thu Jan 1 01:00:00 1970 -+++ linux-2.4.20-dm-release4/mm/mempool.c Mon Sep 1 16:33:46 2003 ++++ linux/mm/mempool.c Fri Nov 21 18:01:23 2003 @@ -0,0 +1,299 @@ +/* + * linux/mm/mempool.c @@ -10204,7 +10191,7 @@ +EXPORT_SYMBOL(mempool_alloc_slab); +EXPORT_SYMBOL(mempool_free_slab); --- linux-2.4.20/mm/vmalloc.c Fri Jan 10 16:36:03 2003 -+++ linux-2.4.20-dm-release4/mm/vmalloc.c Mon Sep 1 16:33:46 2003 ++++ linux/mm/vmalloc.c Fri Nov 21 18:01:29 2003 @@ -327,3 +327,22 @@ read_unlock(&vmlist_lock); return buf - buf_start; diff --git a/patches/linux-2.4.21-devmapper-ioctl.patch b/patches/linux-2.4.21-devmapper-ioctl.patch index 837eee2..ef571cc 100644 --- a/patches/linux-2.4.21-devmapper-ioctl.patch +++ b/patches/linux-2.4.21-devmapper-ioctl.patch @@ -1,5 +1,5 @@ --- linux-2.4.21/Documentation/Configure.help Fri Jun 13 16:32:30 2003 -+++ linux/Documentation/Configure.help Mon Sep 1 16:26:19 2003 ++++ linux/Documentation/Configure.help Fri Nov 21 18:03:22 2003 @@ -1839,6 +1839,20 @@ want), say M here and read . The module will be called lvm-mod.o. @@ -22,7 +22,7 @@ CONFIG_MD Support multiple physical spindles through a single logical device. --- linux-2.4.21/MAINTAINERS Fri Jun 13 16:32:30 2003 -+++ linux/MAINTAINERS Mon Sep 1 16:26:19 2003 ++++ linux/MAINTAINERS Fri Nov 21 18:03:22 2003 @@ -476,6 +476,13 @@ W: http://www.debian.org/~dz/i8k/ S: Maintained @@ -38,7 +38,7 @@ P: H. Peter Anvin M: hpa@zytor.com --- linux-2.4.21/arch/mips64/kernel/ioctl32.c Fri Jan 10 16:34:18 2003 -+++ linux/arch/mips64/kernel/ioctl32.c Mon Sep 1 16:26:19 2003 ++++ linux/arch/mips64/kernel/ioctl32.c Fri Nov 21 18:03:30 2003 @@ -33,6 +33,7 @@ #include #include @@ -71,7 +71,7 @@ IOCTL32_DEFAULT(MTIOCTOP), /* mtio.h ioctls */ IOCTL32_HANDLER(MTIOCGET32, mt_ioctl_trans), --- linux-2.4.21/arch/parisc/kernel/ioctl32.c Fri Jun 13 16:32:32 2003 -+++ linux/arch/parisc/kernel/ioctl32.c Mon Sep 1 16:26:19 2003 ++++ linux/arch/parisc/kernel/ioctl32.c Fri Nov 21 18:03:30 2003 @@ -55,6 +55,7 @@ #define max max */ #include @@ -104,7 +104,7 @@ COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC) COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID) --- linux-2.4.21/arch/ppc64/kernel/ioctl32.c Fri Jun 13 16:32:33 2003 -+++ linux/arch/ppc64/kernel/ioctl32.c Mon Sep 1 16:26:19 2003 ++++ linux/arch/ppc64/kernel/ioctl32.c Fri Nov 21 18:03:30 2003 @@ -66,6 +66,7 @@ #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) #include @@ -137,7 +137,7 @@ COMPATIBLE_IOCTL(SIOCDEVPRIVATE), COMPATIBLE_IOCTL(SIOCDEVPRIVATE+1), --- linux-2.4.21/arch/s390x/kernel/ioctl32.c Fri Jan 10 16:34:26 2003 -+++ linux/arch/s390x/kernel/ioctl32.c Mon Sep 1 16:26:19 2003 ++++ linux/arch/s390x/kernel/ioctl32.c Fri Nov 21 18:03:30 2003 @@ -25,6 +25,7 @@ #include #include @@ -168,7 +168,7 @@ IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32), IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf), --- linux-2.4.21/arch/sparc64/kernel/ioctl32.c Fri Jun 13 16:32:34 2003 -+++ linux/arch/sparc64/kernel/ioctl32.c Mon Sep 1 16:26:19 2003 ++++ linux/arch/sparc64/kernel/ioctl32.c Fri Nov 21 18:03:30 2003 @@ -56,6 +56,7 @@ #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) #include @@ -201,7 +201,7 @@ #if defined(CONFIG_IEEE1394) || defined(CONFIG_IEEE1394_MODULE) COMPATIBLE_IOCTL(AMDTP_IOC_CHANNEL) --- linux-2.4.21/arch/x86_64/ia32/ia32_ioctl.c Fri Jun 13 16:32:35 2003 -+++ linux/arch/x86_64/ia32/ia32_ioctl.c Mon Sep 1 16:26:19 2003 ++++ linux/arch/x86_64/ia32/ia32_ioctl.c Fri Nov 21 18:03:30 2003 @@ -67,6 +67,7 @@ #define max max #include @@ -234,7 +234,7 @@ COMPATIBLE_IOCTL(AUTOFS_IOC_READY) COMPATIBLE_IOCTL(AUTOFS_IOC_FAIL) --- linux-2.4.21/drivers/md/Config.in Fri Jan 10 16:34:50 2003 -+++ linux/drivers/md/Config.in Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/Config.in Fri Nov 21 18:03:22 2003 @@ -14,5 +14,7 @@ dep_tristate ' Multipath I/O support' CONFIG_MD_MULTIPATH $CONFIG_BLK_DEV_MD @@ -244,7 +244,7 @@ endmenu --- linux-2.4.21/drivers/md/Makefile Fri Jan 10 16:34:50 2003 -+++ linux/drivers/md/Makefile Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/Makefile Fri Nov 21 18:03:13 2003 @@ -4,24 +4,41 @@ O_TARGET := mddev.o @@ -297,7 +297,7 @@ + $(LD) -r -o $@ $(dm-mirror-mod-objs) + --- linux-2.4.21/drivers/md/dm-daemon.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-daemon.c Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/dm-daemon.c Fri Nov 21 18:03:15 2003 @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2003 Sistina Software @@ -413,7 +413,7 @@ +EXPORT_SYMBOL(dm_daemon_stop); +EXPORT_SYMBOL(dm_daemon_wake); --- linux-2.4.21/drivers/md/dm-daemon.h Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-daemon.h Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/dm-daemon.h Fri Nov 21 18:03:15 2003 @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2003 Sistina Software @@ -445,7 +445,7 @@ + +#endif --- linux-2.4.21/drivers/md/dm-exception-store.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-exception-store.c Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/dm-exception-store.c Fri Nov 21 18:03:15 2003 @@ -0,0 +1,673 @@ +/* + * dm-snapshot.c @@ -1121,8 +1121,8 @@ + return 0; +} --- linux-2.4.21/drivers/md/dm-io.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-io.c Mon Sep 1 16:26:19 2003 -@@ -0,0 +1,360 @@ ++++ linux/drivers/md/dm-io.c Fri Nov 21 18:03:15 2003 +@@ -0,0 +1,361 @@ +/* + * Copyright (C) 2003 Sistina Software + * @@ -1135,6 +1135,7 @@ +#include +#include +#include ++#include + +/* FIXME: can we shrink this ? */ +struct io_context { @@ -1484,7 +1485,7 @@ +EXPORT_SYMBOL(dm_io_sync); +EXPORT_SYMBOL(dm_io_async); --- linux-2.4.21/drivers/md/dm-io.h Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-io.h Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/dm-io.h Fri Nov 21 18:03:15 2003 @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2003 Sistina Software @@ -1573,7 +1574,7 @@ + +#endif --- linux-2.4.21/drivers/md/dm-ioctl.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-ioctl.c Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/dm-ioctl.c Fri Nov 21 18:03:15 2003 @@ -0,0 +1,1284 @@ +/* + * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. @@ -2275,6 +2276,113 @@ + return r; +} + ++/* ++ * Build up the status struct for each target ++ */ ++static void retrieve_status(struct dm_table *table, struct dm_ioctl *param, ++ size_t param_size) ++{ ++ unsigned int i, num_targets; ++ struct dm_target_spec *spec; ++ char *outbuf, *outptr; ++ status_type_t type; ++ size_t remaining, len, used = 0; ++ ++ outptr = outbuf = get_result_buffer(param, param_size, &len); ++ ++ if (param->flags & DM_STATUS_TABLE_FLAG) ++ type = STATUSTYPE_TABLE; ++ else ++ type = STATUSTYPE_INFO; ++ ++ /* Get all the target info */ ++ num_targets = dm_table_get_num_targets(table); ++ for (i = 0; i < num_targets; i++) { ++ struct dm_target *ti = dm_table_get_target(table, i); ++ ++ remaining = len - (outptr - outbuf); ++ if (remaining < sizeof(struct dm_target_spec)) { ++ param->flags |= DM_BUFFER_FULL_FLAG; ++ break; ++ } ++ ++ spec = (struct dm_target_spec *) outptr; ++ ++ spec->status = 0; ++ spec->sector_start = ti->begin; ++ spec->length = ti->len; ++ strncpy(spec->target_type, ti->type->name, ++ sizeof(spec->target_type)); ++ ++ outptr += sizeof(struct dm_target_spec); ++ remaining = len - (outptr - outbuf); ++ ++ /* Get the status/table string from the target driver */ ++ if (ti->type->status) { ++ if (ti->type->status(ti, type, outptr, remaining)) { ++ param->flags |= DM_BUFFER_FULL_FLAG; ++ break; ++ } ++ } else ++ outptr[0] = '\0'; ++ ++ outptr += strlen(outptr) + 1; ++ used = param->data_start + (outptr - outbuf); ++ ++ align_ptr(outptr); ++ spec->next = outptr - outbuf; ++ } ++ ++ if (used) ++ param->data_size = used; ++ ++ param->target_count = num_targets; ++} ++ ++/* ++ * Wait for a device to report an event ++ */ ++static int dev_wait(struct dm_ioctl *param, size_t param_size) ++{ ++ int r; ++ struct mapped_device *md; ++ struct dm_table *table; ++ DECLARE_WAITQUEUE(wq, current); ++ ++ md = find_device(param); ++ if (!md) ++ return -ENXIO; ++ ++ /* ++ * Wait for a notification event ++ */ ++ set_current_state(TASK_INTERRUPTIBLE); ++ if (!dm_add_wait_queue(md, &wq, param->event_nr)) { ++ schedule(); ++ dm_remove_wait_queue(md, &wq); ++ } ++ set_current_state(TASK_RUNNING); ++ ++ /* ++ * The userland program is going to want to know what ++ * changed to trigger the event, so we may as well tell ++ * him and save an ioctl. ++ */ ++ r = __dev_status(md, param); ++ if (r) ++ goto out; ++ ++ table = dm_get_table(md); ++ if (table) { ++ retrieve_status(table, param, param_size); ++ dm_table_put(table); ++ } ++ ++ out: ++ dm_put(md); ++ return r; ++} ++ +static inline int get_mode(struct dm_ioctl *param) +{ + int mode = FMODE_READ | FMODE_WRITE; @@ -2462,69 +2570,6 @@ +} + +/* -+ * Build up the status struct for each target -+ */ -+static void retrieve_status(struct dm_table *table, struct dm_ioctl *param, -+ size_t param_size) -+{ -+ unsigned int i, num_targets; -+ struct dm_target_spec *spec; -+ char *outbuf, *outptr; -+ status_type_t type; -+ size_t remaining, len, used = 0; -+ -+ outptr = outbuf = get_result_buffer(param, param_size, &len); -+ -+ if (param->flags & DM_STATUS_TABLE_FLAG) -+ type = STATUSTYPE_TABLE; -+ else -+ type = STATUSTYPE_INFO; -+ -+ /* Get all the target info */ -+ num_targets = dm_table_get_num_targets(table); -+ for (i = 0; i < num_targets; i++) { -+ struct dm_target *ti = dm_table_get_target(table, i); -+ -+ remaining = len - (outptr - outbuf); -+ if (remaining < sizeof(struct dm_target_spec)) { -+ param->flags |= DM_BUFFER_FULL_FLAG; -+ break; -+ } -+ -+ spec = (struct dm_target_spec *) outptr; -+ -+ spec->status = 0; -+ spec->sector_start = ti->begin; -+ spec->length = ti->len; -+ strncpy(spec->target_type, ti->type->name, -+ sizeof(spec->target_type)); -+ -+ outptr += sizeof(struct dm_target_spec); -+ remaining = len - (outptr - outbuf); -+ -+ /* Get the status/table string from the target driver */ -+ if (ti->type->status) { -+ if (ti->type->status(ti, type, outptr, remaining)) { -+ param->flags |= DM_BUFFER_FULL_FLAG; -+ break; -+ } -+ } else -+ outptr[0] = '\0'; -+ -+ outptr += strlen(outptr) + 1; -+ used = param->data_start + (outptr - outbuf); -+ -+ align_ptr(outptr); -+ spec->next = outptr - outbuf; -+ } -+ -+ if (used) -+ param->data_size = used; -+ -+ param->target_count = num_targets; -+} -+ -+/* + * Return the status of a device as a text string for each + * target. + */ @@ -2553,50 +2598,6 @@ + return r; +} + -+/* -+ * Wait for a device to report an event -+ */ -+static int dev_wait(struct dm_ioctl *param, size_t param_size) -+{ -+ int r; -+ struct mapped_device *md; -+ struct dm_table *table; -+ DECLARE_WAITQUEUE(wq, current); -+ -+ md = find_device(param); -+ if (!md) -+ return -ENXIO; -+ -+ /* -+ * Wait for a notification event -+ */ -+ set_current_state(TASK_INTERRUPTIBLE); -+ if (!dm_add_wait_queue(md, &wq, param->event_nr)) { -+ schedule(); -+ dm_remove_wait_queue(md, &wq); -+ } -+ set_current_state(TASK_RUNNING); -+ -+ /* -+ * The userland program is going to want to know what -+ * changed to trigger the event, so we may as well tell -+ * him and save an ioctl. -+ */ -+ r = __dev_status(md, param); -+ if (r) -+ goto out; -+ -+ table = dm_get_table(md); -+ if (table) { -+ retrieve_status(table, param, param_size); -+ dm_table_put(table); -+ } -+ -+ out: -+ dm_put(md); -+ return r; -+} -+ +/*----------------------------------------------------------------- + * Implementation of open/close/ioctl on the special char + * device. @@ -2860,7 +2861,7 @@ + dm_hash_exit(); +} --- linux-2.4.21/drivers/md/dm-linear.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-linear.c Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/dm-linear.c Fri Nov 21 18:03:15 2003 @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. @@ -2986,8 +2987,8 @@ + DMERR("linear: unregister failed %d", r); +} --- linux-2.4.21/drivers/md/dm-log.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-log.c Mon Sep 1 16:26:19 2003 -@@ -0,0 +1,303 @@ ++++ linux/drivers/md/dm-log.c Fri Nov 21 18:03:15 2003 +@@ -0,0 +1,310 @@ +/* + * Copyright (C) 2003 Sistina Software + * @@ -3114,6 +3115,8 @@ + int sync_search; +}; + ++#define BYTE_SHIFT 3 ++ +static int core_ctr(struct dirty_log *log, sector_t dev_size, + unsigned int argc, char **argv) +{ @@ -3143,8 +3146,13 @@ + clog->region_size = region_size; + clog->region_count = region_count; + -+ bitset_size = dm_round_up((region_count + 7) >> 3, -+ sizeof(*clog->clean_bits)); ++ /* ++ * Work out how many words we need to hold the bitset. ++ */ ++ bitset_size = dm_round_up(region_count, ++ sizeof(*clog->clean_bits) << BYTE_SHIFT); ++ bitset_size >>= BYTE_SHIFT; ++ + clog->clean_bits = vmalloc(bitset_size); + if (!clog->clean_bits) { + DMWARN("couldn't allocate clean bitset"); @@ -3292,7 +3300,7 @@ +EXPORT_SYMBOL(dm_create_dirty_log); +EXPORT_SYMBOL(dm_destroy_dirty_log); --- linux-2.4.21/drivers/md/dm-log.h Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-log.h Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/dm-log.h Fri Nov 21 18:03:15 2003 @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2003 Sistina Software @@ -3407,7 +3415,7 @@ + +#endif --- linux-2.4.21/drivers/md/dm-raid1.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-raid1.c Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/dm-raid1.c Fri Nov 21 18:03:15 2003 @@ -0,0 +1,1294 @@ +/* + * Copyright (C) 2003 Sistina Software Limited. @@ -4456,7 +4464,7 @@ + * For now, #log_params = 1, log_type = "core" + * + */ -+#define DM_IO_PAGES 256 ++#define DM_IO_PAGES 64 +static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) +{ + int r; @@ -4704,7 +4712,7 @@ +MODULE_AUTHOR("Heinz Mauelshagen "); +MODULE_LICENSE("GPL"); --- linux-2.4.21/drivers/md/dm-snapshot.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-snapshot.c Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/dm-snapshot.c Fri Nov 21 18:03:15 2003 @@ -0,0 +1,1235 @@ +/* + * dm-snapshot.c @@ -5942,7 +5950,7 @@ + kmem_cache_destroy(exception_cache); +} --- linux-2.4.21/drivers/md/dm-snapshot.h Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-snapshot.h Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/dm-snapshot.h Fri Nov 21 18:03:15 2003 @@ -0,0 +1,158 @@ +/* + * dm-snapshot.c @@ -6103,7 +6111,7 @@ + +#endif --- linux-2.4.21/drivers/md/dm-stripe.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-stripe.c Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/dm-stripe.c Fri Nov 21 18:03:15 2003 @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. @@ -6364,8 +6372,8 @@ + return; +} --- linux-2.4.21/drivers/md/dm-table.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-table.c Mon Sep 1 16:26:19 2003 -@@ -0,0 +1,710 @@ ++++ linux/drivers/md/dm-table.c Fri Nov 21 18:03:15 2003 +@@ -0,0 +1,679 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * @@ -6385,7 +6393,6 @@ +#define NODE_SIZE L1_CACHE_BYTES +#define KEYS_PER_NODE (NODE_SIZE / sizeof(sector_t)) +#define CHILDREN_PER_NODE (KEYS_PER_NODE + 1) -+#define MAX_TARGET_ARGS 64 + +struct dm_table { + atomic_t holders; @@ -6481,44 +6488,11 @@ + return 0; +} + -+/* -+ * highs, and targets are managed as dynamic arrays during a -+ * table load. -+ */ -+static int alloc_targets(struct dm_table *t, unsigned int num) -+{ -+ sector_t *n_highs; -+ struct dm_target *n_targets; -+ int n = t->num_targets; -+ -+ /* -+ * Allocate both the target array and offset array at once. -+ */ -+ n_highs = (sector_t *) vcalloc(sizeof(struct dm_target) + -+ sizeof(sector_t), num); -+ if (!n_highs) -+ return -ENOMEM; -+ -+ n_targets = (struct dm_target *) (n_highs + num); -+ -+ if (n) { -+ memcpy(n_highs, t->highs, sizeof(*n_highs) * n); -+ memcpy(n_targets, t->targets, sizeof(*n_targets) * n); -+ } -+ -+ memset(n_highs + n, -1, sizeof(*n_highs) * (num - n)); -+ vfree(t->highs); -+ -+ t->num_allocated = num; -+ t->highs = n_highs; -+ t->targets = n_targets; + -+ return 0; -+} + +int dm_table_create(struct dm_table **result, int mode, unsigned num_targets) +{ -+ struct dm_table *t = kmalloc(sizeof(*t), GFP_NOIO); ++ struct dm_table *t = kmalloc(sizeof(*t), GFP_KERNEL); + + if (!t) + return -ENOMEM; @@ -6527,15 +6501,20 @@ + INIT_LIST_HEAD(&t->devices); + atomic_set(&t->holders, 1); + -+ if (!num_targets) -+ num_targets = KEYS_PER_NODE; ++ num_targets = dm_round_up(num_targets, KEYS_PER_NODE); + -+ if (alloc_targets(t, num_targets)) { ++ /* Allocate both the target array and offset array at once. */ ++ t->highs = (sector_t *) vcalloc(sizeof(struct dm_target) + ++ sizeof(sector_t), num_targets); ++ if (!t->highs) { + kfree(t); -+ t = NULL; + return -ENOMEM; + } + ++ memset(t->highs, -1, sizeof(*t->highs) * num_targets); ++ ++ t->targets = (struct dm_target *) (t->highs + num_targets); ++ t->num_allocated = num_targets; + t->mode = mode; + *result = t; + return 0; @@ -6595,17 +6574,6 @@ +} + +/* -+ * Checks to see if we need to extend highs or targets. -+ */ -+static inline int check_space(struct dm_table *t) -+{ -+ if (t->num_targets >= t->num_allocated) -+ return alloc_targets(t, t->num_allocated * 2); -+ -+ return 0; -+} -+ -+/* + * Convert a device path to a dev_t. + */ +static int lookup_device(const char *path, kdev_t *dev) @@ -6812,16 +6780,34 @@ +} + +/* ++ * Used to dynamically allocate the arg array. ++ */ ++static char **realloc_argv(unsigned *array_size, char **old_argv) ++{ ++ char **argv; ++ unsigned new_size; ++ ++ new_size = *array_size ? *array_size * 2 : 64; ++ argv = kmalloc(new_size * sizeof(*argv), GFP_KERNEL); ++ if (argv) { ++ memcpy(argv, old_argv, *array_size * sizeof(*argv)); ++ *array_size = new_size; ++ } ++ ++ kfree(old_argv); ++ return argv; ++} ++ ++/* + * Destructively splits up the argument list to pass to ctr. + */ +static int split_args(int *argc, char ***argvp, char *input) +{ -+ char *start, *end = input, *out; -+ char **argv; -+ int max_args = MAX_TARGET_ARGS; ++ char *start, *end = input, *out, **argv = NULL; ++ unsigned array_size = 0; + + *argc = 0; -+ argv = kmalloc(sizeof(*argv) * max_args, GFP_NOIO); ++ argv = realloc_argv(&array_size, argv); + if (!argv) + return -ENOMEM; + @@ -6852,19 +6838,10 @@ + } + + /* have we already filled the array ? */ -+ if ((*argc + 1) > max_args) { -+ char **argv2; -+ -+ max_args *= 2; -+ argv2 = kmalloc(sizeof(*argv2) * max_args, GFP_NOIO); -+ if (!argv2) { -+ kfree(argv); ++ if ((*argc + 1) > array_size) { ++ argv = realloc_argv(&array_size, argv); ++ if (!argv) + return -ENOMEM; -+ } -+ -+ memcpy(argv2, argv, sizeof(*argv) * *argc); -+ kfree(argv); -+ argv = argv2; + } + + /* we know this is whitespace */ @@ -6888,8 +6865,8 @@ + char **argv; + struct dm_target *tgt; + -+ if ((r = check_space(t))) -+ return r; ++ if (t->num_targets >= t->num_allocated) ++ return -ENOMEM; + + tgt = t->targets + t->num_targets; + memset(tgt, 0, sizeof(*tgt)); @@ -7077,7 +7054,7 @@ +EXPORT_SYMBOL(dm_table_event); +EXPORT_SYMBOL(dm_table_get_mode); --- linux-2.4.21/drivers/md/dm-target.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm-target.c Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/dm-target.c Fri Nov 21 18:03:15 2003 @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited @@ -7268,7 +7245,7 @@ +EXPORT_SYMBOL(dm_register_target); +EXPORT_SYMBOL(dm_unregister_target); --- linux-2.4.21/drivers/md/dm.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm.c Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/dm.c Fri Nov 21 18:03:15 2003 @@ -0,0 +1,1115 @@ +/* + * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. @@ -8386,7 +8363,7 @@ + +EXPORT_SYMBOL(dm_kdevname); --- linux-2.4.21/drivers/md/dm.h Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/dm.h Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/dm.h Fri Nov 21 18:03:15 2003 @@ -0,0 +1,175 @@ +/* + * Internal header file for device mapper @@ -8564,8 +8541,8 @@ + +#endif --- linux-2.4.21/drivers/md/kcopyd.c Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/kcopyd.c Mon Sep 1 16:26:19 2003 -@@ -0,0 +1,656 @@ ++++ linux/drivers/md/kcopyd.c Fri Nov 21 18:03:15 2003 +@@ -0,0 +1,666 @@ +/* + * Copyright (C) 2002 Sistina Software (UK) Limited. + * @@ -8595,6 +8572,11 @@ + +static struct dm_daemon _kcopyd; + ++#define SECTORS_PER_PAGE (PAGE_SIZE / SECTOR_SIZE) ++#define SUB_JOB_SIZE 128 ++#define PAGES_PER_SUB_JOB (SUB_JOB_SIZE / SECTORS_PER_PAGE) ++#define SUB_JOB_COUNT 8 ++ +/*----------------------------------------------------------------- + * Each kcopyd client has its own little pool of preallocated + * pages for kcopyd io. @@ -8606,6 +8588,7 @@ + struct list_head pages; + unsigned int nr_pages; + unsigned int nr_free_pages; ++ unsigned int max_split; +}; + +static inline void __push_page(struct kcopyd_client *kc, struct page *p) @@ -8690,6 +8673,10 @@ + + kcopyd_put_pages(kc, &new); + kc->nr_pages += nr; ++ kc->max_split = kc->nr_pages / PAGES_PER_SUB_JOB; ++ if (kc->max_split > SUB_JOB_COUNT) ++ kc->max_split = SUB_JOB_COUNT; ++ + return 0; +} + @@ -8902,7 +8889,6 @@ + return r; +} + -+#define SECTORS_PER_PAGE (PAGE_SIZE / SECTOR_SIZE) +static int run_pages_job(struct kcopyd_job *job) +{ + int r; @@ -8990,7 +8976,6 @@ + dm_daemon_wake(&_kcopyd); +} + -+#define SUB_JOB_SIZE 128 +static void segment_complete(int read_err, + unsigned int write_err, void *context) +{ @@ -9059,17 +9044,19 @@ + * Create some little jobs that will do the move between + * them. + */ -+#define SPLIT_COUNT 8 +static void split_job(struct kcopyd_job *job) +{ -+ int i; ++ int nr; ++ ++ nr = dm_div_up(job->source.count, SUB_JOB_SIZE); ++ if (nr > job->kc->max_split) ++ nr = job->kc->max_split; + -+ atomic_set(&job->sub_jobs, SPLIT_COUNT); -+ for (i = 0; i < SPLIT_COUNT; i++) ++ atomic_set(&job->sub_jobs, nr); ++ while (nr--) + segment_complete(0, 0u, job); +} + -+#define SUB_JOB_THRESHOLD (SPLIT_COUNT * SUB_JOB_SIZE) +int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from, + unsigned int num_dests, struct io_region *dests, + unsigned int flags, kcopyd_notify_fn fn, void *context) @@ -9102,7 +9089,7 @@ + job->fn = fn; + job->context = context; + -+ if (job->source.count < SUB_JOB_THRESHOLD) ++ if (job->source.count < SUB_JOB_SIZE) + dispatch_job(job); + + else { @@ -9150,9 +9137,9 @@ + int r = 0; + struct kcopyd_client *kc; + -+ if (nr_pages * SECTORS_PER_PAGE < SUB_JOB_SIZE * SPLIT_COUNT) { ++ if (nr_pages * SECTORS_PER_PAGE < SUB_JOB_SIZE) { + DMERR("kcopyd client requested %u pages: minimum is %lu", -+ nr_pages, SUB_JOB_SIZE * SPLIT_COUNT / SECTORS_PER_PAGE); ++ nr_pages, SUB_JOB_SIZE / SECTORS_PER_PAGE); + return -ENOMEM; + } + @@ -9223,7 +9210,7 @@ +EXPORT_SYMBOL(kcopyd_copy); +EXPORT_SYMBOL(kcopyd_cancel); --- linux-2.4.21/drivers/md/kcopyd.h Thu Jan 1 01:00:00 1970 -+++ linux/drivers/md/kcopyd.h Mon Sep 1 16:26:19 2003 ++++ linux/drivers/md/kcopyd.h Fri Nov 21 18:03:15 2003 @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2001 Sistina Software @@ -9273,7 +9260,7 @@ + +#endif --- linux-2.4.21/fs/buffer.c Fri Jun 13 16:32:48 2003 -+++ linux/fs/buffer.c Mon Sep 1 16:26:19 2003 ++++ linux/fs/buffer.c Fri Nov 21 18:03:26 2003 @@ -735,6 +735,7 @@ bh->b_list = BUF_CLEAN; bh->b_end_io = handler; @@ -9283,7 +9270,7 @@ static void end_buffer_io_async(struct buffer_head * bh, int uptodate) --- linux-2.4.21/fs/jbd/journal.c Fri Jun 13 16:32:48 2003 -+++ linux/fs/jbd/journal.c Mon Sep 1 16:26:19 2003 ++++ linux/fs/jbd/journal.c Fri Nov 21 18:03:26 2003 @@ -1802,9 +1802,9 @@ if (buffer_jbd(bh)) { @@ -9324,7 +9311,7 @@ clear_bit(BH_JBD, &bh->b_state); __brelse(bh); --- linux-2.4.21/include/linux/device-mapper.h Thu Jan 1 01:00:00 1970 -+++ linux/include/linux/device-mapper.h Mon Sep 1 16:26:19 2003 ++++ linux/include/linux/device-mapper.h Fri Nov 21 18:03:15 2003 @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. @@ -9431,7 +9418,7 @@ + +#endif /* _LINUX_DEVICE_MAPPER_H */ --- linux-2.4.21/include/linux/dm-ioctl.h Thu Jan 1 01:00:00 1970 -+++ linux/include/linux/dm-ioctl.h Mon Sep 1 16:26:19 2003 ++++ linux/include/linux/dm-ioctl.h Fri Nov 21 18:03:15 2003 @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2001 - 2003 Sistina Software (UK) Limited. @@ -9642,8 +9629,8 @@ + +#define DM_VERSION_MAJOR 4 +#define DM_VERSION_MINOR 0 -+#define DM_VERSION_PATCHLEVEL 4 -+#define DM_VERSION_EXTRA "-ioctl (2003-08-30)" ++#define DM_VERSION_PATCHLEVEL 5 ++#define DM_VERSION_EXTRA "-ioctl (2003-11-18)" + +/* Status bits */ +#define DM_READONLY_FLAG (1 << 0) /* In/Out */ @@ -9671,7 +9658,7 @@ + +#endif /* _LINUX_DM_IOCTL_H */ --- linux-2.4.21/include/linux/fs.h Fri Jun 13 16:32:51 2003 -+++ linux/include/linux/fs.h Mon Sep 1 16:26:19 2003 ++++ linux/include/linux/fs.h Fri Nov 21 18:03:26 2003 @@ -263,7 +263,7 @@ struct page *b_page; /* the page this bh is mapped to */ void (*b_end_io)(struct buffer_head *bh, int uptodate); /* I/O completion */ @@ -9682,7 +9669,7 @@ wait_queue_head_t b_wait; --- linux-2.4.21/include/linux/jbd.h Fri Jun 13 16:32:51 2003 -+++ linux/include/linux/jbd.h Mon Sep 1 16:26:19 2003 ++++ linux/include/linux/jbd.h Fri Nov 21 18:03:26 2003 @@ -311,7 +311,7 @@ static inline struct journal_head *bh2jh(struct buffer_head *bh) @@ -9693,7 +9680,7 @@ #define HAVE_JOURNAL_CALLBACK_STATUS --- linux-2.4.21/include/linux/mempool.h Thu Jan 1 01:00:00 1970 -+++ linux/include/linux/mempool.h Mon Sep 1 16:26:19 2003 ++++ linux/include/linux/mempool.h Fri Nov 21 18:03:10 2003 @@ -0,0 +1,31 @@ +/* + * memory buffer pool support @@ -9727,7 +9714,7 @@ + +#endif /* _LINUX_MEMPOOL_H */ --- linux-2.4.21/include/linux/vmalloc.h Fri Jan 10 16:35:58 2003 -+++ linux/include/linux/vmalloc.h Mon Sep 1 16:26:19 2003 ++++ linux/include/linux/vmalloc.h Fri Nov 21 18:03:03 2003 @@ -26,6 +26,7 @@ extern void vmfree_area_pages(unsigned long address, unsigned long size); extern int vmalloc_area_pages(unsigned long address, unsigned long size, @@ -9737,7 +9724,7 @@ /* * Allocate any pages --- linux-2.4.21/kernel/ksyms.c Fri Jun 13 16:32:52 2003 -+++ linux/kernel/ksyms.c Mon Sep 1 16:26:19 2003 ++++ linux/kernel/ksyms.c Fri Nov 21 18:03:03 2003 @@ -112,6 +112,7 @@ EXPORT_SYMBOL(vfree); EXPORT_SYMBOL(__vmalloc); @@ -9747,7 +9734,7 @@ EXPORT_SYMBOL(remap_page_range); EXPORT_SYMBOL(max_mapnr); --- linux-2.4.21/mm/Makefile Fri Jan 10 16:36:02 2003 -+++ linux/mm/Makefile Mon Sep 1 16:26:19 2003 ++++ linux/mm/Makefile Fri Nov 21 18:03:10 2003 @@ -9,12 +9,12 @@ O_TARGET := mm.o @@ -9764,7 +9751,7 @@ obj-$(CONFIG_HIGHMEM) += highmem.o --- linux-2.4.21/mm/filemap.c Fri Jun 13 16:33:25 2003 -+++ linux/mm/filemap.c Mon Sep 1 16:26:19 2003 ++++ linux/mm/filemap.c Fri Nov 21 18:03:07 2003 @@ -1704,8 +1704,10 @@ retval = generic_file_direct_IO(READ, filp, buf, count, pos); if (retval > 0) @@ -9793,7 +9780,7 @@ if (file->f_flags & O_DIRECT) goto o_direct; --- linux-2.4.21/mm/mempool.c Thu Jan 1 01:00:00 1970 -+++ linux/mm/mempool.c Mon Sep 1 16:26:19 2003 ++++ linux/mm/mempool.c Fri Nov 21 18:03:10 2003 @@ -0,0 +1,299 @@ +/* + * linux/mm/mempool.c @@ -10095,7 +10082,7 @@ +EXPORT_SYMBOL(mempool_alloc_slab); +EXPORT_SYMBOL(mempool_free_slab); --- linux-2.4.21/mm/vmalloc.c Fri Jun 13 16:33:25 2003 -+++ linux/mm/vmalloc.c Mon Sep 1 16:26:19 2003 ++++ linux/mm/vmalloc.c Fri Nov 21 18:03:03 2003 @@ -327,3 +327,22 @@ read_unlock(&vmlist_lock); return buf - buf_start; -- 2.43.5