Commit 48dc8100 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-6.4/dm-changes' of...

Merge tag 'for-6.4/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull device mapper updates from Mike Snitzer:

 - Split dm-bufio's rw_semaphore and rbtree. Offers improvements to
   dm-bufio's locking to allow increased concurrent IO -- particularly
   for read access for buffers already in dm-bufio's cache.

 - Also split dm-bio-prison-v1's spinlock and rbtree with comparable aim
   at improving concurrent IO (for the DM thinp target).

 - Both the dm-bufio and dm-bio-prison-v1 scaling of the number of locks
   and rbtrees used are managed by dm_num_hash_locks(). And the hash
   function used by both is dm_hash_locks_index().

 - Allow DM targets to require DISCARD, WRITE_ZEROES and SECURE_ERASE to
   be split at the target specified boundary (in terms of
   max_discard_sectors, max_write_zeroes_sectors and
   max_secure_erase_sectors respectively).

 - DM verity error handling fix for check_at_most_once on FEC.

 - Update DM verity target to emit audit events on verification failure
   and more.

 - DM core ->io_hints improvements needed in support of new discard
   support that is added to the DM "zero" and "error" targets.

 - Fix missing kmem_cache_destroy() call in initialization error path of
   both the DM integrity and DM clone targets.

 - A couple fixes for DM flakey, also add "error_reads" feature.

 - Fix DM core's resume to not lock FS when the DM map is NULL;
   otherwise initial table load can race with FS mount that takes
   superblock's ->s_umount rw_semaphore.

 - Various small improvements to both DM core and DM targets.

* tag 'for-6.4/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: (40 commits)
  dm: don't lock fs when the map is NULL in process of resume
  dm flakey: add an "error_reads" option
  dm flakey: remove trailing space in the table line
  dm flakey: fix a crash with invalid table line
  dm ioctl: fix nested locking in table_clear() to remove deadlock concern
  dm: unexport dm_get_queue_limits()
  dm: allow targets to require splitting WRITE_ZEROES and SECURE_ERASE
  dm: add helper macro for simple DM target module init and exit
  dm raid: remove unused d variable
  dm: remove unnecessary (void*) conversions
  dm mirror: add DMERR message if alloc_workqueue fails
  dm: push error reporting down to dm_register_target()
  dm integrity: call kmem_cache_destroy() in dm_integrity_init() error path
  dm clone: call kmem_cache_destroy() in dm_clone_init() error path
  dm error: add discard support
  dm zero: add discard support
  dm table: allow targets without devices to set ->io_hints
  dm verity: emit audit events on verification failure and more
  dm verity: fix error handling for check_at_most_once on FEC
  dm: improve hash_locks sizing and hash function
  ...
parents 9dd6956b 38d11da5
......@@ -39,6 +39,10 @@ Optional feature parameters:
If no feature parameters are present, during the periods of
unreliability, all I/O returns errors.
error_reads:
All read I/O is failed with an error signalled.
Write I/O is handled correctly.
drop_writes:
All write I/O is silently ignored.
Read I/O is handled correctly.
......
......@@ -18,10 +18,15 @@
#define MIN_CELLS 1024
struct dm_bio_prison {
struct prison_region {
spinlock_t lock;
struct rb_root cells;
struct rb_root cell;
} ____cacheline_aligned_in_smp;
struct dm_bio_prison {
mempool_t cell_pool;
unsigned int num_locks;
struct prison_region regions[];
};
static struct kmem_cache *_cell_cache;
......@@ -34,13 +39,20 @@ static struct kmem_cache *_cell_cache;
*/
struct dm_bio_prison *dm_bio_prison_create(void)
{
struct dm_bio_prison *prison = kzalloc(sizeof(*prison), GFP_KERNEL);
int ret;
unsigned int i, num_locks;
struct dm_bio_prison *prison;
num_locks = dm_num_hash_locks();
prison = kzalloc(struct_size(prison, regions, num_locks), GFP_KERNEL);
if (!prison)
return NULL;
prison->num_locks = num_locks;
spin_lock_init(&prison->lock);
for (i = 0; i < prison->num_locks; i++) {
spin_lock_init(&prison->regions[i].lock);
prison->regions[i].cell = RB_ROOT;
}
ret = mempool_init_slab_pool(&prison->cell_pool, MIN_CELLS, _cell_cache);
if (ret) {
......@@ -48,8 +60,6 @@ struct dm_bio_prison *dm_bio_prison_create(void)
return NULL;
}
prison->cells = RB_ROOT;
return prison;
}
EXPORT_SYMBOL_GPL(dm_bio_prison_create);
......@@ -107,14 +117,32 @@ static int cmp_keys(struct dm_cell_key *lhs,
return 0;
}
static int __bio_detain(struct dm_bio_prison *prison,
static inline unsigned int lock_nr(struct dm_cell_key *key, unsigned int num_locks)
{
return dm_hash_locks_index((key->block_begin >> BIO_PRISON_MAX_RANGE_SHIFT),
num_locks);
}
bool dm_cell_key_has_valid_range(struct dm_cell_key *key)
{
if (WARN_ON_ONCE(key->block_end - key->block_begin > BIO_PRISON_MAX_RANGE))
return false;
if (WARN_ON_ONCE((key->block_begin >> BIO_PRISON_MAX_RANGE_SHIFT) !=
(key->block_end - 1) >> BIO_PRISON_MAX_RANGE_SHIFT))
return false;
return true;
}
EXPORT_SYMBOL(dm_cell_key_has_valid_range);
static int __bio_detain(struct rb_root *root,
struct dm_cell_key *key,
struct bio *inmate,
struct dm_bio_prison_cell *cell_prealloc,
struct dm_bio_prison_cell **cell_result)
{
int r;
struct rb_node **new = &prison->cells.rb_node, *parent = NULL;
struct rb_node **new = &root->rb_node, *parent = NULL;
while (*new) {
struct dm_bio_prison_cell *cell =
......@@ -139,7 +167,7 @@ static int __bio_detain(struct dm_bio_prison *prison,
*cell_result = cell_prealloc;
rb_link_node(&cell_prealloc->node, parent, new);
rb_insert_color(&cell_prealloc->node, &prison->cells);
rb_insert_color(&cell_prealloc->node, root);
return 0;
}
......@@ -151,10 +179,11 @@ static int bio_detain(struct dm_bio_prison *prison,
struct dm_bio_prison_cell **cell_result)
{
int r;
unsigned l = lock_nr(key, prison->num_locks);
spin_lock_irq(&prison->lock);
r = __bio_detain(prison, key, inmate, cell_prealloc, cell_result);
spin_unlock_irq(&prison->lock);
spin_lock_irq(&prison->regions[l].lock);
r = __bio_detain(&prison->regions[l].cell, key, inmate, cell_prealloc, cell_result);
spin_unlock_irq(&prison->regions[l].lock);
return r;
}
......@@ -181,11 +210,11 @@ EXPORT_SYMBOL_GPL(dm_get_cell);
/*
* @inmates must have been initialised prior to this call
*/
static void __cell_release(struct dm_bio_prison *prison,
static void __cell_release(struct rb_root *root,
struct dm_bio_prison_cell *cell,
struct bio_list *inmates)
{
rb_erase(&cell->node, &prison->cells);
rb_erase(&cell->node, root);
if (inmates) {
if (cell->holder)
......@@ -198,20 +227,22 @@ void dm_cell_release(struct dm_bio_prison *prison,
struct dm_bio_prison_cell *cell,
struct bio_list *bios)
{
spin_lock_irq(&prison->lock);
__cell_release(prison, cell, bios);
spin_unlock_irq(&prison->lock);
unsigned l = lock_nr(&cell->key, prison->num_locks);
spin_lock_irq(&prison->regions[l].lock);
__cell_release(&prison->regions[l].cell, cell, bios);
spin_unlock_irq(&prison->regions[l].lock);
}
EXPORT_SYMBOL_GPL(dm_cell_release);
/*
* Sometimes we don't want the holder, just the additional bios.
*/
static void __cell_release_no_holder(struct dm_bio_prison *prison,
static void __cell_release_no_holder(struct rb_root *root,
struct dm_bio_prison_cell *cell,
struct bio_list *inmates)
{
rb_erase(&cell->node, &prison->cells);
rb_erase(&cell->node, root);
bio_list_merge(inmates, &cell->bios);
}
......@@ -219,11 +250,12 @@ void dm_cell_release_no_holder(struct dm_bio_prison *prison,
struct dm_bio_prison_cell *cell,
struct bio_list *inmates)
{
unsigned l = lock_nr(&cell->key, prison->num_locks);
unsigned long flags;
spin_lock_irqsave(&prison->lock, flags);
__cell_release_no_holder(prison, cell, inmates);
spin_unlock_irqrestore(&prison->lock, flags);
spin_lock_irqsave(&prison->regions[l].lock, flags);
__cell_release_no_holder(&prison->regions[l].cell, cell, inmates);
spin_unlock_irqrestore(&prison->regions[l].lock, flags);
}
EXPORT_SYMBOL_GPL(dm_cell_release_no_holder);
......@@ -248,18 +280,19 @@ void dm_cell_visit_release(struct dm_bio_prison *prison,
void *context,
struct dm_bio_prison_cell *cell)
{
spin_lock_irq(&prison->lock);
unsigned l = lock_nr(&cell->key, prison->num_locks);
spin_lock_irq(&prison->regions[l].lock);
visit_fn(context, cell);
rb_erase(&cell->node, &prison->cells);
spin_unlock_irq(&prison->lock);
rb_erase(&cell->node, &prison->regions[l].cell);
spin_unlock_irq(&prison->regions[l].lock);
}
EXPORT_SYMBOL_GPL(dm_cell_visit_release);
static int __promote_or_release(struct dm_bio_prison *prison,
static int __promote_or_release(struct rb_root *root,
struct dm_bio_prison_cell *cell)
{
if (bio_list_empty(&cell->bios)) {
rb_erase(&cell->node, &prison->cells);
rb_erase(&cell->node, root);
return 1;
}
......@@ -271,10 +304,11 @@ int dm_cell_promote_or_release(struct dm_bio_prison *prison,
struct dm_bio_prison_cell *cell)
{
int r;
unsigned l = lock_nr(&cell->key, prison->num_locks);
spin_lock_irq(&prison->lock);
r = __promote_or_release(prison, cell);
spin_unlock_irq(&prison->lock);
spin_lock_irq(&prison->regions[l].lock);
r = __promote_or_release(&prison->regions[l].cell, cell);
spin_unlock_irq(&prison->regions[l].lock);
return r;
}
......
......@@ -34,6 +34,16 @@ struct dm_cell_key {
dm_block_t block_begin, block_end;
};
/*
* The range of a key (block_end - block_begin) must not
* exceed BIO_PRISON_MAX_RANGE. Also the range must not
* cross a similarly sized boundary.
*
* Must be a power of 2.
*/
#define BIO_PRISON_MAX_RANGE 1024
#define BIO_PRISON_MAX_RANGE_SHIFT 10
/*
* Treat this as opaque, only in header so callers can manage allocation
* themselves.
......@@ -73,6 +83,11 @@ int dm_get_cell(struct dm_bio_prison *prison,
struct dm_bio_prison_cell *cell_prealloc,
struct dm_bio_prison_cell **cell_result);
/*
* Returns false if key is beyond BIO_PRISON_MAX_RANGE or spans a boundary.
*/
bool dm_cell_key_has_valid_range(struct dm_cell_key *key);
/*
* An atomic op that combines retrieving or creating a cell, and adding a
* bio to it.
......
This diff is collapsed.
......@@ -3459,7 +3459,6 @@ static int __init dm_cache_init(void)
r = dm_register_target(&cache_target);
if (r) {
DMERR("cache target registration failed: %d", r);
kmem_cache_destroy(migration_cache);
return r;
}
......
......@@ -2204,7 +2204,7 @@ static int __init dm_clone_init(void)
r = dm_register_target(&clone_target);
if (r < 0) {
DMERR("Failed to register clone target");
kmem_cache_destroy(_hydration_cache);
return r;
}
......
......@@ -3659,25 +3659,7 @@ static struct target_type crypt_target = {
.iterate_devices = crypt_iterate_devices,
.io_hints = crypt_io_hints,
};
static int __init dm_crypt_init(void)
{
int r;
r = dm_register_target(&crypt_target);
if (r < 0)
DMERR("register failed %d", r);
return r;
}
static void __exit dm_crypt_exit(void)
{
dm_unregister_target(&crypt_target);
}
module_init(dm_crypt_init);
module_exit(dm_crypt_exit);
module_dm(crypt);
MODULE_AUTHOR("Jana Saout <jana@saout.de>");
MODULE_DESCRIPTION(DM_NAME " target for transparent encryption / decryption");
......
......@@ -367,31 +367,7 @@ static struct target_type delay_target = {
.status = delay_status,
.iterate_devices = delay_iterate_devices,
};
static int __init dm_delay_init(void)
{
int r;
r = dm_register_target(&delay_target);
if (r < 0) {
DMERR("register failed %d", r);
goto bad_register;
}
return 0;
bad_register:
return r;
}
static void __exit dm_delay_exit(void)
{
dm_unregister_target(&delay_target);
}
/* Module hooks */
module_init(dm_delay_init);
module_exit(dm_delay_exit);
module_dm(delay);
MODULE_DESCRIPTION(DM_NAME " delay target");
MODULE_AUTHOR("Heinz Mauelshagen <mauelshagen@redhat.com>");
......
......@@ -570,24 +570,7 @@ static struct target_type dust_target = {
.status = dust_status,
.prepare_ioctl = dust_prepare_ioctl,
};
static int __init dm_dust_init(void)
{
int r = dm_register_target(&dust_target);
if (r < 0)
DMERR("dm_register_target failed %d", r);
return r;
}
static void __exit dm_dust_exit(void)
{
dm_unregister_target(&dust_target);
}
module_init(dm_dust_init);
module_exit(dm_dust_exit);
module_dm(dust);
MODULE_DESCRIPTION(DM_NAME " dust test target");
MODULE_AUTHOR("Bryan Gurney <dm-devel@redhat.com>");
......
......@@ -452,24 +452,7 @@ static struct target_type ebs_target = {
.prepare_ioctl = ebs_prepare_ioctl,
.iterate_devices = ebs_iterate_devices,
};
static int __init dm_ebs_init(void)
{
int r = dm_register_target(&ebs_target);
if (r < 0)
DMERR("register failed %d", r);
return r;
}
static void dm_ebs_exit(void)
{
dm_unregister_target(&ebs_target);
}
module_init(dm_ebs_init);
module_exit(dm_ebs_exit);
module_dm(ebs);
MODULE_AUTHOR("Heinz Mauelshagen <dm-devel@redhat.com>");
MODULE_DESCRIPTION(DM_NAME " emulated block size target");
......
......@@ -1753,27 +1753,7 @@ static struct target_type era_target = {
.iterate_devices = era_iterate_devices,
.io_hints = era_io_hints
};
static int __init dm_era_init(void)
{
int r;
r = dm_register_target(&era_target);
if (r) {
DMERR("era target registration failed: %d", r);
return r;
}
return 0;
}
static void __exit dm_era_exit(void)
{
dm_unregister_target(&era_target);
}
module_init(dm_era_init);
module_exit(dm_era_exit);
module_dm(era);
MODULE_DESCRIPTION(DM_NAME " era target");
MODULE_AUTHOR("Joe Thornber <ejt@redhat.com>");
......
......@@ -37,6 +37,7 @@ struct flakey_c {
};
enum feature_flag_bits {
ERROR_READS,
DROP_WRITES,
ERROR_WRITES
};
......@@ -53,7 +54,7 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
const char *arg_name;
static const struct dm_arg _args[] = {
{0, 6, "Invalid number of feature args"},
{0, 7, "Invalid number of feature args"},
{1, UINT_MAX, "Invalid corrupt bio byte"},
{0, 255, "Invalid corrupt value to write into bio byte (0-255)"},
{0, UINT_MAX, "Invalid corrupt bio flags mask"},
......@@ -76,6 +77,17 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
return -EINVAL;
}
/*
* error_reads
*/
if (!strcasecmp(arg_name, "error_reads")) {
if (test_and_set_bit(ERROR_READS, &fc->flags)) {
ti->error = "Feature error_reads duplicated";
return -EINVAL;
}
continue;
}
/*
* drop_writes
*/
......@@ -125,9 +137,9 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
* Direction r or w?
*/
arg_name = dm_shift_arg(as);
if (!strcasecmp(arg_name, "w"))
if (arg_name && !strcasecmp(arg_name, "w"))
fc->corrupt_bio_rw = WRITE;
else if (!strcasecmp(arg_name, "r"))
else if (arg_name && !strcasecmp(arg_name, "r"))
fc->corrupt_bio_rw = READ;
else {
ti->error = "Invalid corrupt bio direction (r or w)";
......@@ -171,6 +183,12 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
return -EINVAL;
}
if (!fc->corrupt_bio_byte && !test_bit(ERROR_READS, &fc->flags) &&
!test_bit(DROP_WRITES, &fc->flags) && !test_bit(ERROR_WRITES, &fc->flags)) {
set_bit(ERROR_WRITES, &fc->flags);
set_bit(ERROR_READS, &fc->flags);
}
return 0;
}
......@@ -346,8 +364,7 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
* Otherwise, flakey_end_io() will decide if the reads should be modified.
*/
if (bio_data_dir(bio) == READ) {
if (!fc->corrupt_bio_byte && !test_bit(DROP_WRITES, &fc->flags) &&
!test_bit(ERROR_WRITES, &fc->flags))
if (test_bit(ERROR_READS, &fc->flags))
return DM_MAPIO_KILL;
goto map_bio;
}
......@@ -373,11 +390,6 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
}
goto map_bio;
}
/*
* By default, error all I/O.
*/
return DM_MAPIO_KILL;
}
map_bio:
......@@ -404,8 +416,8 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio,
*/
corrupt_bio_data(bio, fc);
}
} else if (!test_bit(DROP_WRITES, &fc->flags) &&
!test_bit(ERROR_WRITES, &fc->flags)) {
}
if (test_bit(ERROR_READS, &fc->flags)) {
/*
* Error read during the down_interval if drop_writes
* and error_writes were not configured.
......@@ -422,7 +434,7 @@ static void flakey_status(struct dm_target *ti, status_type_t type,
{
unsigned int sz = 0;
struct flakey_c *fc = ti->private;
unsigned int drop_writes, error_writes;
unsigned int error_reads, drop_writes, error_writes;
switch (type) {
case STATUSTYPE_INFO:
......@@ -430,21 +442,24 @@ static void flakey_status(struct dm_target *ti, status_type_t type,
break;
case STATUSTYPE_TABLE:
DMEMIT("%s %llu %u %u ", fc->dev->name,
DMEMIT("%s %llu %u %u", fc->dev->name,
(unsigned long long)fc->start, fc->up_interval,
fc->down_interval);
error_reads = test_bit(ERROR_READS, &fc->flags);
drop_writes = test_bit(DROP_WRITES, &fc->flags);
error_writes = test_bit(ERROR_WRITES, &fc->flags);
DMEMIT("%u ", drop_writes + error_writes + (fc->corrupt_bio_byte > 0) * 5);
DMEMIT(" %u", error_reads + drop_writes + error_writes + (fc->corrupt_bio_byte > 0) * 5);
if (error_reads)
DMEMIT(" error_reads");
if (drop_writes)
DMEMIT("drop_writes ");
DMEMIT(" drop_writes");
else if (error_writes)
DMEMIT("error_writes ");
DMEMIT(" error_writes");
if (fc->corrupt_bio_byte)
DMEMIT("corrupt_bio_byte %u %c %u %u ",
DMEMIT(" corrupt_bio_byte %u %c %u %u",
fc->corrupt_bio_byte,
(fc->corrupt_bio_rw == WRITE) ? 'w' : 'r',
fc->corrupt_bio_value, fc->corrupt_bio_flags);
......@@ -506,25 +521,7 @@ static struct target_type flakey_target = {
.prepare_ioctl = flakey_prepare_ioctl,
.iterate_devices = flakey_iterate_devices,
};
static int __init dm_flakey_init(void)
{
int r = dm_register_target(&flakey_target);
if (r < 0)
DMERR("register failed %d", r);
return r;
}
static void __exit dm_flakey_exit(void)
{
dm_unregister_target(&flakey_target);
}
/* Module hooks */
module_init(dm_flakey_init);
module_exit(dm_flakey_exit);
module_dm(flakey);
MODULE_DESCRIPTION(DM_NAME " flakey target");
MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>");
......
......@@ -3118,7 +3118,7 @@ static int dm_integrity_reboot(struct notifier_block *n, unsigned long code, voi
static void dm_integrity_postsuspend(struct dm_target *ti)
{
struct dm_integrity_c *ic = (struct dm_integrity_c *)ti->private;
struct dm_integrity_c *ic = ti->private;
int r;
WARN_ON(unregister_reboot_notifier(&ic->reboot_notifier));
......@@ -3167,7 +3167,7 @@ static void dm_integrity_postsuspend(struct dm_target *ti)
static void dm_integrity_resume(struct dm_target *ti)
{
struct dm_integrity_c *ic = (struct dm_integrity_c *)ti->private;
struct dm_integrity_c *ic = ti->private;
__u64 old_provided_data_sectors = le64_to_cpu(ic->sb->provided_data_sectors);
int r;
......@@ -3290,7 +3290,7 @@ static void dm_integrity_resume(struct dm_target *ti)
static void dm_integrity_status(struct dm_target *ti, status_type_t type,
unsigned int status_flags, char *result, unsigned int maxlen)
{
struct dm_integrity_c *ic = (struct dm_integrity_c *)ti->private;
struct dm_integrity_c *ic = ti->private;
unsigned int arg_count;
size_t sz = 0;
......@@ -4703,11 +4703,12 @@ static int __init dm_integrity_init(void)
}
r = dm_register_target(&integrity_target);
if (r < 0) {
kmem_cache_destroy(journal_io_cache);
return r;
}
if (r < 0)
DMERR("register failed %d", r);
return r;
return 0;
}
static void __exit dm_integrity_exit(void)
......
......@@ -187,7 +187,7 @@ static void list_get_page(struct dpages *dp,
struct page **p, unsigned long *len, unsigned int *offset)
{
unsigned int o = dp->context_u;
struct page_list *pl = (struct page_list *) dp->context_ptr;
struct page_list *pl = dp->context_ptr;
*p = pl->page;
*len = PAGE_SIZE - o;
......@@ -196,7 +196,7 @@ static void list_get_page(struct dpages *dp,
static void list_next_page(struct dpages *dp)
{
struct page_list *pl = (struct page_list *) dp->context_ptr;
struct page_list *pl = dp->context_ptr;
dp->context_ptr = pl->next;
dp->context_u = 0;
......
......@@ -1168,10 +1168,13 @@ static int do_resume(struct dm_ioctl *param)
/* Do we need to load a new map ? */
if (new_map) {
sector_t old_size, new_size;
int srcu_idx;
/* Suspend if it isn't already suspended */
if (param->flags & DM_SKIP_LOCKFS_FLAG)
old_map = dm_get_live_table(md, &srcu_idx);
if ((param->flags & DM_SKIP_LOCKFS_FLAG) || !old_map)
suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG;
dm_put_live_table(md, srcu_idx);
if (param->flags & DM_NOFLUSH_FLAG)
suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG;
if (!dm_suspended_md(md))
......@@ -1556,11 +1559,12 @@ static int table_clear(struct file *filp, struct dm_ioctl *param, size_t param_s
has_new_map = true;
}
param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
__dev_status(hc->md, param);
md = hc->md;
up_write(&_hash_lock);
param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
__dev_status(md, param);
if (old_map) {
dm_sync_table(md);
dm_table_destroy(old_map);
......
......@@ -519,7 +519,7 @@ static int run_complete_job(struct kcopyd_job *job)
static void complete_io(unsigned long error, void *context)
{
struct kcopyd_job *job = (struct kcopyd_job *) context;
struct kcopyd_job *job = context;
struct dm_kcopyd_client *kc = job->kc;
io_job_finish(kc->throttle);
......@@ -696,7 +696,7 @@ static void segment_complete(int read_err, unsigned long write_err,
/* FIXME: tidy this function */
sector_t progress = 0;
sector_t count = 0;
struct kcopyd_job *sub_job = (struct kcopyd_job *) context;
struct kcopyd_job *sub_job = context;
struct kcopyd_job *job = sub_job->master_job;
struct dm_kcopyd_client *kc = job->kc;
......
......@@ -72,7 +72,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
static void linear_dtr(struct dm_target *ti)
{
struct linear_c *lc = (struct linear_c *) ti->private;
struct linear_c *lc = ti->private;
dm_put_device(ti, lc->dev);
kfree(lc);
......@@ -98,7 +98,7 @@ static int linear_map(struct dm_target *ti, struct bio *bio)
static void linear_status(struct dm_target *ti, status_type_t type,
unsigned int status_flags, char *result, unsigned int maxlen)
{
struct linear_c *lc = (struct linear_c *) ti->private;
struct linear_c *lc = ti->private;
size_t sz = 0;
switch (type) {
......@@ -120,7 +120,7 @@ static void linear_status(struct dm_target *ti, status_type_t type,
static int linear_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
{
struct linear_c *lc = (struct linear_c *) ti->private;
struct linear_c *lc = ti->private;
struct dm_dev *dev = lc->dev;
*bdev = dev->bdev;
......
......@@ -429,7 +429,7 @@ static inline sector_t logdev_last_sector(struct log_writes_c *lc)
static int log_writes_kthread(void *arg)
{
struct log_writes_c *lc = (struct log_writes_c *)arg;
struct log_writes_c *lc = arg;
sector_t sector = 0;
while (!kthread_should_stop()) {
......@@ -937,24 +937,7 @@ static struct target_type log_writes_target = {
.dax_zero_page_range = log_writes_dax_zero_page_range,
.dax_recovery_write = log_writes_dax_recovery_write,
};
static int __init dm_log_writes_init(void)
{
int r = dm_register_target(&log_writes_target);
if (r < 0)
DMERR("register failed %d", r);
return r;
}
static void __exit dm_log_writes_exit(void)
{
dm_unregister_target(&log_writes_target);
}
module_init(dm_log_writes_init);
module_exit(dm_log_writes_exit);
module_dm(log_writes);
MODULE_DESCRIPTION(DM_NAME " log writes target");
MODULE_AUTHOR("Josef Bacik <jbacik@fb.com>");
......
......@@ -530,7 +530,7 @@ static void destroy_log_context(struct log_c *lc)
static void core_dtr(struct dm_dirty_log *log)
{
struct log_c *lc = (struct log_c *) log->context;
struct log_c *lc = log->context;
vfree(lc->clean_bits);
destroy_log_context(lc);
......@@ -569,7 +569,7 @@ static int disk_ctr(struct dm_dirty_log *log, struct dm_target *ti,
static void disk_dtr(struct dm_dirty_log *log)
{
struct log_c *lc = (struct log_c *) log->context;
struct log_c *lc = log->context;
dm_put_device(lc->ti, lc->log_dev);
vfree(lc->disk_header);
......@@ -590,7 +590,7 @@ static int disk_resume(struct dm_dirty_log *log)
{
int r;
unsigned int i;
struct log_c *lc = (struct log_c *) log->context;
struct log_c *lc = log->context;
size_t size = lc->bitset_uint32_count * sizeof(uint32_t);
/* read the disk header */
......@@ -652,14 +652,14 @@ static int disk_resume(struct dm_dirty_log *log)
static uint32_t core_get_region_size(struct dm_dirty_log *log)
{
struct log_c *lc = (struct log_c *) log->context;
struct log_c *lc = log->context;
return lc->region_size;
}
static int core_resume(struct dm_dirty_log *log)
{
struct log_c *lc = (struct log_c *) log->context;
struct log_c *lc = log->context;
lc->sync_search = 0;
return 0;
......@@ -667,14 +667,14 @@ static int core_resume(struct dm_dirty_log *log)
static int core_is_clean(struct dm_dirty_log *log, region_t region)
{
struct log_c *lc = (struct log_c *) log->context;
struct log_c *lc = log->context;
return log_test_bit(lc->clean_bits, region);
}
static int core_in_sync(struct dm_dirty_log *log, region_t region, int block)
{
struct log_c *lc = (struct log_c *) log->context;
struct log_c *lc = log->context;
return log_test_bit(lc->sync_bits, region);
}
......@@ -727,14 +727,14 @@ static int disk_flush(struct dm_dirty_log *log)
static void core_mark_region(struct dm_dirty_log *log, region_t region)
{
struct log_c *lc = (struct log_c *) log->context;
struct log_c *lc = log->context;
log_clear_bit(lc, lc->clean_bits, region);
}
static void core_clear_region(struct dm_dirty_log *log, region_t region)
{
struct log_c *lc = (struct log_c *) log->context;
struct log_c *lc = log->context;
if (likely(!lc->flush_failed))
log_set_bit(lc, lc->clean_bits, region);
......@@ -742,7 +742,7 @@ static void core_clear_region(struct dm_dirty_log *log, region_t region)
static int core_get_resync_work(struct dm_dirty_log *log, region_t *region)
{
struct log_c *lc = (struct log_c *) log->context;
struct log_c *lc = log->context;
if (lc->sync_search >= lc->region_count)
return 0;
......@@ -765,7 +765,7 @@ static int core_get_resync_work(struct dm_dirty_log *log, region_t *region)
static void core_set_region_sync(struct dm_dirty_log *log, region_t region,
int in_sync)
{
struct log_c *lc = (struct log_c *) log->context;
struct log_c *lc = log->context;
log_clear_bit(lc, lc->recovering_bits, region);
if (in_sync) {
......@@ -779,7 +779,7 @@ static void core_set_region_sync(struct dm_dirty_log *log, region_t region,
static region_t core_get_sync_count(struct dm_dirty_log *log)
{
struct log_c *lc = (struct log_c *) log->context;
struct log_c *lc = log->context;
return lc->sync_count;
}
......
......@@ -2235,11 +2235,8 @@ static int __init dm_multipath_init(void)
}
r = dm_register_target(&multipath_target);
if (r < 0) {
DMERR("request-based register failed %d", r);
r = -EINVAL;
if (r < 0)
goto bad_register_target;
}
return 0;
......
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