Commit 78134d08 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/net-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 8ef8f7b5 f767677f
...@@ -351,7 +351,8 @@ static int next_target(struct dm_target_spec *last, uint32_t next, ...@@ -351,7 +351,8 @@ static int next_target(struct dm_target_spec *last, uint32_t next,
static int populate_table(struct dm_table *table, struct dm_ioctl *args) static int populate_table(struct dm_table *table, struct dm_ioctl *args)
{ {
int i = 0, r, first = 1; int r, first = 1;
unsigned int i = 0;
struct dm_target_spec *spec; struct dm_target_spec *spec;
char *params; char *params;
void *begin, *end; void *begin, *end;
...@@ -380,7 +381,8 @@ static int populate_table(struct dm_table *table, struct dm_ioctl *args) ...@@ -380,7 +381,8 @@ static int populate_table(struct dm_table *table, struct dm_ioctl *args)
} }
r = dm_table_add_target(table, spec->target_type, r = dm_table_add_target(table, spec->target_type,
spec->sector_start, spec->length, (sector_t) spec->sector_start,
(sector_t) spec->length,
params); params);
if (r) { if (r) {
DMWARN("internal error adding target to table"); DMWARN("internal error adding target to table");
...@@ -558,7 +560,7 @@ static int create(struct dm_ioctl *param, struct dm_ioctl *user) ...@@ -558,7 +560,7 @@ static int create(struct dm_ioctl *param, struct dm_ioctl *user)
int r; int r;
struct dm_table *t; struct dm_table *t;
struct mapped_device *md; struct mapped_device *md;
int minor; unsigned int minor = 0;
r = check_name(param->name); r = check_name(param->name);
if (r) if (r)
...@@ -574,8 +576,8 @@ static int create(struct dm_ioctl *param, struct dm_ioctl *user) ...@@ -574,8 +576,8 @@ static int create(struct dm_ioctl *param, struct dm_ioctl *user)
return r; return r;
} }
minor = (param->flags & DM_PERSISTENT_DEV_FLAG) ? if (param->flags & DM_PERSISTENT_DEV_FLAG)
minor(to_kdev_t(param->dev)) : -1; minor = minor(to_kdev_t(param->dev));
r = dm_create(minor, t, &md); r = dm_create(minor, t, &md);
if (r) { if (r) {
...@@ -584,7 +586,7 @@ static int create(struct dm_ioctl *param, struct dm_ioctl *user) ...@@ -584,7 +586,7 @@ static int create(struct dm_ioctl *param, struct dm_ioctl *user)
} }
dm_table_put(t); /* md will have grabbed its own reference */ dm_table_put(t); /* md will have grabbed its own reference */
set_disk_ro(dm_disk(md), (param->flags & DM_READONLY_FLAG)); set_disk_ro(dm_disk(md), (param->flags & DM_READONLY_FLAG) ? 1 : 0);
r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md); r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md);
dm_put(md); dm_put(md);
...@@ -595,9 +597,9 @@ static int create(struct dm_ioctl *param, struct dm_ioctl *user) ...@@ -595,9 +597,9 @@ static int create(struct dm_ioctl *param, struct dm_ioctl *user)
* Build up the status struct for each target * Build up the status struct for each target
*/ */
static int __status(struct mapped_device *md, struct dm_ioctl *param, static int __status(struct mapped_device *md, struct dm_ioctl *param,
char *outbuf, int *len) char *outbuf, size_t *len)
{ {
int i, num_targets; unsigned int i, num_targets;
struct dm_target_spec *spec; struct dm_target_spec *spec;
char *outptr; char *outptr;
status_type_t type; status_type_t type;
...@@ -657,7 +659,7 @@ static int __status(struct mapped_device *md, struct dm_ioctl *param, ...@@ -657,7 +659,7 @@ static int __status(struct mapped_device *md, struct dm_ioctl *param,
static int get_status(struct dm_ioctl *param, struct dm_ioctl *user) static int get_status(struct dm_ioctl *param, struct dm_ioctl *user)
{ {
struct mapped_device *md; struct mapped_device *md;
int len = 0; size_t len = 0;
int ret; int ret;
char *outbuf = NULL; char *outbuf = NULL;
...@@ -738,7 +740,8 @@ static int wait_device_event(struct dm_ioctl *param, struct dm_ioctl *user) ...@@ -738,7 +740,8 @@ static int wait_device_event(struct dm_ioctl *param, struct dm_ioctl *user)
*/ */
static int dep(struct dm_ioctl *param, struct dm_ioctl *user) static int dep(struct dm_ioctl *param, struct dm_ioctl *user)
{ {
int count, r; int r;
unsigned int count;
struct mapped_device *md; struct mapped_device *md;
struct list_head *tmp; struct list_head *tmp;
size_t len = 0; size_t len = 0;
...@@ -889,7 +892,7 @@ static int reload(struct dm_ioctl *param, struct dm_ioctl *user) ...@@ -889,7 +892,7 @@ static int reload(struct dm_ioctl *param, struct dm_ioctl *user)
} }
dm_table_put(t); /* md will have taken its own reference */ dm_table_put(t); /* md will have taken its own reference */
set_disk_ro(dm_disk(md), (param->flags & DM_READONLY_FLAG)); set_disk_ro(dm_disk(md), (param->flags & DM_READONLY_FLAG) ? 1 : 0);
dm_put(md); dm_put(md);
r = info(param, user); r = info(param, user);
...@@ -945,7 +948,7 @@ static ioctl_fn lookup_ioctl(unsigned int cmd) ...@@ -945,7 +948,7 @@ static ioctl_fn lookup_ioctl(unsigned int cmd)
* As well as checking the version compatibility this always * As well as checking the version compatibility this always
* copies the kernel interface version out. * copies the kernel interface version out.
*/ */
static int check_version(int cmd, struct dm_ioctl *user) static int check_version(unsigned int cmd, struct dm_ioctl *user)
{ {
uint32_t version[3]; uint32_t version[3];
int r = 0; int r = 0;
...@@ -1028,7 +1031,8 @@ static int validate_params(uint cmd, struct dm_ioctl *param) ...@@ -1028,7 +1031,8 @@ static int validate_params(uint cmd, struct dm_ioctl *param)
static int ctl_ioctl(struct inode *inode, struct file *file, static int ctl_ioctl(struct inode *inode, struct file *file,
uint command, ulong u) uint command, ulong u)
{ {
int r = 0, cmd; int r = 0;
unsigned int cmd;
struct dm_ioctl *param; struct dm_ioctl *param;
struct dm_ioctl *user = (struct dm_ioctl *) u; struct dm_ioctl *user = (struct dm_ioctl *) u;
ioctl_fn fn = NULL; ioctl_fn fn = NULL;
......
...@@ -23,7 +23,7 @@ struct linear_c { ...@@ -23,7 +23,7 @@ struct linear_c {
/* /*
* Construct a linear mapping: <dev_path> <offset> * Construct a linear mapping: <dev_path> <offset>
*/ */
static int linear_ctr(struct dm_target *ti, int argc, char **argv) static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
{ {
struct linear_c *lc; struct linear_c *lc;
...@@ -76,7 +76,7 @@ static int linear_map(struct dm_target *ti, struct bio *bio) ...@@ -76,7 +76,7 @@ static int linear_map(struct dm_target *ti, struct bio *bio)
} }
static int linear_status(struct dm_target *ti, status_type_t type, static int linear_status(struct dm_target *ti, status_type_t type,
char *result, int maxlen) char *result, unsigned int maxlen)
{ {
struct linear_c *lc = (struct linear_c *) ti->private; struct linear_c *lc = (struct linear_c *) ti->private;
char b[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE];
......
...@@ -30,7 +30,7 @@ struct stripe_c { ...@@ -30,7 +30,7 @@ struct stripe_c {
struct stripe stripe[0]; struct stripe stripe[0];
}; };
static inline struct stripe_c *alloc_context(int stripes) static inline struct stripe_c *alloc_context(unsigned int stripes)
{ {
size_t len; size_t len;
...@@ -47,7 +47,7 @@ static inline struct stripe_c *alloc_context(int stripes) ...@@ -47,7 +47,7 @@ static inline struct stripe_c *alloc_context(int stripes)
* Parse a single <dev> <sector> pair * Parse a single <dev> <sector> pair
*/ */
static int get_stripe(struct dm_target *ti, struct stripe_c *sc, static int get_stripe(struct dm_target *ti, struct stripe_c *sc,
int stripe, char **argv) unsigned int stripe, char **argv)
{ {
sector_t start; sector_t start;
...@@ -91,14 +91,15 @@ static int multiple(sector_t a, sector_t b, sector_t *n) ...@@ -91,14 +91,15 @@ static int multiple(sector_t a, sector_t b, sector_t *n)
* Construct a striped mapping. * Construct a striped mapping.
* <number of stripes> <chunk size (2^^n)> [<dev_path> <offset>]+ * <number of stripes> <chunk size (2^^n)> [<dev_path> <offset>]+
*/ */
static int stripe_ctr(struct dm_target *ti, int argc, char **argv) static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
{ {
struct stripe_c *sc; struct stripe_c *sc;
sector_t width; sector_t width;
uint32_t stripes; uint32_t stripes;
uint32_t chunk_size; uint32_t chunk_size;
char *end; char *end;
int r, i; int r;
unsigned int i;
if (argc < 2) { if (argc < 2) {
ti->error = "dm-stripe: Not enough arguments"; ti->error = "dm-stripe: Not enough arguments";
...@@ -204,11 +205,11 @@ static int stripe_map(struct dm_target *ti, struct bio *bio) ...@@ -204,11 +205,11 @@ static int stripe_map(struct dm_target *ti, struct bio *bio)
} }
static int stripe_status(struct dm_target *ti, static int stripe_status(struct dm_target *ti,
status_type_t type, char *result, int maxlen) status_type_t type, char *result, unsigned int maxlen)
{ {
struct stripe_c *sc = (struct stripe_c *) ti->private; struct stripe_c *sc = (struct stripe_c *) ti->private;
int offset; int offset;
int i; unsigned int i;
char b[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE];
switch (type) { switch (type) {
......
...@@ -23,12 +23,12 @@ struct dm_table { ...@@ -23,12 +23,12 @@ struct dm_table {
atomic_t holders; atomic_t holders;
/* btree table */ /* btree table */
int depth; unsigned int depth;
int counts[MAX_DEPTH]; /* in nodes */ unsigned int counts[MAX_DEPTH]; /* in nodes */
sector_t *index[MAX_DEPTH]; sector_t *index[MAX_DEPTH];
int num_targets; unsigned int num_targets;
int num_allocated; unsigned int num_allocated;
sector_t *highs; sector_t *highs;
struct dm_target *targets; struct dm_target *targets;
...@@ -55,14 +55,6 @@ struct dm_table { ...@@ -55,14 +55,6 @@ struct dm_table {
wait_queue_head_t eventq; wait_queue_head_t eventq;
}; };
/*
* Ceiling(n / size)
*/
static inline unsigned long div_up(unsigned long n, unsigned long size)
{
return dm_round_up(n, size) / size;
}
/* /*
* Similar to ceiling(log_size(n)) * Similar to ceiling(log_size(n))
*/ */
...@@ -71,35 +63,46 @@ static unsigned int int_log(unsigned long n, unsigned long base) ...@@ -71,35 +63,46 @@ static unsigned int int_log(unsigned long n, unsigned long base)
int result = 0; int result = 0;
while (n > 1) { while (n > 1) {
n = div_up(n, base); n = dm_div_up(n, base);
result++; result++;
} }
return result; return result;
} }
#define __HIGH(l, r) if (*(l) < (r)) *(l) = (r) /*
#define __LOW(l, r) if (*(l) == 0 || *(l) > (r)) *(l) = (r) * Returns the minimum that is _not_ zero, unless both are zero.
*/
#define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r))
/* /*
* Combine two io_restrictions, always taking the lower value. * Combine two io_restrictions, always taking the lower value.
*/ */
static void combine_restrictions_low(struct io_restrictions *lhs, static void combine_restrictions_low(struct io_restrictions *lhs,
struct io_restrictions *rhs) struct io_restrictions *rhs)
{ {
__LOW(&lhs->max_sectors, rhs->max_sectors); lhs->max_sectors =
__LOW(&lhs->max_phys_segments, rhs->max_phys_segments); min_not_zero(lhs->max_sectors, rhs->max_sectors);
__LOW(&lhs->max_hw_segments, rhs->max_hw_segments);
__HIGH(&lhs->hardsect_size, rhs->hardsect_size); lhs->max_phys_segments =
__LOW(&lhs->max_segment_size, rhs->max_segment_size); min_not_zero(lhs->max_phys_segments, rhs->max_phys_segments);
__LOW(&lhs->seg_boundary_mask, rhs->seg_boundary_mask);
lhs->max_hw_segments =
min_not_zero(lhs->max_hw_segments, rhs->max_hw_segments);
lhs->hardsect_size = max(lhs->hardsect_size, rhs->hardsect_size);
lhs->max_segment_size =
min_not_zero(lhs->max_segment_size, rhs->max_segment_size);
lhs->seg_boundary_mask =
min_not_zero(lhs->seg_boundary_mask, rhs->seg_boundary_mask);
} }
/* /*
* Calculate the index of the child node of the n'th node k'th key. * Calculate the index of the child node of the n'th node k'th key.
*/ */
static inline int get_child(int n, int k) static inline unsigned int get_child(unsigned int n, unsigned int k)
{ {
return (n * CHILDREN_PER_NODE) + k; return (n * CHILDREN_PER_NODE) + k;
} }
...@@ -107,7 +110,8 @@ static inline int get_child(int n, int k) ...@@ -107,7 +110,8 @@ static inline int get_child(int n, int k)
/* /*
* Return the n'th node of level l from table t. * Return the n'th node of level l from table t.
*/ */
static inline sector_t *get_node(struct dm_table *t, int l, int n) static inline sector_t *get_node(struct dm_table *t,
unsigned int l, unsigned int n)
{ {
return t->index[l] + (n * KEYS_PER_NODE); return t->index[l] + (n * KEYS_PER_NODE);
} }
...@@ -116,7 +120,7 @@ static inline sector_t *get_node(struct dm_table *t, int l, int n) ...@@ -116,7 +120,7 @@ static inline sector_t *get_node(struct dm_table *t, int l, int n)
* Return the highest key that you could lookup from the n'th * Return the highest key that you could lookup from the n'th
* node on level l of the btree. * node on level l of the btree.
*/ */
static sector_t high(struct dm_table *t, int l, int n) static sector_t high(struct dm_table *t, unsigned int l, unsigned int n)
{ {
for (; l < t->depth - 1; l++) for (; l < t->depth - 1; l++)
n = get_child(n, CHILDREN_PER_NODE - 1); n = get_child(n, CHILDREN_PER_NODE - 1);
...@@ -131,15 +135,15 @@ static sector_t high(struct dm_table *t, int l, int n) ...@@ -131,15 +135,15 @@ static sector_t high(struct dm_table *t, int l, int n)
* Fills in a level of the btree based on the highs of the level * Fills in a level of the btree based on the highs of the level
* below it. * below it.
*/ */
static int setup_btree_index(int l, struct dm_table *t) static int setup_btree_index(unsigned int l, struct dm_table *t)
{ {
int n, k; unsigned int n, k;
sector_t *node; sector_t *node;
for (n = 0; n < t->counts[l]; n++) { for (n = 0U; n < t->counts[l]; n++) {
node = get_node(t, l, n); node = get_node(t, l, n);
for (k = 0; k < KEYS_PER_NODE; k++) for (k = 0U; k < KEYS_PER_NODE; k++)
node[k] = high(t, l + 1, get_child(n, k)); node[k] = high(t, l + 1, get_child(n, k));
} }
...@@ -169,7 +173,7 @@ static void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size) ...@@ -169,7 +173,7 @@ static void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size)
* highs, and targets are managed as dynamic arrays during a * highs, and targets are managed as dynamic arrays during a
* table load. * table load.
*/ */
static int alloc_targets(struct dm_table *t, int num) static int alloc_targets(struct dm_table *t, unsigned int num)
{ {
sector_t *n_highs; sector_t *n_highs;
struct dm_target *n_targets; struct dm_target *n_targets;
...@@ -237,9 +241,7 @@ static void free_devices(struct list_head *devices) ...@@ -237,9 +241,7 @@ static void free_devices(struct list_head *devices)
void table_destroy(struct dm_table *t) void table_destroy(struct dm_table *t)
{ {
int i; unsigned int i;
DMWARN("destroying table");
/* destroying the table counts as an event */ /* destroying the table counts as an event */
dm_table_event(t); dm_table_event(t);
...@@ -481,13 +483,31 @@ int dm_get_device(struct dm_target *ti, const char *path, sector_t start, ...@@ -481,13 +483,31 @@ int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
request_queue_t *q = bdev_get_queue((*result)->bdev); request_queue_t *q = bdev_get_queue((*result)->bdev);
struct io_restrictions *rs = &ti->limits; struct io_restrictions *rs = &ti->limits;
/* combine the device limits low */ /*
__LOW(&rs->max_sectors, q->max_sectors); * Combine the device limits low.
__LOW(&rs->max_phys_segments, q->max_phys_segments); *
__LOW(&rs->max_hw_segments, q->max_hw_segments); * FIXME: if we move an io_restriction struct
__HIGH(&rs->hardsect_size, q->hardsect_size); * into q this would just be a call to
__LOW(&rs->max_segment_size, q->max_segment_size); * combine_restrictions_low()
__LOW(&rs->seg_boundary_mask, q->seg_boundary_mask); */
rs->max_sectors =
min_not_zero(rs->max_sectors, q->max_sectors);
rs->max_phys_segments =
min_not_zero(rs->max_phys_segments,
q->max_phys_segments);
rs->max_hw_segments =
min_not_zero(rs->max_hw_segments, q->max_hw_segments);
rs->hardsect_size = max(rs->hardsect_size, q->hardsect_size);
rs->max_segment_size =
min_not_zero(rs->max_segment_size, q->max_segment_size);
rs->seg_boundary_mask =
min_not_zero(rs->seg_boundary_mask,
q->seg_boundary_mask);
} }
return r; return r;
...@@ -628,12 +648,13 @@ int dm_table_add_target(struct dm_table *t, const char *type, ...@@ -628,12 +648,13 @@ int dm_table_add_target(struct dm_table *t, const char *type,
static int setup_indexes(struct dm_table *t) static int setup_indexes(struct dm_table *t)
{ {
int i, total = 0; int i;
unsigned int total = 0;
sector_t *indexes; sector_t *indexes;
/* allocate the space for *all* the indexes */ /* allocate the space for *all* the indexes */
for (i = t->depth - 2; i >= 0; i--) { for (i = t->depth - 2; i >= 0; i--) {
t->counts[i] = div_up(t->counts[i + 1], CHILDREN_PER_NODE); t->counts[i] = dm_div_up(t->counts[i + 1], CHILDREN_PER_NODE);
total += t->counts[i]; total += t->counts[i];
} }
...@@ -656,10 +677,11 @@ static int setup_indexes(struct dm_table *t) ...@@ -656,10 +677,11 @@ static int setup_indexes(struct dm_table *t)
*/ */
int dm_table_complete(struct dm_table *t) int dm_table_complete(struct dm_table *t)
{ {
int leaf_nodes, r = 0; int r = 0;
unsigned int leaf_nodes;
/* how many indexes will the btree have ? */ /* how many indexes will the btree have ? */
leaf_nodes = div_up(t->num_targets, KEYS_PER_NODE); leaf_nodes = dm_div_up(t->num_targets, KEYS_PER_NODE);
t->depth = 1 + int_log(leaf_nodes, CHILDREN_PER_NODE); t->depth = 1 + int_log(leaf_nodes, CHILDREN_PER_NODE);
/* leaf layer has already been set up */ /* leaf layer has already been set up */
...@@ -682,7 +704,7 @@ sector_t dm_table_get_size(struct dm_table *t) ...@@ -682,7 +704,7 @@ sector_t dm_table_get_size(struct dm_table *t)
return t->num_targets ? (t->highs[t->num_targets - 1] + 1) : 0; return t->num_targets ? (t->highs[t->num_targets - 1] + 1) : 0;
} }
struct dm_target *dm_table_get_target(struct dm_table *t, int index) struct dm_target *dm_table_get_target(struct dm_table *t, unsigned int index)
{ {
if (index > t->num_targets) if (index > t->num_targets)
return NULL; return NULL;
...@@ -695,7 +717,7 @@ struct dm_target *dm_table_get_target(struct dm_table *t, int index) ...@@ -695,7 +717,7 @@ struct dm_target *dm_table_get_target(struct dm_table *t, int index)
*/ */
struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector) struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector)
{ {
int l, n = 0, k = 0; unsigned int l, n = 0, k = 0;
sector_t *node; sector_t *node;
for (l = 0; l < t->depth; l++) { for (l = 0; l < t->depth; l++) {
...@@ -744,6 +766,31 @@ void dm_table_add_wait_queue(struct dm_table *t, wait_queue_t *wq) ...@@ -744,6 +766,31 @@ void dm_table_add_wait_queue(struct dm_table *t, wait_queue_t *wq)
add_wait_queue(&t->eventq, wq); add_wait_queue(&t->eventq, wq);
} }
void dm_table_suspend_targets(struct dm_table *t)
{
int i;
for (i = 0; i < t->num_targets; i++) {
struct dm_target *ti = t->targets + i;
if (ti->type->suspend)
ti->type->suspend(ti);
}
}
void dm_table_resume_targets(struct dm_table *t)
{
int i;
for (i = 0; i < t->num_targets; i++) {
struct dm_target *ti = t->targets + i;
if (ti->type->resume)
ti->type->resume(ti);
}
}
EXPORT_SYMBOL(dm_get_device); EXPORT_SYMBOL(dm_get_device);
EXPORT_SYMBOL(dm_put_device); EXPORT_SYMBOL(dm_put_device);
EXPORT_SYMBOL(dm_table_event); EXPORT_SYMBOL(dm_table_event);
......
...@@ -109,9 +109,10 @@ int dm_register_target(struct target_type *t) ...@@ -109,9 +109,10 @@ int dm_register_target(struct target_type *t)
return -ENOMEM; return -ENOMEM;
down_write(&_lock); down_write(&_lock);
if (__find_target_type(t->name)) if (__find_target_type(t->name)) {
kfree(ti);
rv = -EEXIST; rv = -EEXIST;
else } else
list_add(&ti->list, &_targets); list_add(&ti->list, &_targets);
up_write(&_lock); up_write(&_lock);
...@@ -146,7 +147,7 @@ int dm_unregister_target(struct target_type *t) ...@@ -146,7 +147,7 @@ int dm_unregister_target(struct target_type *t)
* io-err: always fails an io, useful for bringing * io-err: always fails an io, useful for bringing
* up LVs that have holes in them. * up LVs that have holes in them.
*/ */
static int io_err_ctr(struct dm_target *ti, int argc, char **args) static int io_err_ctr(struct dm_target *ti, unsigned int argc, char **args)
{ {
return 0; return 0;
} }
......
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
static const char *_name = DM_NAME; static const char *_name = DM_NAME;
#define MAX_DEVICES 1024 #define MAX_DEVICES 1024
static int major = 0; static unsigned int major = 0;
static int _major = 0; static unsigned int _major = 0;
struct dm_io { struct dm_io {
struct mapped_device *md; struct mapped_device *md;
...@@ -281,9 +281,6 @@ static sector_t max_io_len(struct mapped_device *md, ...@@ -281,9 +281,6 @@ static sector_t max_io_len(struct mapped_device *md,
sector_t offset = sector - ti->begin; sector_t offset = sector - ti->begin;
sector_t len = ti->len - offset; sector_t len = ti->len - offset;
/* FIXME: obey io_restrictions ! */
/* /*
* Does the target need to split even further ? * Does the target need to split even further ?
*/ */
...@@ -524,7 +521,7 @@ static int dm_request(request_queue_t *q, struct bio *bio) ...@@ -524,7 +521,7 @@ static int dm_request(request_queue_t *q, struct bio *bio)
static spinlock_t _minor_lock = SPIN_LOCK_UNLOCKED; static spinlock_t _minor_lock = SPIN_LOCK_UNLOCKED;
static unsigned long _minor_bits[MAX_DEVICES / BITS_PER_LONG]; static unsigned long _minor_bits[MAX_DEVICES / BITS_PER_LONG];
static void free_minor(int minor) static void free_minor(unsigned int minor)
{ {
spin_lock(&_minor_lock); spin_lock(&_minor_lock);
clear_bit(minor, _minor_bits); clear_bit(minor, _minor_bits);
...@@ -534,7 +531,7 @@ static void free_minor(int minor) ...@@ -534,7 +531,7 @@ static void free_minor(int minor)
/* /*
* See if the device with a specific minor # is free. * See if the device with a specific minor # is free.
*/ */
static int specific_minor(int minor) static int specific_minor(unsigned int minor)
{ {
int r = -EBUSY; int r = -EBUSY;
...@@ -546,21 +543,23 @@ static int specific_minor(int minor) ...@@ -546,21 +543,23 @@ static int specific_minor(int minor)
spin_lock(&_minor_lock); spin_lock(&_minor_lock);
if (!test_and_set_bit(minor, _minor_bits)) if (!test_and_set_bit(minor, _minor_bits))
r = minor; r = 0;
spin_unlock(&_minor_lock); spin_unlock(&_minor_lock);
return r; return r;
} }
static int next_free_minor(void) static int next_free_minor(unsigned int *minor)
{ {
int minor, r = -EBUSY; int r = -EBUSY;
unsigned int m;
spin_lock(&_minor_lock); spin_lock(&_minor_lock);
minor = find_first_zero_bit(_minor_bits, MAX_DEVICES); m = find_first_zero_bit(_minor_bits, MAX_DEVICES);
if (minor != MAX_DEVICES) { if (m != MAX_DEVICES) {
set_bit(minor, _minor_bits); set_bit(m, _minor_bits);
r = minor; *minor = m;
r = 0;
} }
spin_unlock(&_minor_lock); spin_unlock(&_minor_lock);
...@@ -570,8 +569,9 @@ static int next_free_minor(void) ...@@ -570,8 +569,9 @@ static int next_free_minor(void)
/* /*
* Allocate and initialise a blank device with a given minor. * Allocate and initialise a blank device with a given minor.
*/ */
static struct mapped_device *alloc_dev(int minor) static struct mapped_device *alloc_dev(unsigned int minor)
{ {
int r;
struct mapped_device *md = kmalloc(sizeof(*md), GFP_KERNEL); struct mapped_device *md = kmalloc(sizeof(*md), GFP_KERNEL);
if (!md) { if (!md) {
...@@ -580,13 +580,12 @@ static struct mapped_device *alloc_dev(int minor) ...@@ -580,13 +580,12 @@ static struct mapped_device *alloc_dev(int minor)
} }
/* get a minor number for the dev */ /* get a minor number for the dev */
minor = (minor < 0) ? next_free_minor() : specific_minor(minor); r = (minor < 0) ? next_free_minor(&minor) : specific_minor(minor);
if (minor < 0) { if (r < 0) {
kfree(md); kfree(md);
return NULL; return NULL;
} }
DMWARN("allocating minor %d.", minor);
memset(md, 0, sizeof(*md)); memset(md, 0, sizeof(*md));
init_rwsem(&md->lock); init_rwsem(&md->lock);
atomic_set(&md->holders, 1); atomic_set(&md->holders, 1);
...@@ -597,7 +596,7 @@ static struct mapped_device *alloc_dev(int minor) ...@@ -597,7 +596,7 @@ static struct mapped_device *alloc_dev(int minor)
md->io_pool = mempool_create(MIN_IOS, mempool_alloc_slab, md->io_pool = mempool_create(MIN_IOS, mempool_alloc_slab,
mempool_free_slab, _io_cache); mempool_free_slab, _io_cache);
if (!md->io_pool) { if (!md->io_pool) {
free_minor(md->disk->first_minor); free_minor(minor);
kfree(md); kfree(md);
return NULL; return NULL;
} }
...@@ -605,7 +604,7 @@ static struct mapped_device *alloc_dev(int minor) ...@@ -605,7 +604,7 @@ static struct mapped_device *alloc_dev(int minor)
md->disk = alloc_disk(1); md->disk = alloc_disk(1);
if (!md->disk) { if (!md->disk) {
mempool_destroy(md->io_pool); mempool_destroy(md->io_pool);
free_minor(md->disk->first_minor); free_minor(minor);
kfree(md); kfree(md);
return NULL; return NULL;
} }
...@@ -661,7 +660,8 @@ static void __unbind(struct mapped_device *md) ...@@ -661,7 +660,8 @@ static void __unbind(struct mapped_device *md)
/* /*
* Constructor for a new device. * Constructor for a new device.
*/ */
int dm_create(int minor, struct dm_table *table, struct mapped_device **result) int dm_create(unsigned int minor, struct dm_table *table,
struct mapped_device **result)
{ {
int r; int r;
struct mapped_device *md; struct mapped_device *md;
...@@ -675,6 +675,7 @@ int dm_create(int minor, struct dm_table *table, struct mapped_device **result) ...@@ -675,6 +675,7 @@ int dm_create(int minor, struct dm_table *table, struct mapped_device **result)
free_dev(md); free_dev(md);
return r; return r;
} }
dm_table_resume_targets(md->map);
*result = md; *result = md;
return 0; return 0;
...@@ -688,7 +689,8 @@ void dm_get(struct mapped_device *md) ...@@ -688,7 +689,8 @@ void dm_get(struct mapped_device *md)
void dm_put(struct mapped_device *md) void dm_put(struct mapped_device *md)
{ {
if (atomic_dec_and_test(&md->holders)) { if (atomic_dec_and_test(&md->holders)) {
DMWARN("destroying md"); if (!test_bit(DMF_SUSPENDED, &md->flags))
dm_table_suspend_targets(md->map);
__unbind(md); __unbind(md);
free_dev(md); free_dev(md);
} }
...@@ -778,6 +780,7 @@ int dm_suspend(struct mapped_device *md) ...@@ -778,6 +780,7 @@ int dm_suspend(struct mapped_device *md)
down_write(&md->lock); down_write(&md->lock);
remove_wait_queue(&md->wait, &wait); remove_wait_queue(&md->wait, &wait);
set_bit(DMF_SUSPENDED, &md->flags); set_bit(DMF_SUSPENDED, &md->flags);
dm_table_suspend_targets(md->map);
up_write(&md->lock); up_write(&md->lock);
return 0; return 0;
...@@ -794,6 +797,7 @@ int dm_resume(struct mapped_device *md) ...@@ -794,6 +797,7 @@ int dm_resume(struct mapped_device *md)
return -EINVAL; return -EINVAL;
} }
dm_table_resume_targets(md->map);
clear_bit(DMF_SUSPENDED, &md->flags); clear_bit(DMF_SUSPENDED, &md->flags);
clear_bit(DMF_BLOCK_IO, &md->flags); clear_bit(DMF_BLOCK_IO, &md->flags);
def = md->deferred; def = md->deferred;
......
...@@ -51,7 +51,8 @@ struct mapped_device; ...@@ -51,7 +51,8 @@ struct mapped_device;
* Functions for manipulating a struct mapped_device. * Functions for manipulating a struct mapped_device.
* Drop the reference with dm_put when you finish with the object. * Drop the reference with dm_put when you finish with the object.
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
int dm_create(int minor, struct dm_table *table, struct mapped_device **md); int dm_create(unsigned int minor, struct dm_table *table,
struct mapped_device **md);
/* /*
* Reference counting for md. * Reference counting for md.
...@@ -96,13 +97,15 @@ int dm_table_add_target(struct dm_table *t, const char *type, ...@@ -96,13 +97,15 @@ int dm_table_add_target(struct dm_table *t, const char *type,
int dm_table_complete(struct dm_table *t); int dm_table_complete(struct dm_table *t);
void dm_table_event(struct dm_table *t); void dm_table_event(struct dm_table *t);
sector_t dm_table_get_size(struct dm_table *t); sector_t dm_table_get_size(struct dm_table *t);
struct dm_target *dm_table_get_target(struct dm_table *t, int index); struct dm_target *dm_table_get_target(struct dm_table *t, unsigned int index);
struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector); struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector);
void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q); void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q);
unsigned int dm_table_get_num_targets(struct dm_table *t); unsigned int dm_table_get_num_targets(struct dm_table *t);
struct list_head *dm_table_get_devices(struct dm_table *t); struct list_head *dm_table_get_devices(struct dm_table *t);
int dm_table_get_mode(struct dm_table *t); int dm_table_get_mode(struct dm_table *t);
void dm_table_add_wait_queue(struct dm_table *t, wait_queue_t *wq); void dm_table_add_wait_queue(struct dm_table *t, wait_queue_t *wq);
void dm_table_suspend_targets(struct dm_table *t);
void dm_table_resume_targets(struct dm_table *t);
/*----------------------------------------------------------------- /*-----------------------------------------------------------------
* A registry of target types. * A registry of target types.
...@@ -131,6 +134,14 @@ static inline unsigned long dm_round_up(unsigned long n, unsigned long size) ...@@ -131,6 +134,14 @@ static inline unsigned long dm_round_up(unsigned long n, unsigned long size)
return n + (r ? (size - r) : 0); return n + (r ? (size - r) : 0);
} }
/*
* Ceiling(n / size)
*/
static inline unsigned long dm_div_up(unsigned long n, unsigned long size)
{
return dm_round_up(n, size) / size;
}
/* /*
* The device-mapper can be driven through one of two interfaces; * The device-mapper can be driven through one of two interfaces;
* ioctl or filesystem, depending which patch you have applied. * ioctl or filesystem, depending which patch you have applied.
......
...@@ -17,7 +17,8 @@ typedef enum { STATUSTYPE_INFO, STATUSTYPE_TABLE } status_type_t; ...@@ -17,7 +17,8 @@ typedef enum { STATUSTYPE_INFO, STATUSTYPE_TABLE } status_type_t;
* In the constructor the target parameter will already have the * In the constructor the target parameter will already have the
* table, type, begin and len fields filled in. * table, type, begin and len fields filled in.
*/ */
typedef int (*dm_ctr_fn) (struct dm_target *target, int argc, char **argv); typedef int (*dm_ctr_fn) (struct dm_target *target,
unsigned int argc, char **argv);
/* /*
* The destructor doesn't need to free the dm_target, just * The destructor doesn't need to free the dm_target, just
...@@ -32,8 +33,12 @@ typedef void (*dm_dtr_fn) (struct dm_target *ti); ...@@ -32,8 +33,12 @@ typedef void (*dm_dtr_fn) (struct dm_target *ti);
* > 0: simple remap complete * > 0: simple remap complete
*/ */
typedef int (*dm_map_fn) (struct dm_target *ti, struct bio *bio); typedef int (*dm_map_fn) (struct dm_target *ti, struct bio *bio);
typedef void (*dm_suspend_fn) (struct dm_target *ti);
typedef void (*dm_resume_fn) (struct dm_target *ti);
typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type, typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type,
char *result, int maxlen); char *result, unsigned int maxlen);
void dm_error(const char *message); void dm_error(const char *message);
...@@ -55,6 +60,8 @@ struct target_type { ...@@ -55,6 +60,8 @@ struct target_type {
dm_ctr_fn ctr; dm_ctr_fn ctr;
dm_dtr_fn dtr; dm_dtr_fn dtr;
dm_map_fn map; dm_map_fn map;
dm_suspend_fn suspend;
dm_resume_fn resume;
dm_status_fn status; dm_status_fn status;
}; };
......
...@@ -872,8 +872,9 @@ static void check_match( ...@@ -872,8 +872,9 @@ static void check_match(
* performed for at least two bytes (required for the zip translate_eol * performed for at least two bytes (required for the zip translate_eol
* option -- not supported here). * option -- not supported here).
*/ */
static void fill_window(s) static void fill_window(
deflate_state *s; deflate_state *s
)
{ {
register unsigned n, m; register unsigned n, m;
register Pos *p; register Pos *p;
...@@ -1261,7 +1262,7 @@ static block_state deflate_slow( ...@@ -1261,7 +1262,7 @@ static block_state deflate_slow(
return flush == Z_FINISH ? finish_done : block_done; return flush == Z_FINISH ? finish_done : block_done;
} }
extern int zlib_deflate_workspacesize () extern int zlib_deflate_workspacesize(void)
{ {
return sizeof(deflate_workspace); return sizeof(deflate_workspace);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment