device-mapper patchset 2.5.54-dm-1
Linus,
Could you please apply the following patches ?
Thanks,
- Joe
PATCH 1/10 dm: Don't let the ioctl interface drop a suspended device
Don't let the ioctl interface drop a suspended device.
drivers/md/dm-ioctl.c +18 -0
@@ -812,6 +812,24 @@return -EINVAL ; } +/* +* You may ask the interface to drop its reference to an +* in use device. This is no different to unlinking a +* file that someone still has open. The device will not +* actually be destroyed until the last opener closes it. +* The name and uuid of the device (both are interface +* properties) will be available for reuse immediately. +* +* You don't want to drop a _suspended_ device from the +* interface, since that will leave you with no way of +* resuming it. +*/ +if (dm_suspended (hc->md)) { +DMWARN ("refusing to remove a suspended device." ); +up_write (&_hash_lock); +return -EPERM ; + } +__hash_remove (hc);up_write (&_hash_lock);return 0 ;
PATCH 2/10 dm: Correct clone info initialisation
In reply to Joe ThornberInitialize the clone-info's index to the original bio's index. Required to properly handle stacking DM devices. [Kevin Corry]
drivers/md/dm.c +1 -1
@@ -475,7 +475,7 @@ ci.io->md = md; ci.sector = bio->bi_sector; ci.sector_count =bio_sectors (bio); - ci.idx =0 ; + ci.idx = bio->bi_idx;atomic_inc (&md->pending);while (ci.sector_count)
PATCH 3/10 dm: Correct target_type reference counting
In reply to Joe Thornberti->use was only getting incremented the first time a target type was retrieved (bug introduced by recent hch patch).
drivers/md/dm-target.c +6 -5
@@ -43,15 +43,16 @@struct tt_internal *ti;read_lock (&_lock); + ti =__find_target_type (name); -if (ti && ti->use ==0 ) { -if (try_module_get (ti->tt.module)) - ti->use++; -else +if (ti) { +if ((ti->use ==0 ) && !try_module_get (ti->tt.module)) ti =NULL ; +else + ti->use++; } -read_unlock (&_lock); +read_unlock (&_lock);return ti; }
PATCH 4/10 dm: rwlock_t -> rw_semaphore (fluff)
In reply to Joe ThornberUse a rw_semaphore in dm_target.c rather than a rwlock_t, just to keep in line with dm.c
drivers/md/dm-target.c +11 -11
@@ -19,7 +19,7 @@ };static LIST_HEAD (_targets); -static rwlock_t _lock =RW_LOCK_UNLOCKED ; +static DECLARE_RWSEM (_lock);#define DM_MOD_NAME_SIZE 32
@@ -42,7 +42,7 @@ {struct tt_internal *ti; -read_lock (&_lock); +down_read (&_lock); ti =__find_target_type (name);if (ti) {
@@ -52,7 +52,7 @@ ti->use++; } -read_unlock (&_lock); +up_read (&_lock);return ti; }
@@ -86,13 +86,13 @@ {struct tt_internal *ti = (struct tt_internal *) t; -read_lock (&_lock); +down_read (&_lock);if (--ti->use ==0 )module_put (ti->tt.module);if (ti->use <0 )BUG (); -read_unlock (&_lock); +up_read (&_lock);return ; }
@@ -117,13 +117,13 @@if (!ti)return -ENOMEM ; -write_lock (&_lock); +down_write (&_lock);if (__find_target_type (t->name)) rv = -EEXIST ;else list_add (&ti->list, &_targets); -write_unlock (&_lock); +up_write (&_lock);return rv; }
@@ -131,21 +131,21 @@ {struct tt_internal *ti; -write_lock (&_lock); +down_write (&_lock);if (!(ti =__find_target_type (t->name))) { -write_unlock (&_lock); +up_write (&_lock);return -EINVAL ; }if (ti->use) { -write_unlock (&_lock); +up_write (&_lock);return -ETXTBSY ; }list_del (&ti->list);kfree (ti); -write_unlock (&_lock); +up_write (&_lock);return 0 ; }
PATCH 5/10 dm: Call dm_put_target_type() *after* calling the destructor
In reply to Joe ThornberCall dm_put_target_type() *after* calling the destructor.
drivers/md/dm-table.c +3 -3
@@ -250,12 +250,12 @@/* free the targets */ for (i =0 ; i < t->num_targets; i++) { -struct dm_target *tgt = &t->targets[i]; - -dm_put_target_type (t->targets[i].type); +struct dm_target *tgt = t->targets + i;if (tgt->type->dtr) tgt->type->dtr (tgt); + +dm_put_target_type (tgt->type); }vfree (t->highs);
PATCH 6/10 dm: Remove explicit returns from void fns (fluff)
In reply to Joe ThornberRemove explicit return at the end of a couple of void functions.
drivers/md/dm-target.c +0 -3
@@ -66,8 +66,6 @@strcat (module_name, name);request_module (module_name); - -return ; }struct target_type *dm_get_target_type (const char *name)
@@ -161,7 +159,6 @@static void io_err_dtr (struct dm_target *ti) {/* empty */ -return ; }static int io_err_map (struct dm_target *ti,struct bio *bio)
PATCH 7/10 dm: printk tgt->error if dm_table_add_target() fails.
In reply to Joe Thornberprintk tgt->error if dm_table_add_target() fails.
drivers/md/dm-table.c +15 -16
@@ -578,9 +578,8 @@int dm_table_add_target (struct dm_table *t,const char *type,sector_t start,sector_t len,char *params) { -int r, argc; +int r = -EINVAL , argc;char *argv[32 ]; -struct target_type *tt;struct dm_target *tgt;if ((r =check_space (t)))
@@ -589,14 +588,13 @@ tgt = t->targets + t->num_targets;memset (tgt,0 ,sizeof (*tgt)); - tt =dm_get_target_type (type); -if (!tt) { + tgt->type =dm_get_target_type (type); +if (!tgt->type) { tgt->error ="unknown target type" ; -return -EINVAL ; + goto bad; } tgt->table = t; - tgt->type = tt; tgt->begin = start; tgt->len = len; tgt->error ="Unknown error" ;
@@ -605,23 +603,19 @@* Does this target adjoin the previous one ? */ if (!adjoin (t, tgt)) { -DMERR ("Gap in table" ); -dm_put_target_type (tt); -return -EINVAL ; + tgt->error ="Gap in table" ; + goto bad; } r =split_args (ARRAY_SIZE (argv), &argc, argv, params);if (r) { tgt->error ="couldn't split parameters" ; -dm_put_target_type (tt); -return r; + goto bad; } - r = tt->ctr (tgt, argc, argv); -if (r) { -dm_put_target_type (tt); -return r; - } + r = tgt->type->ctr (tgt, argc, argv); +if (r) + goto bad; t->highs[t->num_targets++] = tgt->begin + tgt->len -1 ;
@@ -629,6 +623,11 @@* the merge fn apply the target level restrictions. */ combine_restrictions_low (&t->limits, &tgt->limits);return 0 ; + + bad: + printk(KERN_ERR DM_NAME ": %s\n", tgt->error); +dm_put_target_type (tgt->type); +return r; }static int setup_indexes (struct dm_table *t)
PATCH 8/10 dm: Simplify error->map
In reply to Joe ThornberJust return an error from the error targets map function, rather than erroring the buffer_head.
drivers/md/dm-target.c +1 -2
@@ -163,8 +163,7 @@static int io_err_map (struct dm_target *ti,struct bio *bio) { -bio_io_error (bio,0 ); -return 0 ; +return -EIO ; }static struct target_type error_target = {
PATCH 9/10 dm: Export dm_table_get_mode()
In reply to Joe ThornberExport dm_table_get_mode()
drivers/md/dm-table.c +1 -0
@@ -751,3 +751,4 @@EXPORT_SYMBOL (dm_get_device);EXPORT_SYMBOL (dm_put_device);EXPORT_SYMBOL (dm_table_event); +EXPORT_SYMBOL (dm_table_get_mode);
PATCH 10/10 dm: Remove redundant error checking
In reply to Joe Thornberbio_alloc() shouldn't fail if GFP_NOIO is used, and the bvec count is sensible. So remove redundant error checking.
drivers/md/dm.c +8 -21
@@ -347,18 +347,15 @@struct bio_vec *bv = bio->bi_io_vec + idx; clone =bio_alloc (GFP_NOIO ,1 ); +memcpy (clone->bi_io_vec, bv,sizeof (*bv)); -if (clone) { -memcpy (clone->bi_io_vec, bv,sizeof (*bv)); - - clone->bi_sector = sector; - clone->bi_bdev = bio->bi_bdev; - clone->bi_rw = bio->bi_rw; - clone->bi_vcnt =1 ; - clone->bi_size =to_bytes (len); - clone->bi_io_vec->bv_offset = offset; - clone->bi_io_vec->bv_len = clone->bi_size; - } + clone->bi_sector = sector; + clone->bi_bdev = bio->bi_bdev; + clone->bi_rw = bio->bi_rw; + clone->bi_vcnt =1 ; + clone->bi_size =to_bytes (len); + clone->bi_io_vec->bv_offset = offset; + clone->bi_io_vec->bv_len = clone->bi_size;return clone; }
@@ -432,11 +429,6 @@ clone =split_bvec (bio, ci->sector, ci->idx, bv->bv_offset, max); -if (!clone) { -dec_pending (ci->io, -ENOMEM ); -return ; - } -__map_bio (ti, clone, ci->io); ci->sector += max;
@@ -446,11 +438,6 @@ len =to_sector (bv->bv_len) - max; clone =split_bvec (bio, ci->sector, ci->idx, bv->bv_offset +to_bytes (max), len); -if (!clone) { -dec_pending (ci->io, -ENOMEM ); -return ; - } -__map_bio (ti, clone, ci->io); ci->sector += len;