162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2003 Sistina Software Limited.
462306a36Sopenharmony_ci * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * This file is released under the GPL.
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/device-mapper.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include "dm-rq.h"
1262306a36Sopenharmony_ci#include "dm-bio-record.h"
1362306a36Sopenharmony_ci#include "dm-path-selector.h"
1462306a36Sopenharmony_ci#include "dm-uevent.h"
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include <linux/blkdev.h>
1762306a36Sopenharmony_ci#include <linux/ctype.h>
1862306a36Sopenharmony_ci#include <linux/init.h>
1962306a36Sopenharmony_ci#include <linux/mempool.h>
2062306a36Sopenharmony_ci#include <linux/module.h>
2162306a36Sopenharmony_ci#include <linux/pagemap.h>
2262306a36Sopenharmony_ci#include <linux/slab.h>
2362306a36Sopenharmony_ci#include <linux/time.h>
2462306a36Sopenharmony_ci#include <linux/timer.h>
2562306a36Sopenharmony_ci#include <linux/workqueue.h>
2662306a36Sopenharmony_ci#include <linux/delay.h>
2762306a36Sopenharmony_ci#include <scsi/scsi_dh.h>
2862306a36Sopenharmony_ci#include <linux/atomic.h>
2962306a36Sopenharmony_ci#include <linux/blk-mq.h>
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_cistatic struct workqueue_struct *dm_mpath_wq;
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#define DM_MSG_PREFIX "multipath"
3462306a36Sopenharmony_ci#define DM_PG_INIT_DELAY_MSECS 2000
3562306a36Sopenharmony_ci#define DM_PG_INIT_DELAY_DEFAULT ((unsigned int) -1)
3662306a36Sopenharmony_ci#define QUEUE_IF_NO_PATH_TIMEOUT_DEFAULT 0
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_cistatic unsigned long queue_if_no_path_timeout_secs = QUEUE_IF_NO_PATH_TIMEOUT_DEFAULT;
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci/* Path properties */
4162306a36Sopenharmony_cistruct pgpath {
4262306a36Sopenharmony_ci	struct list_head list;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	struct priority_group *pg;	/* Owning PG */
4562306a36Sopenharmony_ci	unsigned int fail_count;		/* Cumulative failure count */
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	struct dm_path path;
4862306a36Sopenharmony_ci	struct delayed_work activate_path;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	bool is_active:1;		/* Path status */
5162306a36Sopenharmony_ci};
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci#define path_to_pgpath(__pgp) container_of((__pgp), struct pgpath, path)
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci/*
5662306a36Sopenharmony_ci * Paths are grouped into Priority Groups and numbered from 1 upwards.
5762306a36Sopenharmony_ci * Each has a path selector which controls which path gets used.
5862306a36Sopenharmony_ci */
5962306a36Sopenharmony_cistruct priority_group {
6062306a36Sopenharmony_ci	struct list_head list;
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	struct multipath *m;		/* Owning multipath instance */
6362306a36Sopenharmony_ci	struct path_selector ps;
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	unsigned int pg_num;		/* Reference number */
6662306a36Sopenharmony_ci	unsigned int nr_pgpaths;		/* Number of paths in PG */
6762306a36Sopenharmony_ci	struct list_head pgpaths;
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	bool bypassed:1;		/* Temporarily bypass this PG? */
7062306a36Sopenharmony_ci};
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/* Multipath context */
7362306a36Sopenharmony_cistruct multipath {
7462306a36Sopenharmony_ci	unsigned long flags;		/* Multipath state flags */
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci	spinlock_t lock;
7762306a36Sopenharmony_ci	enum dm_queue_mode queue_mode;
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	struct pgpath *current_pgpath;
8062306a36Sopenharmony_ci	struct priority_group *current_pg;
8162306a36Sopenharmony_ci	struct priority_group *next_pg;	/* Switch to this PG if set */
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	atomic_t nr_valid_paths;	/* Total number of usable paths */
8462306a36Sopenharmony_ci	unsigned int nr_priority_groups;
8562306a36Sopenharmony_ci	struct list_head priority_groups;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	const char *hw_handler_name;
8862306a36Sopenharmony_ci	char *hw_handler_params;
8962306a36Sopenharmony_ci	wait_queue_head_t pg_init_wait;	/* Wait for pg_init completion */
9062306a36Sopenharmony_ci	unsigned int pg_init_retries;	/* Number of times to retry pg_init */
9162306a36Sopenharmony_ci	unsigned int pg_init_delay_msecs;	/* Number of msecs before pg_init retry */
9262306a36Sopenharmony_ci	atomic_t pg_init_in_progress;	/* Only one pg_init allowed at once */
9362306a36Sopenharmony_ci	atomic_t pg_init_count;		/* Number of times pg_init called */
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci	struct mutex work_mutex;
9662306a36Sopenharmony_ci	struct work_struct trigger_event;
9762306a36Sopenharmony_ci	struct dm_target *ti;
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	struct work_struct process_queued_bios;
10062306a36Sopenharmony_ci	struct bio_list queued_bios;
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	struct timer_list nopath_timer;	/* Timeout for queue_if_no_path */
10362306a36Sopenharmony_ci};
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci/*
10662306a36Sopenharmony_ci * Context information attached to each io we process.
10762306a36Sopenharmony_ci */
10862306a36Sopenharmony_cistruct dm_mpath_io {
10962306a36Sopenharmony_ci	struct pgpath *pgpath;
11062306a36Sopenharmony_ci	size_t nr_bytes;
11162306a36Sopenharmony_ci	u64 start_time_ns;
11262306a36Sopenharmony_ci};
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_citypedef int (*action_fn) (struct pgpath *pgpath);
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_cistatic struct workqueue_struct *kmultipathd, *kmpath_handlerd;
11762306a36Sopenharmony_cistatic void trigger_event(struct work_struct *work);
11862306a36Sopenharmony_cistatic void activate_or_offline_path(struct pgpath *pgpath);
11962306a36Sopenharmony_cistatic void activate_path_work(struct work_struct *work);
12062306a36Sopenharmony_cistatic void process_queued_bios(struct work_struct *work);
12162306a36Sopenharmony_cistatic void queue_if_no_path_timeout_work(struct timer_list *t);
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci/*
12462306a36Sopenharmony_ci *-----------------------------------------------
12562306a36Sopenharmony_ci * Multipath state flags.
12662306a36Sopenharmony_ci *-----------------------------------------------
12762306a36Sopenharmony_ci */
12862306a36Sopenharmony_ci#define MPATHF_QUEUE_IO 0			/* Must we queue all I/O? */
12962306a36Sopenharmony_ci#define MPATHF_QUEUE_IF_NO_PATH 1		/* Queue I/O if last path fails? */
13062306a36Sopenharmony_ci#define MPATHF_SAVED_QUEUE_IF_NO_PATH 2		/* Saved state during suspension */
13162306a36Sopenharmony_ci#define MPATHF_RETAIN_ATTACHED_HW_HANDLER 3	/* If there's already a hw_handler present, don't change it. */
13262306a36Sopenharmony_ci#define MPATHF_PG_INIT_DISABLED 4		/* pg_init is not currently allowed */
13362306a36Sopenharmony_ci#define MPATHF_PG_INIT_REQUIRED 5		/* pg_init needs calling? */
13462306a36Sopenharmony_ci#define MPATHF_PG_INIT_DELAY_RETRY 6		/* Delay pg_init retry? */
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_cistatic bool mpath_double_check_test_bit(int MPATHF_bit, struct multipath *m)
13762306a36Sopenharmony_ci{
13862306a36Sopenharmony_ci	bool r = test_bit(MPATHF_bit, &m->flags);
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	if (r) {
14162306a36Sopenharmony_ci		unsigned long flags;
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci		spin_lock_irqsave(&m->lock, flags);
14462306a36Sopenharmony_ci		r = test_bit(MPATHF_bit, &m->flags);
14562306a36Sopenharmony_ci		spin_unlock_irqrestore(&m->lock, flags);
14662306a36Sopenharmony_ci	}
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci	return r;
14962306a36Sopenharmony_ci}
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci/*
15262306a36Sopenharmony_ci *-----------------------------------------------
15362306a36Sopenharmony_ci * Allocation routines
15462306a36Sopenharmony_ci *-----------------------------------------------
15562306a36Sopenharmony_ci */
15662306a36Sopenharmony_cistatic struct pgpath *alloc_pgpath(void)
15762306a36Sopenharmony_ci{
15862306a36Sopenharmony_ci	struct pgpath *pgpath = kzalloc(sizeof(*pgpath), GFP_KERNEL);
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci	if (!pgpath)
16162306a36Sopenharmony_ci		return NULL;
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	pgpath->is_active = true;
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci	return pgpath;
16662306a36Sopenharmony_ci}
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_cistatic void free_pgpath(struct pgpath *pgpath)
16962306a36Sopenharmony_ci{
17062306a36Sopenharmony_ci	kfree(pgpath);
17162306a36Sopenharmony_ci}
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_cistatic struct priority_group *alloc_priority_group(void)
17462306a36Sopenharmony_ci{
17562306a36Sopenharmony_ci	struct priority_group *pg;
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci	pg = kzalloc(sizeof(*pg), GFP_KERNEL);
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci	if (pg)
18062306a36Sopenharmony_ci		INIT_LIST_HEAD(&pg->pgpaths);
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	return pg;
18362306a36Sopenharmony_ci}
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_cistatic void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti)
18662306a36Sopenharmony_ci{
18762306a36Sopenharmony_ci	struct pgpath *pgpath, *tmp;
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci	list_for_each_entry_safe(pgpath, tmp, pgpaths, list) {
19062306a36Sopenharmony_ci		list_del(&pgpath->list);
19162306a36Sopenharmony_ci		dm_put_device(ti, pgpath->path.dev);
19262306a36Sopenharmony_ci		free_pgpath(pgpath);
19362306a36Sopenharmony_ci	}
19462306a36Sopenharmony_ci}
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_cistatic void free_priority_group(struct priority_group *pg,
19762306a36Sopenharmony_ci				struct dm_target *ti)
19862306a36Sopenharmony_ci{
19962306a36Sopenharmony_ci	struct path_selector *ps = &pg->ps;
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci	if (ps->type) {
20262306a36Sopenharmony_ci		ps->type->destroy(ps);
20362306a36Sopenharmony_ci		dm_put_path_selector(ps->type);
20462306a36Sopenharmony_ci	}
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	free_pgpaths(&pg->pgpaths, ti);
20762306a36Sopenharmony_ci	kfree(pg);
20862306a36Sopenharmony_ci}
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_cistatic struct multipath *alloc_multipath(struct dm_target *ti)
21162306a36Sopenharmony_ci{
21262306a36Sopenharmony_ci	struct multipath *m;
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci	m = kzalloc(sizeof(*m), GFP_KERNEL);
21562306a36Sopenharmony_ci	if (m) {
21662306a36Sopenharmony_ci		INIT_LIST_HEAD(&m->priority_groups);
21762306a36Sopenharmony_ci		spin_lock_init(&m->lock);
21862306a36Sopenharmony_ci		atomic_set(&m->nr_valid_paths, 0);
21962306a36Sopenharmony_ci		INIT_WORK(&m->trigger_event, trigger_event);
22062306a36Sopenharmony_ci		mutex_init(&m->work_mutex);
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci		m->queue_mode = DM_TYPE_NONE;
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci		m->ti = ti;
22562306a36Sopenharmony_ci		ti->private = m;
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci		timer_setup(&m->nopath_timer, queue_if_no_path_timeout_work, 0);
22862306a36Sopenharmony_ci	}
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	return m;
23162306a36Sopenharmony_ci}
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_cistatic int alloc_multipath_stage2(struct dm_target *ti, struct multipath *m)
23462306a36Sopenharmony_ci{
23562306a36Sopenharmony_ci	if (m->queue_mode == DM_TYPE_NONE) {
23662306a36Sopenharmony_ci		m->queue_mode = DM_TYPE_REQUEST_BASED;
23762306a36Sopenharmony_ci	} else if (m->queue_mode == DM_TYPE_BIO_BASED) {
23862306a36Sopenharmony_ci		INIT_WORK(&m->process_queued_bios, process_queued_bios);
23962306a36Sopenharmony_ci		/*
24062306a36Sopenharmony_ci		 * bio-based doesn't support any direct scsi_dh management;
24162306a36Sopenharmony_ci		 * it just discovers if a scsi_dh is attached.
24262306a36Sopenharmony_ci		 */
24362306a36Sopenharmony_ci		set_bit(MPATHF_RETAIN_ATTACHED_HW_HANDLER, &m->flags);
24462306a36Sopenharmony_ci	}
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci	dm_table_set_type(ti->table, m->queue_mode);
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci	/*
24962306a36Sopenharmony_ci	 * Init fields that are only used when a scsi_dh is attached
25062306a36Sopenharmony_ci	 * - must do this unconditionally (really doesn't hurt non-SCSI uses)
25162306a36Sopenharmony_ci	 */
25262306a36Sopenharmony_ci	set_bit(MPATHF_QUEUE_IO, &m->flags);
25362306a36Sopenharmony_ci	atomic_set(&m->pg_init_in_progress, 0);
25462306a36Sopenharmony_ci	atomic_set(&m->pg_init_count, 0);
25562306a36Sopenharmony_ci	m->pg_init_delay_msecs = DM_PG_INIT_DELAY_DEFAULT;
25662306a36Sopenharmony_ci	init_waitqueue_head(&m->pg_init_wait);
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci	return 0;
25962306a36Sopenharmony_ci}
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_cistatic void free_multipath(struct multipath *m)
26262306a36Sopenharmony_ci{
26362306a36Sopenharmony_ci	struct priority_group *pg, *tmp;
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	list_for_each_entry_safe(pg, tmp, &m->priority_groups, list) {
26662306a36Sopenharmony_ci		list_del(&pg->list);
26762306a36Sopenharmony_ci		free_priority_group(pg, m->ti);
26862306a36Sopenharmony_ci	}
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci	kfree(m->hw_handler_name);
27162306a36Sopenharmony_ci	kfree(m->hw_handler_params);
27262306a36Sopenharmony_ci	mutex_destroy(&m->work_mutex);
27362306a36Sopenharmony_ci	kfree(m);
27462306a36Sopenharmony_ci}
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_cistatic struct dm_mpath_io *get_mpio(union map_info *info)
27762306a36Sopenharmony_ci{
27862306a36Sopenharmony_ci	return info->ptr;
27962306a36Sopenharmony_ci}
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_cistatic size_t multipath_per_bio_data_size(void)
28262306a36Sopenharmony_ci{
28362306a36Sopenharmony_ci	return sizeof(struct dm_mpath_io) + sizeof(struct dm_bio_details);
28462306a36Sopenharmony_ci}
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_cistatic struct dm_mpath_io *get_mpio_from_bio(struct bio *bio)
28762306a36Sopenharmony_ci{
28862306a36Sopenharmony_ci	return dm_per_bio_data(bio, multipath_per_bio_data_size());
28962306a36Sopenharmony_ci}
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_cistatic struct dm_bio_details *get_bio_details_from_mpio(struct dm_mpath_io *mpio)
29262306a36Sopenharmony_ci{
29362306a36Sopenharmony_ci	/* dm_bio_details is immediately after the dm_mpath_io in bio's per-bio-data */
29462306a36Sopenharmony_ci	void *bio_details = mpio + 1;
29562306a36Sopenharmony_ci	return bio_details;
29662306a36Sopenharmony_ci}
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_cistatic void multipath_init_per_bio_data(struct bio *bio, struct dm_mpath_io **mpio_p)
29962306a36Sopenharmony_ci{
30062306a36Sopenharmony_ci	struct dm_mpath_io *mpio = get_mpio_from_bio(bio);
30162306a36Sopenharmony_ci	struct dm_bio_details *bio_details = get_bio_details_from_mpio(mpio);
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci	mpio->nr_bytes = bio->bi_iter.bi_size;
30462306a36Sopenharmony_ci	mpio->pgpath = NULL;
30562306a36Sopenharmony_ci	mpio->start_time_ns = 0;
30662306a36Sopenharmony_ci	*mpio_p = mpio;
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci	dm_bio_record(bio_details, bio);
30962306a36Sopenharmony_ci}
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci/*
31262306a36Sopenharmony_ci *-----------------------------------------------
31362306a36Sopenharmony_ci * Path selection
31462306a36Sopenharmony_ci *-----------------------------------------------
31562306a36Sopenharmony_ci */
31662306a36Sopenharmony_cistatic int __pg_init_all_paths(struct multipath *m)
31762306a36Sopenharmony_ci{
31862306a36Sopenharmony_ci	struct pgpath *pgpath;
31962306a36Sopenharmony_ci	unsigned long pg_init_delay = 0;
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	lockdep_assert_held(&m->lock);
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ci	if (atomic_read(&m->pg_init_in_progress) || test_bit(MPATHF_PG_INIT_DISABLED, &m->flags))
32462306a36Sopenharmony_ci		return 0;
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci	atomic_inc(&m->pg_init_count);
32762306a36Sopenharmony_ci	clear_bit(MPATHF_PG_INIT_REQUIRED, &m->flags);
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci	/* Check here to reset pg_init_required */
33062306a36Sopenharmony_ci	if (!m->current_pg)
33162306a36Sopenharmony_ci		return 0;
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci	if (test_bit(MPATHF_PG_INIT_DELAY_RETRY, &m->flags))
33462306a36Sopenharmony_ci		pg_init_delay = msecs_to_jiffies(m->pg_init_delay_msecs != DM_PG_INIT_DELAY_DEFAULT ?
33562306a36Sopenharmony_ci						 m->pg_init_delay_msecs : DM_PG_INIT_DELAY_MSECS);
33662306a36Sopenharmony_ci	list_for_each_entry(pgpath, &m->current_pg->pgpaths, list) {
33762306a36Sopenharmony_ci		/* Skip failed paths */
33862306a36Sopenharmony_ci		if (!pgpath->is_active)
33962306a36Sopenharmony_ci			continue;
34062306a36Sopenharmony_ci		if (queue_delayed_work(kmpath_handlerd, &pgpath->activate_path,
34162306a36Sopenharmony_ci				       pg_init_delay))
34262306a36Sopenharmony_ci			atomic_inc(&m->pg_init_in_progress);
34362306a36Sopenharmony_ci	}
34462306a36Sopenharmony_ci	return atomic_read(&m->pg_init_in_progress);
34562306a36Sopenharmony_ci}
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_cistatic int pg_init_all_paths(struct multipath *m)
34862306a36Sopenharmony_ci{
34962306a36Sopenharmony_ci	int ret;
35062306a36Sopenharmony_ci	unsigned long flags;
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci	spin_lock_irqsave(&m->lock, flags);
35362306a36Sopenharmony_ci	ret = __pg_init_all_paths(m);
35462306a36Sopenharmony_ci	spin_unlock_irqrestore(&m->lock, flags);
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci	return ret;
35762306a36Sopenharmony_ci}
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_cistatic void __switch_pg(struct multipath *m, struct priority_group *pg)
36062306a36Sopenharmony_ci{
36162306a36Sopenharmony_ci	lockdep_assert_held(&m->lock);
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	m->current_pg = pg;
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	/* Must we initialise the PG first, and queue I/O till it's ready? */
36662306a36Sopenharmony_ci	if (m->hw_handler_name) {
36762306a36Sopenharmony_ci		set_bit(MPATHF_PG_INIT_REQUIRED, &m->flags);
36862306a36Sopenharmony_ci		set_bit(MPATHF_QUEUE_IO, &m->flags);
36962306a36Sopenharmony_ci	} else {
37062306a36Sopenharmony_ci		clear_bit(MPATHF_PG_INIT_REQUIRED, &m->flags);
37162306a36Sopenharmony_ci		clear_bit(MPATHF_QUEUE_IO, &m->flags);
37262306a36Sopenharmony_ci	}
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci	atomic_set(&m->pg_init_count, 0);
37562306a36Sopenharmony_ci}
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_cistatic struct pgpath *choose_path_in_pg(struct multipath *m,
37862306a36Sopenharmony_ci					struct priority_group *pg,
37962306a36Sopenharmony_ci					size_t nr_bytes)
38062306a36Sopenharmony_ci{
38162306a36Sopenharmony_ci	unsigned long flags;
38262306a36Sopenharmony_ci	struct dm_path *path;
38362306a36Sopenharmony_ci	struct pgpath *pgpath;
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	path = pg->ps.type->select_path(&pg->ps, nr_bytes);
38662306a36Sopenharmony_ci	if (!path)
38762306a36Sopenharmony_ci		return ERR_PTR(-ENXIO);
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci	pgpath = path_to_pgpath(path);
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci	if (unlikely(READ_ONCE(m->current_pg) != pg)) {
39262306a36Sopenharmony_ci		/* Only update current_pgpath if pg changed */
39362306a36Sopenharmony_ci		spin_lock_irqsave(&m->lock, flags);
39462306a36Sopenharmony_ci		m->current_pgpath = pgpath;
39562306a36Sopenharmony_ci		__switch_pg(m, pg);
39662306a36Sopenharmony_ci		spin_unlock_irqrestore(&m->lock, flags);
39762306a36Sopenharmony_ci	}
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci	return pgpath;
40062306a36Sopenharmony_ci}
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_cistatic struct pgpath *choose_pgpath(struct multipath *m, size_t nr_bytes)
40362306a36Sopenharmony_ci{
40462306a36Sopenharmony_ci	unsigned long flags;
40562306a36Sopenharmony_ci	struct priority_group *pg;
40662306a36Sopenharmony_ci	struct pgpath *pgpath;
40762306a36Sopenharmony_ci	unsigned int bypassed = 1;
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ci	if (!atomic_read(&m->nr_valid_paths)) {
41062306a36Sopenharmony_ci		spin_lock_irqsave(&m->lock, flags);
41162306a36Sopenharmony_ci		clear_bit(MPATHF_QUEUE_IO, &m->flags);
41262306a36Sopenharmony_ci		spin_unlock_irqrestore(&m->lock, flags);
41362306a36Sopenharmony_ci		goto failed;
41462306a36Sopenharmony_ci	}
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci	/* Were we instructed to switch PG? */
41762306a36Sopenharmony_ci	if (READ_ONCE(m->next_pg)) {
41862306a36Sopenharmony_ci		spin_lock_irqsave(&m->lock, flags);
41962306a36Sopenharmony_ci		pg = m->next_pg;
42062306a36Sopenharmony_ci		if (!pg) {
42162306a36Sopenharmony_ci			spin_unlock_irqrestore(&m->lock, flags);
42262306a36Sopenharmony_ci			goto check_current_pg;
42362306a36Sopenharmony_ci		}
42462306a36Sopenharmony_ci		m->next_pg = NULL;
42562306a36Sopenharmony_ci		spin_unlock_irqrestore(&m->lock, flags);
42662306a36Sopenharmony_ci		pgpath = choose_path_in_pg(m, pg, nr_bytes);
42762306a36Sopenharmony_ci		if (!IS_ERR_OR_NULL(pgpath))
42862306a36Sopenharmony_ci			return pgpath;
42962306a36Sopenharmony_ci	}
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_ci	/* Don't change PG until it has no remaining paths */
43262306a36Sopenharmony_cicheck_current_pg:
43362306a36Sopenharmony_ci	pg = READ_ONCE(m->current_pg);
43462306a36Sopenharmony_ci	if (pg) {
43562306a36Sopenharmony_ci		pgpath = choose_path_in_pg(m, pg, nr_bytes);
43662306a36Sopenharmony_ci		if (!IS_ERR_OR_NULL(pgpath))
43762306a36Sopenharmony_ci			return pgpath;
43862306a36Sopenharmony_ci	}
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci	/*
44162306a36Sopenharmony_ci	 * Loop through priority groups until we find a valid path.
44262306a36Sopenharmony_ci	 * First time we skip PGs marked 'bypassed'.
44362306a36Sopenharmony_ci	 * Second time we only try the ones we skipped, but set
44462306a36Sopenharmony_ci	 * pg_init_delay_retry so we do not hammer controllers.
44562306a36Sopenharmony_ci	 */
44662306a36Sopenharmony_ci	do {
44762306a36Sopenharmony_ci		list_for_each_entry(pg, &m->priority_groups, list) {
44862306a36Sopenharmony_ci			if (pg->bypassed == !!bypassed)
44962306a36Sopenharmony_ci				continue;
45062306a36Sopenharmony_ci			pgpath = choose_path_in_pg(m, pg, nr_bytes);
45162306a36Sopenharmony_ci			if (!IS_ERR_OR_NULL(pgpath)) {
45262306a36Sopenharmony_ci				if (!bypassed) {
45362306a36Sopenharmony_ci					spin_lock_irqsave(&m->lock, flags);
45462306a36Sopenharmony_ci					set_bit(MPATHF_PG_INIT_DELAY_RETRY, &m->flags);
45562306a36Sopenharmony_ci					spin_unlock_irqrestore(&m->lock, flags);
45662306a36Sopenharmony_ci				}
45762306a36Sopenharmony_ci				return pgpath;
45862306a36Sopenharmony_ci			}
45962306a36Sopenharmony_ci		}
46062306a36Sopenharmony_ci	} while (bypassed--);
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_cifailed:
46362306a36Sopenharmony_ci	spin_lock_irqsave(&m->lock, flags);
46462306a36Sopenharmony_ci	m->current_pgpath = NULL;
46562306a36Sopenharmony_ci	m->current_pg = NULL;
46662306a36Sopenharmony_ci	spin_unlock_irqrestore(&m->lock, flags);
46762306a36Sopenharmony_ci
46862306a36Sopenharmony_ci	return NULL;
46962306a36Sopenharmony_ci}
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_ci/*
47262306a36Sopenharmony_ci * dm_report_EIO() is a macro instead of a function to make pr_debug_ratelimited()
47362306a36Sopenharmony_ci * report the function name and line number of the function from which
47462306a36Sopenharmony_ci * it has been invoked.
47562306a36Sopenharmony_ci */
47662306a36Sopenharmony_ci#define dm_report_EIO(m)						\
47762306a36Sopenharmony_ci	DMDEBUG_LIMIT("%s: returning EIO; QIFNP = %d; SQIFNP = %d; DNFS = %d", \
47862306a36Sopenharmony_ci		      dm_table_device_name((m)->ti->table),		\
47962306a36Sopenharmony_ci		      test_bit(MPATHF_QUEUE_IF_NO_PATH, &(m)->flags),	\
48062306a36Sopenharmony_ci		      test_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &(m)->flags), \
48162306a36Sopenharmony_ci		      dm_noflush_suspending((m)->ti))
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_ci/*
48462306a36Sopenharmony_ci * Check whether bios must be queued in the device-mapper core rather
48562306a36Sopenharmony_ci * than here in the target.
48662306a36Sopenharmony_ci */
48762306a36Sopenharmony_cistatic bool __must_push_back(struct multipath *m)
48862306a36Sopenharmony_ci{
48962306a36Sopenharmony_ci	return dm_noflush_suspending(m->ti);
49062306a36Sopenharmony_ci}
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_cistatic bool must_push_back_rq(struct multipath *m)
49362306a36Sopenharmony_ci{
49462306a36Sopenharmony_ci	unsigned long flags;
49562306a36Sopenharmony_ci	bool ret;
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ci	spin_lock_irqsave(&m->lock, flags);
49862306a36Sopenharmony_ci	ret = (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags) || __must_push_back(m));
49962306a36Sopenharmony_ci	spin_unlock_irqrestore(&m->lock, flags);
50062306a36Sopenharmony_ci
50162306a36Sopenharmony_ci	return ret;
50262306a36Sopenharmony_ci}
50362306a36Sopenharmony_ci
50462306a36Sopenharmony_ci/*
50562306a36Sopenharmony_ci * Map cloned requests (request-based multipath)
50662306a36Sopenharmony_ci */
50762306a36Sopenharmony_cistatic int multipath_clone_and_map(struct dm_target *ti, struct request *rq,
50862306a36Sopenharmony_ci				   union map_info *map_context,
50962306a36Sopenharmony_ci				   struct request **__clone)
51062306a36Sopenharmony_ci{
51162306a36Sopenharmony_ci	struct multipath *m = ti->private;
51262306a36Sopenharmony_ci	size_t nr_bytes = blk_rq_bytes(rq);
51362306a36Sopenharmony_ci	struct pgpath *pgpath;
51462306a36Sopenharmony_ci	struct block_device *bdev;
51562306a36Sopenharmony_ci	struct dm_mpath_io *mpio = get_mpio(map_context);
51662306a36Sopenharmony_ci	struct request_queue *q;
51762306a36Sopenharmony_ci	struct request *clone;
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_ci	/* Do we need to select a new pgpath? */
52062306a36Sopenharmony_ci	pgpath = READ_ONCE(m->current_pgpath);
52162306a36Sopenharmony_ci	if (!pgpath || !mpath_double_check_test_bit(MPATHF_QUEUE_IO, m))
52262306a36Sopenharmony_ci		pgpath = choose_pgpath(m, nr_bytes);
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci	if (!pgpath) {
52562306a36Sopenharmony_ci		if (must_push_back_rq(m))
52662306a36Sopenharmony_ci			return DM_MAPIO_DELAY_REQUEUE;
52762306a36Sopenharmony_ci		dm_report_EIO(m);	/* Failed */
52862306a36Sopenharmony_ci		return DM_MAPIO_KILL;
52962306a36Sopenharmony_ci	} else if (mpath_double_check_test_bit(MPATHF_QUEUE_IO, m) ||
53062306a36Sopenharmony_ci		   mpath_double_check_test_bit(MPATHF_PG_INIT_REQUIRED, m)) {
53162306a36Sopenharmony_ci		pg_init_all_paths(m);
53262306a36Sopenharmony_ci		return DM_MAPIO_DELAY_REQUEUE;
53362306a36Sopenharmony_ci	}
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci	mpio->pgpath = pgpath;
53662306a36Sopenharmony_ci	mpio->nr_bytes = nr_bytes;
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci	bdev = pgpath->path.dev->bdev;
53962306a36Sopenharmony_ci	q = bdev_get_queue(bdev);
54062306a36Sopenharmony_ci	clone = blk_mq_alloc_request(q, rq->cmd_flags | REQ_NOMERGE,
54162306a36Sopenharmony_ci			BLK_MQ_REQ_NOWAIT);
54262306a36Sopenharmony_ci	if (IS_ERR(clone)) {
54362306a36Sopenharmony_ci		/* EBUSY, ENODEV or EWOULDBLOCK: requeue */
54462306a36Sopenharmony_ci		if (blk_queue_dying(q)) {
54562306a36Sopenharmony_ci			atomic_inc(&m->pg_init_in_progress);
54662306a36Sopenharmony_ci			activate_or_offline_path(pgpath);
54762306a36Sopenharmony_ci			return DM_MAPIO_DELAY_REQUEUE;
54862306a36Sopenharmony_ci		}
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_ci		/*
55162306a36Sopenharmony_ci		 * blk-mq's SCHED_RESTART can cover this requeue, so we
55262306a36Sopenharmony_ci		 * needn't deal with it by DELAY_REQUEUE. More importantly,
55362306a36Sopenharmony_ci		 * we have to return DM_MAPIO_REQUEUE so that blk-mq can
55462306a36Sopenharmony_ci		 * get the queue busy feedback (via BLK_STS_RESOURCE),
55562306a36Sopenharmony_ci		 * otherwise I/O merging can suffer.
55662306a36Sopenharmony_ci		 */
55762306a36Sopenharmony_ci		return DM_MAPIO_REQUEUE;
55862306a36Sopenharmony_ci	}
55962306a36Sopenharmony_ci	clone->bio = clone->biotail = NULL;
56062306a36Sopenharmony_ci	clone->cmd_flags |= REQ_FAILFAST_TRANSPORT;
56162306a36Sopenharmony_ci	*__clone = clone;
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_ci	if (pgpath->pg->ps.type->start_io)
56462306a36Sopenharmony_ci		pgpath->pg->ps.type->start_io(&pgpath->pg->ps,
56562306a36Sopenharmony_ci					      &pgpath->path,
56662306a36Sopenharmony_ci					      nr_bytes);
56762306a36Sopenharmony_ci	return DM_MAPIO_REMAPPED;
56862306a36Sopenharmony_ci}
56962306a36Sopenharmony_ci
57062306a36Sopenharmony_cistatic void multipath_release_clone(struct request *clone,
57162306a36Sopenharmony_ci				    union map_info *map_context)
57262306a36Sopenharmony_ci{
57362306a36Sopenharmony_ci	if (unlikely(map_context)) {
57462306a36Sopenharmony_ci		/*
57562306a36Sopenharmony_ci		 * non-NULL map_context means caller is still map
57662306a36Sopenharmony_ci		 * method; must undo multipath_clone_and_map()
57762306a36Sopenharmony_ci		 */
57862306a36Sopenharmony_ci		struct dm_mpath_io *mpio = get_mpio(map_context);
57962306a36Sopenharmony_ci		struct pgpath *pgpath = mpio->pgpath;
58062306a36Sopenharmony_ci
58162306a36Sopenharmony_ci		if (pgpath && pgpath->pg->ps.type->end_io)
58262306a36Sopenharmony_ci			pgpath->pg->ps.type->end_io(&pgpath->pg->ps,
58362306a36Sopenharmony_ci						    &pgpath->path,
58462306a36Sopenharmony_ci						    mpio->nr_bytes,
58562306a36Sopenharmony_ci						    clone->io_start_time_ns);
58662306a36Sopenharmony_ci	}
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ci	blk_mq_free_request(clone);
58962306a36Sopenharmony_ci}
59062306a36Sopenharmony_ci
59162306a36Sopenharmony_ci/*
59262306a36Sopenharmony_ci * Map cloned bios (bio-based multipath)
59362306a36Sopenharmony_ci */
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_cistatic void __multipath_queue_bio(struct multipath *m, struct bio *bio)
59662306a36Sopenharmony_ci{
59762306a36Sopenharmony_ci	/* Queue for the daemon to resubmit */
59862306a36Sopenharmony_ci	bio_list_add(&m->queued_bios, bio);
59962306a36Sopenharmony_ci	if (!test_bit(MPATHF_QUEUE_IO, &m->flags))
60062306a36Sopenharmony_ci		queue_work(kmultipathd, &m->process_queued_bios);
60162306a36Sopenharmony_ci}
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_cistatic void multipath_queue_bio(struct multipath *m, struct bio *bio)
60462306a36Sopenharmony_ci{
60562306a36Sopenharmony_ci	unsigned long flags;
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ci	spin_lock_irqsave(&m->lock, flags);
60862306a36Sopenharmony_ci	__multipath_queue_bio(m, bio);
60962306a36Sopenharmony_ci	spin_unlock_irqrestore(&m->lock, flags);
61062306a36Sopenharmony_ci}
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_cistatic struct pgpath *__map_bio(struct multipath *m, struct bio *bio)
61362306a36Sopenharmony_ci{
61462306a36Sopenharmony_ci	struct pgpath *pgpath;
61562306a36Sopenharmony_ci	unsigned long flags;
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci	/* Do we need to select a new pgpath? */
61862306a36Sopenharmony_ci	pgpath = READ_ONCE(m->current_pgpath);
61962306a36Sopenharmony_ci	if (!pgpath || !mpath_double_check_test_bit(MPATHF_QUEUE_IO, m))
62062306a36Sopenharmony_ci		pgpath = choose_pgpath(m, bio->bi_iter.bi_size);
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ci	if (!pgpath) {
62362306a36Sopenharmony_ci		spin_lock_irqsave(&m->lock, flags);
62462306a36Sopenharmony_ci		if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) {
62562306a36Sopenharmony_ci			__multipath_queue_bio(m, bio);
62662306a36Sopenharmony_ci			pgpath = ERR_PTR(-EAGAIN);
62762306a36Sopenharmony_ci		}
62862306a36Sopenharmony_ci		spin_unlock_irqrestore(&m->lock, flags);
62962306a36Sopenharmony_ci
63062306a36Sopenharmony_ci	} else if (mpath_double_check_test_bit(MPATHF_QUEUE_IO, m) ||
63162306a36Sopenharmony_ci		   mpath_double_check_test_bit(MPATHF_PG_INIT_REQUIRED, m)) {
63262306a36Sopenharmony_ci		multipath_queue_bio(m, bio);
63362306a36Sopenharmony_ci		pg_init_all_paths(m);
63462306a36Sopenharmony_ci		return ERR_PTR(-EAGAIN);
63562306a36Sopenharmony_ci	}
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ci	return pgpath;
63862306a36Sopenharmony_ci}
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_cistatic int __multipath_map_bio(struct multipath *m, struct bio *bio,
64162306a36Sopenharmony_ci			       struct dm_mpath_io *mpio)
64262306a36Sopenharmony_ci{
64362306a36Sopenharmony_ci	struct pgpath *pgpath = __map_bio(m, bio);
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_ci	if (IS_ERR(pgpath))
64662306a36Sopenharmony_ci		return DM_MAPIO_SUBMITTED;
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_ci	if (!pgpath) {
64962306a36Sopenharmony_ci		if (__must_push_back(m))
65062306a36Sopenharmony_ci			return DM_MAPIO_REQUEUE;
65162306a36Sopenharmony_ci		dm_report_EIO(m);
65262306a36Sopenharmony_ci		return DM_MAPIO_KILL;
65362306a36Sopenharmony_ci	}
65462306a36Sopenharmony_ci
65562306a36Sopenharmony_ci	mpio->pgpath = pgpath;
65662306a36Sopenharmony_ci
65762306a36Sopenharmony_ci	if (dm_ps_use_hr_timer(pgpath->pg->ps.type))
65862306a36Sopenharmony_ci		mpio->start_time_ns = ktime_get_ns();
65962306a36Sopenharmony_ci
66062306a36Sopenharmony_ci	bio->bi_status = 0;
66162306a36Sopenharmony_ci	bio_set_dev(bio, pgpath->path.dev->bdev);
66262306a36Sopenharmony_ci	bio->bi_opf |= REQ_FAILFAST_TRANSPORT;
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_ci	if (pgpath->pg->ps.type->start_io)
66562306a36Sopenharmony_ci		pgpath->pg->ps.type->start_io(&pgpath->pg->ps,
66662306a36Sopenharmony_ci					      &pgpath->path,
66762306a36Sopenharmony_ci					      mpio->nr_bytes);
66862306a36Sopenharmony_ci	return DM_MAPIO_REMAPPED;
66962306a36Sopenharmony_ci}
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_cistatic int multipath_map_bio(struct dm_target *ti, struct bio *bio)
67262306a36Sopenharmony_ci{
67362306a36Sopenharmony_ci	struct multipath *m = ti->private;
67462306a36Sopenharmony_ci	struct dm_mpath_io *mpio = NULL;
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_ci	multipath_init_per_bio_data(bio, &mpio);
67762306a36Sopenharmony_ci	return __multipath_map_bio(m, bio, mpio);
67862306a36Sopenharmony_ci}
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_cistatic void process_queued_io_list(struct multipath *m)
68162306a36Sopenharmony_ci{
68262306a36Sopenharmony_ci	if (m->queue_mode == DM_TYPE_REQUEST_BASED)
68362306a36Sopenharmony_ci		dm_mq_kick_requeue_list(dm_table_get_md(m->ti->table));
68462306a36Sopenharmony_ci	else if (m->queue_mode == DM_TYPE_BIO_BASED)
68562306a36Sopenharmony_ci		queue_work(kmultipathd, &m->process_queued_bios);
68662306a36Sopenharmony_ci}
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_cistatic void process_queued_bios(struct work_struct *work)
68962306a36Sopenharmony_ci{
69062306a36Sopenharmony_ci	int r;
69162306a36Sopenharmony_ci	unsigned long flags;
69262306a36Sopenharmony_ci	struct bio *bio;
69362306a36Sopenharmony_ci	struct bio_list bios;
69462306a36Sopenharmony_ci	struct blk_plug plug;
69562306a36Sopenharmony_ci	struct multipath *m =
69662306a36Sopenharmony_ci		container_of(work, struct multipath, process_queued_bios);
69762306a36Sopenharmony_ci
69862306a36Sopenharmony_ci	bio_list_init(&bios);
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_ci	spin_lock_irqsave(&m->lock, flags);
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_ci	if (bio_list_empty(&m->queued_bios)) {
70362306a36Sopenharmony_ci		spin_unlock_irqrestore(&m->lock, flags);
70462306a36Sopenharmony_ci		return;
70562306a36Sopenharmony_ci	}
70662306a36Sopenharmony_ci
70762306a36Sopenharmony_ci	bio_list_merge(&bios, &m->queued_bios);
70862306a36Sopenharmony_ci	bio_list_init(&m->queued_bios);
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_ci	spin_unlock_irqrestore(&m->lock, flags);
71162306a36Sopenharmony_ci
71262306a36Sopenharmony_ci	blk_start_plug(&plug);
71362306a36Sopenharmony_ci	while ((bio = bio_list_pop(&bios))) {
71462306a36Sopenharmony_ci		struct dm_mpath_io *mpio = get_mpio_from_bio(bio);
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci		dm_bio_restore(get_bio_details_from_mpio(mpio), bio);
71762306a36Sopenharmony_ci		r = __multipath_map_bio(m, bio, mpio);
71862306a36Sopenharmony_ci		switch (r) {
71962306a36Sopenharmony_ci		case DM_MAPIO_KILL:
72062306a36Sopenharmony_ci			bio->bi_status = BLK_STS_IOERR;
72162306a36Sopenharmony_ci			bio_endio(bio);
72262306a36Sopenharmony_ci			break;
72362306a36Sopenharmony_ci		case DM_MAPIO_REQUEUE:
72462306a36Sopenharmony_ci			bio->bi_status = BLK_STS_DM_REQUEUE;
72562306a36Sopenharmony_ci			bio_endio(bio);
72662306a36Sopenharmony_ci			break;
72762306a36Sopenharmony_ci		case DM_MAPIO_REMAPPED:
72862306a36Sopenharmony_ci			submit_bio_noacct(bio);
72962306a36Sopenharmony_ci			break;
73062306a36Sopenharmony_ci		case DM_MAPIO_SUBMITTED:
73162306a36Sopenharmony_ci			break;
73262306a36Sopenharmony_ci		default:
73362306a36Sopenharmony_ci			WARN_ONCE(true, "__multipath_map_bio() returned %d\n", r);
73462306a36Sopenharmony_ci		}
73562306a36Sopenharmony_ci	}
73662306a36Sopenharmony_ci	blk_finish_plug(&plug);
73762306a36Sopenharmony_ci}
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ci/*
74062306a36Sopenharmony_ci * If we run out of usable paths, should we queue I/O or error it?
74162306a36Sopenharmony_ci */
74262306a36Sopenharmony_cistatic int queue_if_no_path(struct multipath *m, bool f_queue_if_no_path,
74362306a36Sopenharmony_ci			    bool save_old_value, const char *caller)
74462306a36Sopenharmony_ci{
74562306a36Sopenharmony_ci	unsigned long flags;
74662306a36Sopenharmony_ci	bool queue_if_no_path_bit, saved_queue_if_no_path_bit;
74762306a36Sopenharmony_ci	const char *dm_dev_name = dm_table_device_name(m->ti->table);
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_ci	DMDEBUG("%s: %s caller=%s f_queue_if_no_path=%d save_old_value=%d",
75062306a36Sopenharmony_ci		dm_dev_name, __func__, caller, f_queue_if_no_path, save_old_value);
75162306a36Sopenharmony_ci
75262306a36Sopenharmony_ci	spin_lock_irqsave(&m->lock, flags);
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_ci	queue_if_no_path_bit = test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags);
75562306a36Sopenharmony_ci	saved_queue_if_no_path_bit = test_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags);
75662306a36Sopenharmony_ci
75762306a36Sopenharmony_ci	if (save_old_value) {
75862306a36Sopenharmony_ci		if (unlikely(!queue_if_no_path_bit && saved_queue_if_no_path_bit)) {
75962306a36Sopenharmony_ci			DMERR("%s: QIFNP disabled but saved as enabled, saving again loses state, not saving!",
76062306a36Sopenharmony_ci			      dm_dev_name);
76162306a36Sopenharmony_ci		} else
76262306a36Sopenharmony_ci			assign_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags, queue_if_no_path_bit);
76362306a36Sopenharmony_ci	} else if (!f_queue_if_no_path && saved_queue_if_no_path_bit) {
76462306a36Sopenharmony_ci		/* due to "fail_if_no_path" message, need to honor it. */
76562306a36Sopenharmony_ci		clear_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags);
76662306a36Sopenharmony_ci	}
76762306a36Sopenharmony_ci	assign_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags, f_queue_if_no_path);
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci	DMDEBUG("%s: after %s changes; QIFNP = %d; SQIFNP = %d; DNFS = %d",
77062306a36Sopenharmony_ci		dm_dev_name, __func__,
77162306a36Sopenharmony_ci		test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags),
77262306a36Sopenharmony_ci		test_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags),
77362306a36Sopenharmony_ci		dm_noflush_suspending(m->ti));
77462306a36Sopenharmony_ci
77562306a36Sopenharmony_ci	spin_unlock_irqrestore(&m->lock, flags);
77662306a36Sopenharmony_ci
77762306a36Sopenharmony_ci	if (!f_queue_if_no_path) {
77862306a36Sopenharmony_ci		dm_table_run_md_queue_async(m->ti->table);
77962306a36Sopenharmony_ci		process_queued_io_list(m);
78062306a36Sopenharmony_ci	}
78162306a36Sopenharmony_ci
78262306a36Sopenharmony_ci	return 0;
78362306a36Sopenharmony_ci}
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_ci/*
78662306a36Sopenharmony_ci * If the queue_if_no_path timeout fires, turn off queue_if_no_path and
78762306a36Sopenharmony_ci * process any queued I/O.
78862306a36Sopenharmony_ci */
78962306a36Sopenharmony_cistatic void queue_if_no_path_timeout_work(struct timer_list *t)
79062306a36Sopenharmony_ci{
79162306a36Sopenharmony_ci	struct multipath *m = from_timer(m, t, nopath_timer);
79262306a36Sopenharmony_ci
79362306a36Sopenharmony_ci	DMWARN("queue_if_no_path timeout on %s, failing queued IO",
79462306a36Sopenharmony_ci	       dm_table_device_name(m->ti->table));
79562306a36Sopenharmony_ci	queue_if_no_path(m, false, false, __func__);
79662306a36Sopenharmony_ci}
79762306a36Sopenharmony_ci
79862306a36Sopenharmony_ci/*
79962306a36Sopenharmony_ci * Enable the queue_if_no_path timeout if necessary.
80062306a36Sopenharmony_ci * Called with m->lock held.
80162306a36Sopenharmony_ci */
80262306a36Sopenharmony_cistatic void enable_nopath_timeout(struct multipath *m)
80362306a36Sopenharmony_ci{
80462306a36Sopenharmony_ci	unsigned long queue_if_no_path_timeout =
80562306a36Sopenharmony_ci		READ_ONCE(queue_if_no_path_timeout_secs) * HZ;
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_ci	lockdep_assert_held(&m->lock);
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_ci	if (queue_if_no_path_timeout > 0 &&
81062306a36Sopenharmony_ci	    atomic_read(&m->nr_valid_paths) == 0 &&
81162306a36Sopenharmony_ci	    test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) {
81262306a36Sopenharmony_ci		mod_timer(&m->nopath_timer,
81362306a36Sopenharmony_ci			  jiffies + queue_if_no_path_timeout);
81462306a36Sopenharmony_ci	}
81562306a36Sopenharmony_ci}
81662306a36Sopenharmony_ci
81762306a36Sopenharmony_cistatic void disable_nopath_timeout(struct multipath *m)
81862306a36Sopenharmony_ci{
81962306a36Sopenharmony_ci	del_timer_sync(&m->nopath_timer);
82062306a36Sopenharmony_ci}
82162306a36Sopenharmony_ci
82262306a36Sopenharmony_ci/*
82362306a36Sopenharmony_ci * An event is triggered whenever a path is taken out of use.
82462306a36Sopenharmony_ci * Includes path failure and PG bypass.
82562306a36Sopenharmony_ci */
82662306a36Sopenharmony_cistatic void trigger_event(struct work_struct *work)
82762306a36Sopenharmony_ci{
82862306a36Sopenharmony_ci	struct multipath *m =
82962306a36Sopenharmony_ci		container_of(work, struct multipath, trigger_event);
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_ci	dm_table_event(m->ti->table);
83262306a36Sopenharmony_ci}
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_ci/*
83562306a36Sopenharmony_ci *---------------------------------------------------------------
83662306a36Sopenharmony_ci * Constructor/argument parsing:
83762306a36Sopenharmony_ci * <#multipath feature args> [<arg>]*
83862306a36Sopenharmony_ci * <#hw_handler args> [hw_handler [<arg>]*]
83962306a36Sopenharmony_ci * <#priority groups>
84062306a36Sopenharmony_ci * <initial priority group>
84162306a36Sopenharmony_ci *     [<selector> <#selector args> [<arg>]*
84262306a36Sopenharmony_ci *      <#paths> <#per-path selector args>
84362306a36Sopenharmony_ci *         [<path> [<arg>]* ]+ ]+
84462306a36Sopenharmony_ci *---------------------------------------------------------------
84562306a36Sopenharmony_ci */
84662306a36Sopenharmony_cistatic int parse_path_selector(struct dm_arg_set *as, struct priority_group *pg,
84762306a36Sopenharmony_ci			       struct dm_target *ti)
84862306a36Sopenharmony_ci{
84962306a36Sopenharmony_ci	int r;
85062306a36Sopenharmony_ci	struct path_selector_type *pst;
85162306a36Sopenharmony_ci	unsigned int ps_argc;
85262306a36Sopenharmony_ci
85362306a36Sopenharmony_ci	static const struct dm_arg _args[] = {
85462306a36Sopenharmony_ci		{0, 1024, "invalid number of path selector args"},
85562306a36Sopenharmony_ci	};
85662306a36Sopenharmony_ci
85762306a36Sopenharmony_ci	pst = dm_get_path_selector(dm_shift_arg(as));
85862306a36Sopenharmony_ci	if (!pst) {
85962306a36Sopenharmony_ci		ti->error = "unknown path selector type";
86062306a36Sopenharmony_ci		return -EINVAL;
86162306a36Sopenharmony_ci	}
86262306a36Sopenharmony_ci
86362306a36Sopenharmony_ci	r = dm_read_arg_group(_args, as, &ps_argc, &ti->error);
86462306a36Sopenharmony_ci	if (r) {
86562306a36Sopenharmony_ci		dm_put_path_selector(pst);
86662306a36Sopenharmony_ci		return -EINVAL;
86762306a36Sopenharmony_ci	}
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_ci	r = pst->create(&pg->ps, ps_argc, as->argv);
87062306a36Sopenharmony_ci	if (r) {
87162306a36Sopenharmony_ci		dm_put_path_selector(pst);
87262306a36Sopenharmony_ci		ti->error = "path selector constructor failed";
87362306a36Sopenharmony_ci		return r;
87462306a36Sopenharmony_ci	}
87562306a36Sopenharmony_ci
87662306a36Sopenharmony_ci	pg->ps.type = pst;
87762306a36Sopenharmony_ci	dm_consume_args(as, ps_argc);
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_ci	return 0;
88062306a36Sopenharmony_ci}
88162306a36Sopenharmony_ci
88262306a36Sopenharmony_cistatic int setup_scsi_dh(struct block_device *bdev, struct multipath *m,
88362306a36Sopenharmony_ci			 const char **attached_handler_name, char **error)
88462306a36Sopenharmony_ci{
88562306a36Sopenharmony_ci	struct request_queue *q = bdev_get_queue(bdev);
88662306a36Sopenharmony_ci	int r;
88762306a36Sopenharmony_ci
88862306a36Sopenharmony_ci	if (mpath_double_check_test_bit(MPATHF_RETAIN_ATTACHED_HW_HANDLER, m)) {
88962306a36Sopenharmony_ciretain:
89062306a36Sopenharmony_ci		if (*attached_handler_name) {
89162306a36Sopenharmony_ci			/*
89262306a36Sopenharmony_ci			 * Clear any hw_handler_params associated with a
89362306a36Sopenharmony_ci			 * handler that isn't already attached.
89462306a36Sopenharmony_ci			 */
89562306a36Sopenharmony_ci			if (m->hw_handler_name && strcmp(*attached_handler_name, m->hw_handler_name)) {
89662306a36Sopenharmony_ci				kfree(m->hw_handler_params);
89762306a36Sopenharmony_ci				m->hw_handler_params = NULL;
89862306a36Sopenharmony_ci			}
89962306a36Sopenharmony_ci
90062306a36Sopenharmony_ci			/*
90162306a36Sopenharmony_ci			 * Reset hw_handler_name to match the attached handler
90262306a36Sopenharmony_ci			 *
90362306a36Sopenharmony_ci			 * NB. This modifies the table line to show the actual
90462306a36Sopenharmony_ci			 * handler instead of the original table passed in.
90562306a36Sopenharmony_ci			 */
90662306a36Sopenharmony_ci			kfree(m->hw_handler_name);
90762306a36Sopenharmony_ci			m->hw_handler_name = *attached_handler_name;
90862306a36Sopenharmony_ci			*attached_handler_name = NULL;
90962306a36Sopenharmony_ci		}
91062306a36Sopenharmony_ci	}
91162306a36Sopenharmony_ci
91262306a36Sopenharmony_ci	if (m->hw_handler_name) {
91362306a36Sopenharmony_ci		r = scsi_dh_attach(q, m->hw_handler_name);
91462306a36Sopenharmony_ci		if (r == -EBUSY) {
91562306a36Sopenharmony_ci			DMINFO("retaining handler on device %pg", bdev);
91662306a36Sopenharmony_ci			goto retain;
91762306a36Sopenharmony_ci		}
91862306a36Sopenharmony_ci		if (r < 0) {
91962306a36Sopenharmony_ci			*error = "error attaching hardware handler";
92062306a36Sopenharmony_ci			return r;
92162306a36Sopenharmony_ci		}
92262306a36Sopenharmony_ci
92362306a36Sopenharmony_ci		if (m->hw_handler_params) {
92462306a36Sopenharmony_ci			r = scsi_dh_set_params(q, m->hw_handler_params);
92562306a36Sopenharmony_ci			if (r < 0) {
92662306a36Sopenharmony_ci				*error = "unable to set hardware handler parameters";
92762306a36Sopenharmony_ci				return r;
92862306a36Sopenharmony_ci			}
92962306a36Sopenharmony_ci		}
93062306a36Sopenharmony_ci	}
93162306a36Sopenharmony_ci
93262306a36Sopenharmony_ci	return 0;
93362306a36Sopenharmony_ci}
93462306a36Sopenharmony_ci
93562306a36Sopenharmony_cistatic struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps,
93662306a36Sopenharmony_ci				 struct dm_target *ti)
93762306a36Sopenharmony_ci{
93862306a36Sopenharmony_ci	int r;
93962306a36Sopenharmony_ci	struct pgpath *p;
94062306a36Sopenharmony_ci	struct multipath *m = ti->private;
94162306a36Sopenharmony_ci	struct request_queue *q;
94262306a36Sopenharmony_ci	const char *attached_handler_name = NULL;
94362306a36Sopenharmony_ci
94462306a36Sopenharmony_ci	/* we need at least a path arg */
94562306a36Sopenharmony_ci	if (as->argc < 1) {
94662306a36Sopenharmony_ci		ti->error = "no device given";
94762306a36Sopenharmony_ci		return ERR_PTR(-EINVAL);
94862306a36Sopenharmony_ci	}
94962306a36Sopenharmony_ci
95062306a36Sopenharmony_ci	p = alloc_pgpath();
95162306a36Sopenharmony_ci	if (!p)
95262306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
95362306a36Sopenharmony_ci
95462306a36Sopenharmony_ci	r = dm_get_device(ti, dm_shift_arg(as), dm_table_get_mode(ti->table),
95562306a36Sopenharmony_ci			  &p->path.dev);
95662306a36Sopenharmony_ci	if (r) {
95762306a36Sopenharmony_ci		ti->error = "error getting device";
95862306a36Sopenharmony_ci		goto bad;
95962306a36Sopenharmony_ci	}
96062306a36Sopenharmony_ci
96162306a36Sopenharmony_ci	q = bdev_get_queue(p->path.dev->bdev);
96262306a36Sopenharmony_ci	attached_handler_name = scsi_dh_attached_handler_name(q, GFP_KERNEL);
96362306a36Sopenharmony_ci	if (attached_handler_name || m->hw_handler_name) {
96462306a36Sopenharmony_ci		INIT_DELAYED_WORK(&p->activate_path, activate_path_work);
96562306a36Sopenharmony_ci		r = setup_scsi_dh(p->path.dev->bdev, m, &attached_handler_name, &ti->error);
96662306a36Sopenharmony_ci		kfree(attached_handler_name);
96762306a36Sopenharmony_ci		if (r) {
96862306a36Sopenharmony_ci			dm_put_device(ti, p->path.dev);
96962306a36Sopenharmony_ci			goto bad;
97062306a36Sopenharmony_ci		}
97162306a36Sopenharmony_ci	}
97262306a36Sopenharmony_ci
97362306a36Sopenharmony_ci	r = ps->type->add_path(ps, &p->path, as->argc, as->argv, &ti->error);
97462306a36Sopenharmony_ci	if (r) {
97562306a36Sopenharmony_ci		dm_put_device(ti, p->path.dev);
97662306a36Sopenharmony_ci		goto bad;
97762306a36Sopenharmony_ci	}
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_ci	return p;
98062306a36Sopenharmony_ci bad:
98162306a36Sopenharmony_ci	free_pgpath(p);
98262306a36Sopenharmony_ci	return ERR_PTR(r);
98362306a36Sopenharmony_ci}
98462306a36Sopenharmony_ci
98562306a36Sopenharmony_cistatic struct priority_group *parse_priority_group(struct dm_arg_set *as,
98662306a36Sopenharmony_ci						   struct multipath *m)
98762306a36Sopenharmony_ci{
98862306a36Sopenharmony_ci	static const struct dm_arg _args[] = {
98962306a36Sopenharmony_ci		{1, 1024, "invalid number of paths"},
99062306a36Sopenharmony_ci		{0, 1024, "invalid number of selector args"}
99162306a36Sopenharmony_ci	};
99262306a36Sopenharmony_ci
99362306a36Sopenharmony_ci	int r;
99462306a36Sopenharmony_ci	unsigned int i, nr_selector_args, nr_args;
99562306a36Sopenharmony_ci	struct priority_group *pg;
99662306a36Sopenharmony_ci	struct dm_target *ti = m->ti;
99762306a36Sopenharmony_ci
99862306a36Sopenharmony_ci	if (as->argc < 2) {
99962306a36Sopenharmony_ci		as->argc = 0;
100062306a36Sopenharmony_ci		ti->error = "not enough priority group arguments";
100162306a36Sopenharmony_ci		return ERR_PTR(-EINVAL);
100262306a36Sopenharmony_ci	}
100362306a36Sopenharmony_ci
100462306a36Sopenharmony_ci	pg = alloc_priority_group();
100562306a36Sopenharmony_ci	if (!pg) {
100662306a36Sopenharmony_ci		ti->error = "couldn't allocate priority group";
100762306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
100862306a36Sopenharmony_ci	}
100962306a36Sopenharmony_ci	pg->m = m;
101062306a36Sopenharmony_ci
101162306a36Sopenharmony_ci	r = parse_path_selector(as, pg, ti);
101262306a36Sopenharmony_ci	if (r)
101362306a36Sopenharmony_ci		goto bad;
101462306a36Sopenharmony_ci
101562306a36Sopenharmony_ci	/*
101662306a36Sopenharmony_ci	 * read the paths
101762306a36Sopenharmony_ci	 */
101862306a36Sopenharmony_ci	r = dm_read_arg(_args, as, &pg->nr_pgpaths, &ti->error);
101962306a36Sopenharmony_ci	if (r)
102062306a36Sopenharmony_ci		goto bad;
102162306a36Sopenharmony_ci
102262306a36Sopenharmony_ci	r = dm_read_arg(_args + 1, as, &nr_selector_args, &ti->error);
102362306a36Sopenharmony_ci	if (r)
102462306a36Sopenharmony_ci		goto bad;
102562306a36Sopenharmony_ci
102662306a36Sopenharmony_ci	nr_args = 1 + nr_selector_args;
102762306a36Sopenharmony_ci	for (i = 0; i < pg->nr_pgpaths; i++) {
102862306a36Sopenharmony_ci		struct pgpath *pgpath;
102962306a36Sopenharmony_ci		struct dm_arg_set path_args;
103062306a36Sopenharmony_ci
103162306a36Sopenharmony_ci		if (as->argc < nr_args) {
103262306a36Sopenharmony_ci			ti->error = "not enough path parameters";
103362306a36Sopenharmony_ci			r = -EINVAL;
103462306a36Sopenharmony_ci			goto bad;
103562306a36Sopenharmony_ci		}
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_ci		path_args.argc = nr_args;
103862306a36Sopenharmony_ci		path_args.argv = as->argv;
103962306a36Sopenharmony_ci
104062306a36Sopenharmony_ci		pgpath = parse_path(&path_args, &pg->ps, ti);
104162306a36Sopenharmony_ci		if (IS_ERR(pgpath)) {
104262306a36Sopenharmony_ci			r = PTR_ERR(pgpath);
104362306a36Sopenharmony_ci			goto bad;
104462306a36Sopenharmony_ci		}
104562306a36Sopenharmony_ci
104662306a36Sopenharmony_ci		pgpath->pg = pg;
104762306a36Sopenharmony_ci		list_add_tail(&pgpath->list, &pg->pgpaths);
104862306a36Sopenharmony_ci		dm_consume_args(as, nr_args);
104962306a36Sopenharmony_ci	}
105062306a36Sopenharmony_ci
105162306a36Sopenharmony_ci	return pg;
105262306a36Sopenharmony_ci
105362306a36Sopenharmony_ci bad:
105462306a36Sopenharmony_ci	free_priority_group(pg, ti);
105562306a36Sopenharmony_ci	return ERR_PTR(r);
105662306a36Sopenharmony_ci}
105762306a36Sopenharmony_ci
105862306a36Sopenharmony_cistatic int parse_hw_handler(struct dm_arg_set *as, struct multipath *m)
105962306a36Sopenharmony_ci{
106062306a36Sopenharmony_ci	unsigned int hw_argc;
106162306a36Sopenharmony_ci	int ret;
106262306a36Sopenharmony_ci	struct dm_target *ti = m->ti;
106362306a36Sopenharmony_ci
106462306a36Sopenharmony_ci	static const struct dm_arg _args[] = {
106562306a36Sopenharmony_ci		{0, 1024, "invalid number of hardware handler args"},
106662306a36Sopenharmony_ci	};
106762306a36Sopenharmony_ci
106862306a36Sopenharmony_ci	if (dm_read_arg_group(_args, as, &hw_argc, &ti->error))
106962306a36Sopenharmony_ci		return -EINVAL;
107062306a36Sopenharmony_ci
107162306a36Sopenharmony_ci	if (!hw_argc)
107262306a36Sopenharmony_ci		return 0;
107362306a36Sopenharmony_ci
107462306a36Sopenharmony_ci	if (m->queue_mode == DM_TYPE_BIO_BASED) {
107562306a36Sopenharmony_ci		dm_consume_args(as, hw_argc);
107662306a36Sopenharmony_ci		DMERR("bio-based multipath doesn't allow hardware handler args");
107762306a36Sopenharmony_ci		return 0;
107862306a36Sopenharmony_ci	}
107962306a36Sopenharmony_ci
108062306a36Sopenharmony_ci	m->hw_handler_name = kstrdup(dm_shift_arg(as), GFP_KERNEL);
108162306a36Sopenharmony_ci	if (!m->hw_handler_name)
108262306a36Sopenharmony_ci		return -EINVAL;
108362306a36Sopenharmony_ci
108462306a36Sopenharmony_ci	if (hw_argc > 1) {
108562306a36Sopenharmony_ci		char *p;
108662306a36Sopenharmony_ci		int i, j, len = 4;
108762306a36Sopenharmony_ci
108862306a36Sopenharmony_ci		for (i = 0; i <= hw_argc - 2; i++)
108962306a36Sopenharmony_ci			len += strlen(as->argv[i]) + 1;
109062306a36Sopenharmony_ci		p = m->hw_handler_params = kzalloc(len, GFP_KERNEL);
109162306a36Sopenharmony_ci		if (!p) {
109262306a36Sopenharmony_ci			ti->error = "memory allocation failed";
109362306a36Sopenharmony_ci			ret = -ENOMEM;
109462306a36Sopenharmony_ci			goto fail;
109562306a36Sopenharmony_ci		}
109662306a36Sopenharmony_ci		j = sprintf(p, "%d", hw_argc - 1);
109762306a36Sopenharmony_ci		for (i = 0, p += j + 1; i <= hw_argc - 2; i++, p += j + 1)
109862306a36Sopenharmony_ci			j = sprintf(p, "%s", as->argv[i]);
109962306a36Sopenharmony_ci	}
110062306a36Sopenharmony_ci	dm_consume_args(as, hw_argc - 1);
110162306a36Sopenharmony_ci
110262306a36Sopenharmony_ci	return 0;
110362306a36Sopenharmony_cifail:
110462306a36Sopenharmony_ci	kfree(m->hw_handler_name);
110562306a36Sopenharmony_ci	m->hw_handler_name = NULL;
110662306a36Sopenharmony_ci	return ret;
110762306a36Sopenharmony_ci}
110862306a36Sopenharmony_ci
110962306a36Sopenharmony_cistatic int parse_features(struct dm_arg_set *as, struct multipath *m)
111062306a36Sopenharmony_ci{
111162306a36Sopenharmony_ci	int r;
111262306a36Sopenharmony_ci	unsigned int argc;
111362306a36Sopenharmony_ci	struct dm_target *ti = m->ti;
111462306a36Sopenharmony_ci	const char *arg_name;
111562306a36Sopenharmony_ci
111662306a36Sopenharmony_ci	static const struct dm_arg _args[] = {
111762306a36Sopenharmony_ci		{0, 8, "invalid number of feature args"},
111862306a36Sopenharmony_ci		{1, 50, "pg_init_retries must be between 1 and 50"},
111962306a36Sopenharmony_ci		{0, 60000, "pg_init_delay_msecs must be between 0 and 60000"},
112062306a36Sopenharmony_ci	};
112162306a36Sopenharmony_ci
112262306a36Sopenharmony_ci	r = dm_read_arg_group(_args, as, &argc, &ti->error);
112362306a36Sopenharmony_ci	if (r)
112462306a36Sopenharmony_ci		return -EINVAL;
112562306a36Sopenharmony_ci
112662306a36Sopenharmony_ci	if (!argc)
112762306a36Sopenharmony_ci		return 0;
112862306a36Sopenharmony_ci
112962306a36Sopenharmony_ci	do {
113062306a36Sopenharmony_ci		arg_name = dm_shift_arg(as);
113162306a36Sopenharmony_ci		argc--;
113262306a36Sopenharmony_ci
113362306a36Sopenharmony_ci		if (!strcasecmp(arg_name, "queue_if_no_path")) {
113462306a36Sopenharmony_ci			r = queue_if_no_path(m, true, false, __func__);
113562306a36Sopenharmony_ci			continue;
113662306a36Sopenharmony_ci		}
113762306a36Sopenharmony_ci
113862306a36Sopenharmony_ci		if (!strcasecmp(arg_name, "retain_attached_hw_handler")) {
113962306a36Sopenharmony_ci			set_bit(MPATHF_RETAIN_ATTACHED_HW_HANDLER, &m->flags);
114062306a36Sopenharmony_ci			continue;
114162306a36Sopenharmony_ci		}
114262306a36Sopenharmony_ci
114362306a36Sopenharmony_ci		if (!strcasecmp(arg_name, "pg_init_retries") &&
114462306a36Sopenharmony_ci		    (argc >= 1)) {
114562306a36Sopenharmony_ci			r = dm_read_arg(_args + 1, as, &m->pg_init_retries, &ti->error);
114662306a36Sopenharmony_ci			argc--;
114762306a36Sopenharmony_ci			continue;
114862306a36Sopenharmony_ci		}
114962306a36Sopenharmony_ci
115062306a36Sopenharmony_ci		if (!strcasecmp(arg_name, "pg_init_delay_msecs") &&
115162306a36Sopenharmony_ci		    (argc >= 1)) {
115262306a36Sopenharmony_ci			r = dm_read_arg(_args + 2, as, &m->pg_init_delay_msecs, &ti->error);
115362306a36Sopenharmony_ci			argc--;
115462306a36Sopenharmony_ci			continue;
115562306a36Sopenharmony_ci		}
115662306a36Sopenharmony_ci
115762306a36Sopenharmony_ci		if (!strcasecmp(arg_name, "queue_mode") &&
115862306a36Sopenharmony_ci		    (argc >= 1)) {
115962306a36Sopenharmony_ci			const char *queue_mode_name = dm_shift_arg(as);
116062306a36Sopenharmony_ci
116162306a36Sopenharmony_ci			if (!strcasecmp(queue_mode_name, "bio"))
116262306a36Sopenharmony_ci				m->queue_mode = DM_TYPE_BIO_BASED;
116362306a36Sopenharmony_ci			else if (!strcasecmp(queue_mode_name, "rq") ||
116462306a36Sopenharmony_ci				 !strcasecmp(queue_mode_name, "mq"))
116562306a36Sopenharmony_ci				m->queue_mode = DM_TYPE_REQUEST_BASED;
116662306a36Sopenharmony_ci			else {
116762306a36Sopenharmony_ci				ti->error = "Unknown 'queue_mode' requested";
116862306a36Sopenharmony_ci				r = -EINVAL;
116962306a36Sopenharmony_ci			}
117062306a36Sopenharmony_ci			argc--;
117162306a36Sopenharmony_ci			continue;
117262306a36Sopenharmony_ci		}
117362306a36Sopenharmony_ci
117462306a36Sopenharmony_ci		ti->error = "Unrecognised multipath feature request";
117562306a36Sopenharmony_ci		r = -EINVAL;
117662306a36Sopenharmony_ci	} while (argc && !r);
117762306a36Sopenharmony_ci
117862306a36Sopenharmony_ci	return r;
117962306a36Sopenharmony_ci}
118062306a36Sopenharmony_ci
118162306a36Sopenharmony_cistatic int multipath_ctr(struct dm_target *ti, unsigned int argc, char **argv)
118262306a36Sopenharmony_ci{
118362306a36Sopenharmony_ci	/* target arguments */
118462306a36Sopenharmony_ci	static const struct dm_arg _args[] = {
118562306a36Sopenharmony_ci		{0, 1024, "invalid number of priority groups"},
118662306a36Sopenharmony_ci		{0, 1024, "invalid initial priority group number"},
118762306a36Sopenharmony_ci	};
118862306a36Sopenharmony_ci
118962306a36Sopenharmony_ci	int r;
119062306a36Sopenharmony_ci	struct multipath *m;
119162306a36Sopenharmony_ci	struct dm_arg_set as;
119262306a36Sopenharmony_ci	unsigned int pg_count = 0;
119362306a36Sopenharmony_ci	unsigned int next_pg_num;
119462306a36Sopenharmony_ci	unsigned long flags;
119562306a36Sopenharmony_ci
119662306a36Sopenharmony_ci	as.argc = argc;
119762306a36Sopenharmony_ci	as.argv = argv;
119862306a36Sopenharmony_ci
119962306a36Sopenharmony_ci	m = alloc_multipath(ti);
120062306a36Sopenharmony_ci	if (!m) {
120162306a36Sopenharmony_ci		ti->error = "can't allocate multipath";
120262306a36Sopenharmony_ci		return -EINVAL;
120362306a36Sopenharmony_ci	}
120462306a36Sopenharmony_ci
120562306a36Sopenharmony_ci	r = parse_features(&as, m);
120662306a36Sopenharmony_ci	if (r)
120762306a36Sopenharmony_ci		goto bad;
120862306a36Sopenharmony_ci
120962306a36Sopenharmony_ci	r = alloc_multipath_stage2(ti, m);
121062306a36Sopenharmony_ci	if (r)
121162306a36Sopenharmony_ci		goto bad;
121262306a36Sopenharmony_ci
121362306a36Sopenharmony_ci	r = parse_hw_handler(&as, m);
121462306a36Sopenharmony_ci	if (r)
121562306a36Sopenharmony_ci		goto bad;
121662306a36Sopenharmony_ci
121762306a36Sopenharmony_ci	r = dm_read_arg(_args, &as, &m->nr_priority_groups, &ti->error);
121862306a36Sopenharmony_ci	if (r)
121962306a36Sopenharmony_ci		goto bad;
122062306a36Sopenharmony_ci
122162306a36Sopenharmony_ci	r = dm_read_arg(_args + 1, &as, &next_pg_num, &ti->error);
122262306a36Sopenharmony_ci	if (r)
122362306a36Sopenharmony_ci		goto bad;
122462306a36Sopenharmony_ci
122562306a36Sopenharmony_ci	if ((!m->nr_priority_groups && next_pg_num) ||
122662306a36Sopenharmony_ci	    (m->nr_priority_groups && !next_pg_num)) {
122762306a36Sopenharmony_ci		ti->error = "invalid initial priority group";
122862306a36Sopenharmony_ci		r = -EINVAL;
122962306a36Sopenharmony_ci		goto bad;
123062306a36Sopenharmony_ci	}
123162306a36Sopenharmony_ci
123262306a36Sopenharmony_ci	/* parse the priority groups */
123362306a36Sopenharmony_ci	while (as.argc) {
123462306a36Sopenharmony_ci		struct priority_group *pg;
123562306a36Sopenharmony_ci		unsigned int nr_valid_paths = atomic_read(&m->nr_valid_paths);
123662306a36Sopenharmony_ci
123762306a36Sopenharmony_ci		pg = parse_priority_group(&as, m);
123862306a36Sopenharmony_ci		if (IS_ERR(pg)) {
123962306a36Sopenharmony_ci			r = PTR_ERR(pg);
124062306a36Sopenharmony_ci			goto bad;
124162306a36Sopenharmony_ci		}
124262306a36Sopenharmony_ci
124362306a36Sopenharmony_ci		nr_valid_paths += pg->nr_pgpaths;
124462306a36Sopenharmony_ci		atomic_set(&m->nr_valid_paths, nr_valid_paths);
124562306a36Sopenharmony_ci
124662306a36Sopenharmony_ci		list_add_tail(&pg->list, &m->priority_groups);
124762306a36Sopenharmony_ci		pg_count++;
124862306a36Sopenharmony_ci		pg->pg_num = pg_count;
124962306a36Sopenharmony_ci		if (!--next_pg_num)
125062306a36Sopenharmony_ci			m->next_pg = pg;
125162306a36Sopenharmony_ci	}
125262306a36Sopenharmony_ci
125362306a36Sopenharmony_ci	if (pg_count != m->nr_priority_groups) {
125462306a36Sopenharmony_ci		ti->error = "priority group count mismatch";
125562306a36Sopenharmony_ci		r = -EINVAL;
125662306a36Sopenharmony_ci		goto bad;
125762306a36Sopenharmony_ci	}
125862306a36Sopenharmony_ci
125962306a36Sopenharmony_ci	spin_lock_irqsave(&m->lock, flags);
126062306a36Sopenharmony_ci	enable_nopath_timeout(m);
126162306a36Sopenharmony_ci	spin_unlock_irqrestore(&m->lock, flags);
126262306a36Sopenharmony_ci
126362306a36Sopenharmony_ci	ti->num_flush_bios = 1;
126462306a36Sopenharmony_ci	ti->num_discard_bios = 1;
126562306a36Sopenharmony_ci	ti->num_write_zeroes_bios = 1;
126662306a36Sopenharmony_ci	if (m->queue_mode == DM_TYPE_BIO_BASED)
126762306a36Sopenharmony_ci		ti->per_io_data_size = multipath_per_bio_data_size();
126862306a36Sopenharmony_ci	else
126962306a36Sopenharmony_ci		ti->per_io_data_size = sizeof(struct dm_mpath_io);
127062306a36Sopenharmony_ci
127162306a36Sopenharmony_ci	return 0;
127262306a36Sopenharmony_ci
127362306a36Sopenharmony_ci bad:
127462306a36Sopenharmony_ci	free_multipath(m);
127562306a36Sopenharmony_ci	return r;
127662306a36Sopenharmony_ci}
127762306a36Sopenharmony_ci
127862306a36Sopenharmony_cistatic void multipath_wait_for_pg_init_completion(struct multipath *m)
127962306a36Sopenharmony_ci{
128062306a36Sopenharmony_ci	DEFINE_WAIT(wait);
128162306a36Sopenharmony_ci
128262306a36Sopenharmony_ci	while (1) {
128362306a36Sopenharmony_ci		prepare_to_wait(&m->pg_init_wait, &wait, TASK_UNINTERRUPTIBLE);
128462306a36Sopenharmony_ci
128562306a36Sopenharmony_ci		if (!atomic_read(&m->pg_init_in_progress))
128662306a36Sopenharmony_ci			break;
128762306a36Sopenharmony_ci
128862306a36Sopenharmony_ci		io_schedule();
128962306a36Sopenharmony_ci	}
129062306a36Sopenharmony_ci	finish_wait(&m->pg_init_wait, &wait);
129162306a36Sopenharmony_ci}
129262306a36Sopenharmony_ci
129362306a36Sopenharmony_cistatic void flush_multipath_work(struct multipath *m)
129462306a36Sopenharmony_ci{
129562306a36Sopenharmony_ci	if (m->hw_handler_name) {
129662306a36Sopenharmony_ci		unsigned long flags;
129762306a36Sopenharmony_ci
129862306a36Sopenharmony_ci		if (!atomic_read(&m->pg_init_in_progress))
129962306a36Sopenharmony_ci			goto skip;
130062306a36Sopenharmony_ci
130162306a36Sopenharmony_ci		spin_lock_irqsave(&m->lock, flags);
130262306a36Sopenharmony_ci		if (atomic_read(&m->pg_init_in_progress) &&
130362306a36Sopenharmony_ci		    !test_and_set_bit(MPATHF_PG_INIT_DISABLED, &m->flags)) {
130462306a36Sopenharmony_ci			spin_unlock_irqrestore(&m->lock, flags);
130562306a36Sopenharmony_ci
130662306a36Sopenharmony_ci			flush_workqueue(kmpath_handlerd);
130762306a36Sopenharmony_ci			multipath_wait_for_pg_init_completion(m);
130862306a36Sopenharmony_ci
130962306a36Sopenharmony_ci			spin_lock_irqsave(&m->lock, flags);
131062306a36Sopenharmony_ci			clear_bit(MPATHF_PG_INIT_DISABLED, &m->flags);
131162306a36Sopenharmony_ci		}
131262306a36Sopenharmony_ci		spin_unlock_irqrestore(&m->lock, flags);
131362306a36Sopenharmony_ci	}
131462306a36Sopenharmony_ciskip:
131562306a36Sopenharmony_ci	if (m->queue_mode == DM_TYPE_BIO_BASED)
131662306a36Sopenharmony_ci		flush_work(&m->process_queued_bios);
131762306a36Sopenharmony_ci	flush_work(&m->trigger_event);
131862306a36Sopenharmony_ci}
131962306a36Sopenharmony_ci
132062306a36Sopenharmony_cistatic void multipath_dtr(struct dm_target *ti)
132162306a36Sopenharmony_ci{
132262306a36Sopenharmony_ci	struct multipath *m = ti->private;
132362306a36Sopenharmony_ci
132462306a36Sopenharmony_ci	disable_nopath_timeout(m);
132562306a36Sopenharmony_ci	flush_multipath_work(m);
132662306a36Sopenharmony_ci	free_multipath(m);
132762306a36Sopenharmony_ci}
132862306a36Sopenharmony_ci
132962306a36Sopenharmony_ci/*
133062306a36Sopenharmony_ci * Take a path out of use.
133162306a36Sopenharmony_ci */
133262306a36Sopenharmony_cistatic int fail_path(struct pgpath *pgpath)
133362306a36Sopenharmony_ci{
133462306a36Sopenharmony_ci	unsigned long flags;
133562306a36Sopenharmony_ci	struct multipath *m = pgpath->pg->m;
133662306a36Sopenharmony_ci
133762306a36Sopenharmony_ci	spin_lock_irqsave(&m->lock, flags);
133862306a36Sopenharmony_ci
133962306a36Sopenharmony_ci	if (!pgpath->is_active)
134062306a36Sopenharmony_ci		goto out;
134162306a36Sopenharmony_ci
134262306a36Sopenharmony_ci	DMWARN("%s: Failing path %s.",
134362306a36Sopenharmony_ci	       dm_table_device_name(m->ti->table),
134462306a36Sopenharmony_ci	       pgpath->path.dev->name);
134562306a36Sopenharmony_ci
134662306a36Sopenharmony_ci	pgpath->pg->ps.type->fail_path(&pgpath->pg->ps, &pgpath->path);
134762306a36Sopenharmony_ci	pgpath->is_active = false;
134862306a36Sopenharmony_ci	pgpath->fail_count++;
134962306a36Sopenharmony_ci
135062306a36Sopenharmony_ci	atomic_dec(&m->nr_valid_paths);
135162306a36Sopenharmony_ci
135262306a36Sopenharmony_ci	if (pgpath == m->current_pgpath)
135362306a36Sopenharmony_ci		m->current_pgpath = NULL;
135462306a36Sopenharmony_ci
135562306a36Sopenharmony_ci	dm_path_uevent(DM_UEVENT_PATH_FAILED, m->ti,
135662306a36Sopenharmony_ci		       pgpath->path.dev->name, atomic_read(&m->nr_valid_paths));
135762306a36Sopenharmony_ci
135862306a36Sopenharmony_ci	queue_work(dm_mpath_wq, &m->trigger_event);
135962306a36Sopenharmony_ci
136062306a36Sopenharmony_ci	enable_nopath_timeout(m);
136162306a36Sopenharmony_ci
136262306a36Sopenharmony_ciout:
136362306a36Sopenharmony_ci	spin_unlock_irqrestore(&m->lock, flags);
136462306a36Sopenharmony_ci
136562306a36Sopenharmony_ci	return 0;
136662306a36Sopenharmony_ci}
136762306a36Sopenharmony_ci
136862306a36Sopenharmony_ci/*
136962306a36Sopenharmony_ci * Reinstate a previously-failed path
137062306a36Sopenharmony_ci */
137162306a36Sopenharmony_cistatic int reinstate_path(struct pgpath *pgpath)
137262306a36Sopenharmony_ci{
137362306a36Sopenharmony_ci	int r = 0, run_queue = 0;
137462306a36Sopenharmony_ci	unsigned long flags;
137562306a36Sopenharmony_ci	struct multipath *m = pgpath->pg->m;
137662306a36Sopenharmony_ci	unsigned int nr_valid_paths;
137762306a36Sopenharmony_ci
137862306a36Sopenharmony_ci	spin_lock_irqsave(&m->lock, flags);
137962306a36Sopenharmony_ci
138062306a36Sopenharmony_ci	if (pgpath->is_active)
138162306a36Sopenharmony_ci		goto out;
138262306a36Sopenharmony_ci
138362306a36Sopenharmony_ci	DMWARN("%s: Reinstating path %s.",
138462306a36Sopenharmony_ci	       dm_table_device_name(m->ti->table),
138562306a36Sopenharmony_ci	       pgpath->path.dev->name);
138662306a36Sopenharmony_ci
138762306a36Sopenharmony_ci	r = pgpath->pg->ps.type->reinstate_path(&pgpath->pg->ps, &pgpath->path);
138862306a36Sopenharmony_ci	if (r)
138962306a36Sopenharmony_ci		goto out;
139062306a36Sopenharmony_ci
139162306a36Sopenharmony_ci	pgpath->is_active = true;
139262306a36Sopenharmony_ci
139362306a36Sopenharmony_ci	nr_valid_paths = atomic_inc_return(&m->nr_valid_paths);
139462306a36Sopenharmony_ci	if (nr_valid_paths == 1) {
139562306a36Sopenharmony_ci		m->current_pgpath = NULL;
139662306a36Sopenharmony_ci		run_queue = 1;
139762306a36Sopenharmony_ci	} else if (m->hw_handler_name && (m->current_pg == pgpath->pg)) {
139862306a36Sopenharmony_ci		if (queue_work(kmpath_handlerd, &pgpath->activate_path.work))
139962306a36Sopenharmony_ci			atomic_inc(&m->pg_init_in_progress);
140062306a36Sopenharmony_ci	}
140162306a36Sopenharmony_ci
140262306a36Sopenharmony_ci	dm_path_uevent(DM_UEVENT_PATH_REINSTATED, m->ti,
140362306a36Sopenharmony_ci		       pgpath->path.dev->name, nr_valid_paths);
140462306a36Sopenharmony_ci
140562306a36Sopenharmony_ci	schedule_work(&m->trigger_event);
140662306a36Sopenharmony_ci
140762306a36Sopenharmony_ciout:
140862306a36Sopenharmony_ci	spin_unlock_irqrestore(&m->lock, flags);
140962306a36Sopenharmony_ci	if (run_queue) {
141062306a36Sopenharmony_ci		dm_table_run_md_queue_async(m->ti->table);
141162306a36Sopenharmony_ci		process_queued_io_list(m);
141262306a36Sopenharmony_ci	}
141362306a36Sopenharmony_ci
141462306a36Sopenharmony_ci	if (pgpath->is_active)
141562306a36Sopenharmony_ci		disable_nopath_timeout(m);
141662306a36Sopenharmony_ci
141762306a36Sopenharmony_ci	return r;
141862306a36Sopenharmony_ci}
141962306a36Sopenharmony_ci
142062306a36Sopenharmony_ci/*
142162306a36Sopenharmony_ci * Fail or reinstate all paths that match the provided struct dm_dev.
142262306a36Sopenharmony_ci */
142362306a36Sopenharmony_cistatic int action_dev(struct multipath *m, struct dm_dev *dev,
142462306a36Sopenharmony_ci		      action_fn action)
142562306a36Sopenharmony_ci{
142662306a36Sopenharmony_ci	int r = -EINVAL;
142762306a36Sopenharmony_ci	struct pgpath *pgpath;
142862306a36Sopenharmony_ci	struct priority_group *pg;
142962306a36Sopenharmony_ci
143062306a36Sopenharmony_ci	list_for_each_entry(pg, &m->priority_groups, list) {
143162306a36Sopenharmony_ci		list_for_each_entry(pgpath, &pg->pgpaths, list) {
143262306a36Sopenharmony_ci			if (pgpath->path.dev == dev)
143362306a36Sopenharmony_ci				r = action(pgpath);
143462306a36Sopenharmony_ci		}
143562306a36Sopenharmony_ci	}
143662306a36Sopenharmony_ci
143762306a36Sopenharmony_ci	return r;
143862306a36Sopenharmony_ci}
143962306a36Sopenharmony_ci
144062306a36Sopenharmony_ci/*
144162306a36Sopenharmony_ci * Temporarily try to avoid having to use the specified PG
144262306a36Sopenharmony_ci */
144362306a36Sopenharmony_cistatic void bypass_pg(struct multipath *m, struct priority_group *pg,
144462306a36Sopenharmony_ci		      bool bypassed)
144562306a36Sopenharmony_ci{
144662306a36Sopenharmony_ci	unsigned long flags;
144762306a36Sopenharmony_ci
144862306a36Sopenharmony_ci	spin_lock_irqsave(&m->lock, flags);
144962306a36Sopenharmony_ci
145062306a36Sopenharmony_ci	pg->bypassed = bypassed;
145162306a36Sopenharmony_ci	m->current_pgpath = NULL;
145262306a36Sopenharmony_ci	m->current_pg = NULL;
145362306a36Sopenharmony_ci
145462306a36Sopenharmony_ci	spin_unlock_irqrestore(&m->lock, flags);
145562306a36Sopenharmony_ci
145662306a36Sopenharmony_ci	schedule_work(&m->trigger_event);
145762306a36Sopenharmony_ci}
145862306a36Sopenharmony_ci
145962306a36Sopenharmony_ci/*
146062306a36Sopenharmony_ci * Switch to using the specified PG from the next I/O that gets mapped
146162306a36Sopenharmony_ci */
146262306a36Sopenharmony_cistatic int switch_pg_num(struct multipath *m, const char *pgstr)
146362306a36Sopenharmony_ci{
146462306a36Sopenharmony_ci	struct priority_group *pg;
146562306a36Sopenharmony_ci	unsigned int pgnum;
146662306a36Sopenharmony_ci	unsigned long flags;
146762306a36Sopenharmony_ci	char dummy;
146862306a36Sopenharmony_ci
146962306a36Sopenharmony_ci	if (!pgstr || (sscanf(pgstr, "%u%c", &pgnum, &dummy) != 1) || !pgnum ||
147062306a36Sopenharmony_ci	    !m->nr_priority_groups || (pgnum > m->nr_priority_groups)) {
147162306a36Sopenharmony_ci		DMWARN("invalid PG number supplied to %s", __func__);
147262306a36Sopenharmony_ci		return -EINVAL;
147362306a36Sopenharmony_ci	}
147462306a36Sopenharmony_ci
147562306a36Sopenharmony_ci	spin_lock_irqsave(&m->lock, flags);
147662306a36Sopenharmony_ci	list_for_each_entry(pg, &m->priority_groups, list) {
147762306a36Sopenharmony_ci		pg->bypassed = false;
147862306a36Sopenharmony_ci		if (--pgnum)
147962306a36Sopenharmony_ci			continue;
148062306a36Sopenharmony_ci
148162306a36Sopenharmony_ci		m->current_pgpath = NULL;
148262306a36Sopenharmony_ci		m->current_pg = NULL;
148362306a36Sopenharmony_ci		m->next_pg = pg;
148462306a36Sopenharmony_ci	}
148562306a36Sopenharmony_ci	spin_unlock_irqrestore(&m->lock, flags);
148662306a36Sopenharmony_ci
148762306a36Sopenharmony_ci	schedule_work(&m->trigger_event);
148862306a36Sopenharmony_ci	return 0;
148962306a36Sopenharmony_ci}
149062306a36Sopenharmony_ci
149162306a36Sopenharmony_ci/*
149262306a36Sopenharmony_ci * Set/clear bypassed status of a PG.
149362306a36Sopenharmony_ci * PGs are numbered upwards from 1 in the order they were declared.
149462306a36Sopenharmony_ci */
149562306a36Sopenharmony_cistatic int bypass_pg_num(struct multipath *m, const char *pgstr, bool bypassed)
149662306a36Sopenharmony_ci{
149762306a36Sopenharmony_ci	struct priority_group *pg;
149862306a36Sopenharmony_ci	unsigned int pgnum;
149962306a36Sopenharmony_ci	char dummy;
150062306a36Sopenharmony_ci
150162306a36Sopenharmony_ci	if (!pgstr || (sscanf(pgstr, "%u%c", &pgnum, &dummy) != 1) || !pgnum ||
150262306a36Sopenharmony_ci	    !m->nr_priority_groups || (pgnum > m->nr_priority_groups)) {
150362306a36Sopenharmony_ci		DMWARN("invalid PG number supplied to bypass_pg");
150462306a36Sopenharmony_ci		return -EINVAL;
150562306a36Sopenharmony_ci	}
150662306a36Sopenharmony_ci
150762306a36Sopenharmony_ci	list_for_each_entry(pg, &m->priority_groups, list) {
150862306a36Sopenharmony_ci		if (!--pgnum)
150962306a36Sopenharmony_ci			break;
151062306a36Sopenharmony_ci	}
151162306a36Sopenharmony_ci
151262306a36Sopenharmony_ci	bypass_pg(m, pg, bypassed);
151362306a36Sopenharmony_ci	return 0;
151462306a36Sopenharmony_ci}
151562306a36Sopenharmony_ci
151662306a36Sopenharmony_ci/*
151762306a36Sopenharmony_ci * Should we retry pg_init immediately?
151862306a36Sopenharmony_ci */
151962306a36Sopenharmony_cistatic bool pg_init_limit_reached(struct multipath *m, struct pgpath *pgpath)
152062306a36Sopenharmony_ci{
152162306a36Sopenharmony_ci	unsigned long flags;
152262306a36Sopenharmony_ci	bool limit_reached = false;
152362306a36Sopenharmony_ci
152462306a36Sopenharmony_ci	spin_lock_irqsave(&m->lock, flags);
152562306a36Sopenharmony_ci
152662306a36Sopenharmony_ci	if (atomic_read(&m->pg_init_count) <= m->pg_init_retries &&
152762306a36Sopenharmony_ci	    !test_bit(MPATHF_PG_INIT_DISABLED, &m->flags))
152862306a36Sopenharmony_ci		set_bit(MPATHF_PG_INIT_REQUIRED, &m->flags);
152962306a36Sopenharmony_ci	else
153062306a36Sopenharmony_ci		limit_reached = true;
153162306a36Sopenharmony_ci
153262306a36Sopenharmony_ci	spin_unlock_irqrestore(&m->lock, flags);
153362306a36Sopenharmony_ci
153462306a36Sopenharmony_ci	return limit_reached;
153562306a36Sopenharmony_ci}
153662306a36Sopenharmony_ci
153762306a36Sopenharmony_cistatic void pg_init_done(void *data, int errors)
153862306a36Sopenharmony_ci{
153962306a36Sopenharmony_ci	struct pgpath *pgpath = data;
154062306a36Sopenharmony_ci	struct priority_group *pg = pgpath->pg;
154162306a36Sopenharmony_ci	struct multipath *m = pg->m;
154262306a36Sopenharmony_ci	unsigned long flags;
154362306a36Sopenharmony_ci	bool delay_retry = false;
154462306a36Sopenharmony_ci
154562306a36Sopenharmony_ci	/* device or driver problems */
154662306a36Sopenharmony_ci	switch (errors) {
154762306a36Sopenharmony_ci	case SCSI_DH_OK:
154862306a36Sopenharmony_ci		break;
154962306a36Sopenharmony_ci	case SCSI_DH_NOSYS:
155062306a36Sopenharmony_ci		if (!m->hw_handler_name) {
155162306a36Sopenharmony_ci			errors = 0;
155262306a36Sopenharmony_ci			break;
155362306a36Sopenharmony_ci		}
155462306a36Sopenharmony_ci		DMERR("Could not failover the device: Handler scsi_dh_%s "
155562306a36Sopenharmony_ci		      "Error %d.", m->hw_handler_name, errors);
155662306a36Sopenharmony_ci		/*
155762306a36Sopenharmony_ci		 * Fail path for now, so we do not ping pong
155862306a36Sopenharmony_ci		 */
155962306a36Sopenharmony_ci		fail_path(pgpath);
156062306a36Sopenharmony_ci		break;
156162306a36Sopenharmony_ci	case SCSI_DH_DEV_TEMP_BUSY:
156262306a36Sopenharmony_ci		/*
156362306a36Sopenharmony_ci		 * Probably doing something like FW upgrade on the
156462306a36Sopenharmony_ci		 * controller so try the other pg.
156562306a36Sopenharmony_ci		 */
156662306a36Sopenharmony_ci		bypass_pg(m, pg, true);
156762306a36Sopenharmony_ci		break;
156862306a36Sopenharmony_ci	case SCSI_DH_RETRY:
156962306a36Sopenharmony_ci		/* Wait before retrying. */
157062306a36Sopenharmony_ci		delay_retry = true;
157162306a36Sopenharmony_ci		fallthrough;
157262306a36Sopenharmony_ci	case SCSI_DH_IMM_RETRY:
157362306a36Sopenharmony_ci	case SCSI_DH_RES_TEMP_UNAVAIL:
157462306a36Sopenharmony_ci		if (pg_init_limit_reached(m, pgpath))
157562306a36Sopenharmony_ci			fail_path(pgpath);
157662306a36Sopenharmony_ci		errors = 0;
157762306a36Sopenharmony_ci		break;
157862306a36Sopenharmony_ci	case SCSI_DH_DEV_OFFLINED:
157962306a36Sopenharmony_ci	default:
158062306a36Sopenharmony_ci		/*
158162306a36Sopenharmony_ci		 * We probably do not want to fail the path for a device
158262306a36Sopenharmony_ci		 * error, but this is what the old dm did. In future
158362306a36Sopenharmony_ci		 * patches we can do more advanced handling.
158462306a36Sopenharmony_ci		 */
158562306a36Sopenharmony_ci		fail_path(pgpath);
158662306a36Sopenharmony_ci	}
158762306a36Sopenharmony_ci
158862306a36Sopenharmony_ci	spin_lock_irqsave(&m->lock, flags);
158962306a36Sopenharmony_ci	if (errors) {
159062306a36Sopenharmony_ci		if (pgpath == m->current_pgpath) {
159162306a36Sopenharmony_ci			DMERR("Could not failover device. Error %d.", errors);
159262306a36Sopenharmony_ci			m->current_pgpath = NULL;
159362306a36Sopenharmony_ci			m->current_pg = NULL;
159462306a36Sopenharmony_ci		}
159562306a36Sopenharmony_ci	} else if (!test_bit(MPATHF_PG_INIT_REQUIRED, &m->flags))
159662306a36Sopenharmony_ci		pg->bypassed = false;
159762306a36Sopenharmony_ci
159862306a36Sopenharmony_ci	if (atomic_dec_return(&m->pg_init_in_progress) > 0)
159962306a36Sopenharmony_ci		/* Activations of other paths are still on going */
160062306a36Sopenharmony_ci		goto out;
160162306a36Sopenharmony_ci
160262306a36Sopenharmony_ci	if (test_bit(MPATHF_PG_INIT_REQUIRED, &m->flags)) {
160362306a36Sopenharmony_ci		if (delay_retry)
160462306a36Sopenharmony_ci			set_bit(MPATHF_PG_INIT_DELAY_RETRY, &m->flags);
160562306a36Sopenharmony_ci		else
160662306a36Sopenharmony_ci			clear_bit(MPATHF_PG_INIT_DELAY_RETRY, &m->flags);
160762306a36Sopenharmony_ci
160862306a36Sopenharmony_ci		if (__pg_init_all_paths(m))
160962306a36Sopenharmony_ci			goto out;
161062306a36Sopenharmony_ci	}
161162306a36Sopenharmony_ci	clear_bit(MPATHF_QUEUE_IO, &m->flags);
161262306a36Sopenharmony_ci
161362306a36Sopenharmony_ci	process_queued_io_list(m);
161462306a36Sopenharmony_ci
161562306a36Sopenharmony_ci	/*
161662306a36Sopenharmony_ci	 * Wake up any thread waiting to suspend.
161762306a36Sopenharmony_ci	 */
161862306a36Sopenharmony_ci	wake_up(&m->pg_init_wait);
161962306a36Sopenharmony_ci
162062306a36Sopenharmony_ciout:
162162306a36Sopenharmony_ci	spin_unlock_irqrestore(&m->lock, flags);
162262306a36Sopenharmony_ci}
162362306a36Sopenharmony_ci
162462306a36Sopenharmony_cistatic void activate_or_offline_path(struct pgpath *pgpath)
162562306a36Sopenharmony_ci{
162662306a36Sopenharmony_ci	struct request_queue *q = bdev_get_queue(pgpath->path.dev->bdev);
162762306a36Sopenharmony_ci
162862306a36Sopenharmony_ci	if (pgpath->is_active && !blk_queue_dying(q))
162962306a36Sopenharmony_ci		scsi_dh_activate(q, pg_init_done, pgpath);
163062306a36Sopenharmony_ci	else
163162306a36Sopenharmony_ci		pg_init_done(pgpath, SCSI_DH_DEV_OFFLINED);
163262306a36Sopenharmony_ci}
163362306a36Sopenharmony_ci
163462306a36Sopenharmony_cistatic void activate_path_work(struct work_struct *work)
163562306a36Sopenharmony_ci{
163662306a36Sopenharmony_ci	struct pgpath *pgpath =
163762306a36Sopenharmony_ci		container_of(work, struct pgpath, activate_path.work);
163862306a36Sopenharmony_ci
163962306a36Sopenharmony_ci	activate_or_offline_path(pgpath);
164062306a36Sopenharmony_ci}
164162306a36Sopenharmony_ci
164262306a36Sopenharmony_cistatic int multipath_end_io(struct dm_target *ti, struct request *clone,
164362306a36Sopenharmony_ci			    blk_status_t error, union map_info *map_context)
164462306a36Sopenharmony_ci{
164562306a36Sopenharmony_ci	struct dm_mpath_io *mpio = get_mpio(map_context);
164662306a36Sopenharmony_ci	struct pgpath *pgpath = mpio->pgpath;
164762306a36Sopenharmony_ci	int r = DM_ENDIO_DONE;
164862306a36Sopenharmony_ci
164962306a36Sopenharmony_ci	/*
165062306a36Sopenharmony_ci	 * We don't queue any clone request inside the multipath target
165162306a36Sopenharmony_ci	 * during end I/O handling, since those clone requests don't have
165262306a36Sopenharmony_ci	 * bio clones.  If we queue them inside the multipath target,
165362306a36Sopenharmony_ci	 * we need to make bio clones, that requires memory allocation.
165462306a36Sopenharmony_ci	 * (See drivers/md/dm-rq.c:end_clone_bio() about why the clone requests
165562306a36Sopenharmony_ci	 *  don't have bio clones.)
165662306a36Sopenharmony_ci	 * Instead of queueing the clone request here, we queue the original
165762306a36Sopenharmony_ci	 * request into dm core, which will remake a clone request and
165862306a36Sopenharmony_ci	 * clone bios for it and resubmit it later.
165962306a36Sopenharmony_ci	 */
166062306a36Sopenharmony_ci	if (error && blk_path_error(error)) {
166162306a36Sopenharmony_ci		struct multipath *m = ti->private;
166262306a36Sopenharmony_ci
166362306a36Sopenharmony_ci		if (error == BLK_STS_RESOURCE)
166462306a36Sopenharmony_ci			r = DM_ENDIO_DELAY_REQUEUE;
166562306a36Sopenharmony_ci		else
166662306a36Sopenharmony_ci			r = DM_ENDIO_REQUEUE;
166762306a36Sopenharmony_ci
166862306a36Sopenharmony_ci		if (pgpath)
166962306a36Sopenharmony_ci			fail_path(pgpath);
167062306a36Sopenharmony_ci
167162306a36Sopenharmony_ci		if (!atomic_read(&m->nr_valid_paths) &&
167262306a36Sopenharmony_ci		    !must_push_back_rq(m)) {
167362306a36Sopenharmony_ci			if (error == BLK_STS_IOERR)
167462306a36Sopenharmony_ci				dm_report_EIO(m);
167562306a36Sopenharmony_ci			/* complete with the original error */
167662306a36Sopenharmony_ci			r = DM_ENDIO_DONE;
167762306a36Sopenharmony_ci		}
167862306a36Sopenharmony_ci	}
167962306a36Sopenharmony_ci
168062306a36Sopenharmony_ci	if (pgpath) {
168162306a36Sopenharmony_ci		struct path_selector *ps = &pgpath->pg->ps;
168262306a36Sopenharmony_ci
168362306a36Sopenharmony_ci		if (ps->type->end_io)
168462306a36Sopenharmony_ci			ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes,
168562306a36Sopenharmony_ci					 clone->io_start_time_ns);
168662306a36Sopenharmony_ci	}
168762306a36Sopenharmony_ci
168862306a36Sopenharmony_ci	return r;
168962306a36Sopenharmony_ci}
169062306a36Sopenharmony_ci
169162306a36Sopenharmony_cistatic int multipath_end_io_bio(struct dm_target *ti, struct bio *clone,
169262306a36Sopenharmony_ci				blk_status_t *error)
169362306a36Sopenharmony_ci{
169462306a36Sopenharmony_ci	struct multipath *m = ti->private;
169562306a36Sopenharmony_ci	struct dm_mpath_io *mpio = get_mpio_from_bio(clone);
169662306a36Sopenharmony_ci	struct pgpath *pgpath = mpio->pgpath;
169762306a36Sopenharmony_ci	unsigned long flags;
169862306a36Sopenharmony_ci	int r = DM_ENDIO_DONE;
169962306a36Sopenharmony_ci
170062306a36Sopenharmony_ci	if (!*error || !blk_path_error(*error))
170162306a36Sopenharmony_ci		goto done;
170262306a36Sopenharmony_ci
170362306a36Sopenharmony_ci	if (pgpath)
170462306a36Sopenharmony_ci		fail_path(pgpath);
170562306a36Sopenharmony_ci
170662306a36Sopenharmony_ci	if (!atomic_read(&m->nr_valid_paths)) {
170762306a36Sopenharmony_ci		spin_lock_irqsave(&m->lock, flags);
170862306a36Sopenharmony_ci		if (!test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) {
170962306a36Sopenharmony_ci			if (__must_push_back(m)) {
171062306a36Sopenharmony_ci				r = DM_ENDIO_REQUEUE;
171162306a36Sopenharmony_ci			} else {
171262306a36Sopenharmony_ci				dm_report_EIO(m);
171362306a36Sopenharmony_ci				*error = BLK_STS_IOERR;
171462306a36Sopenharmony_ci			}
171562306a36Sopenharmony_ci			spin_unlock_irqrestore(&m->lock, flags);
171662306a36Sopenharmony_ci			goto done;
171762306a36Sopenharmony_ci		}
171862306a36Sopenharmony_ci		spin_unlock_irqrestore(&m->lock, flags);
171962306a36Sopenharmony_ci	}
172062306a36Sopenharmony_ci
172162306a36Sopenharmony_ci	multipath_queue_bio(m, clone);
172262306a36Sopenharmony_ci	r = DM_ENDIO_INCOMPLETE;
172362306a36Sopenharmony_cidone:
172462306a36Sopenharmony_ci	if (pgpath) {
172562306a36Sopenharmony_ci		struct path_selector *ps = &pgpath->pg->ps;
172662306a36Sopenharmony_ci
172762306a36Sopenharmony_ci		if (ps->type->end_io)
172862306a36Sopenharmony_ci			ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes,
172962306a36Sopenharmony_ci					 (mpio->start_time_ns ?:
173062306a36Sopenharmony_ci					  dm_start_time_ns_from_clone(clone)));
173162306a36Sopenharmony_ci	}
173262306a36Sopenharmony_ci
173362306a36Sopenharmony_ci	return r;
173462306a36Sopenharmony_ci}
173562306a36Sopenharmony_ci
173662306a36Sopenharmony_ci/*
173762306a36Sopenharmony_ci * Suspend with flush can't complete until all the I/O is processed
173862306a36Sopenharmony_ci * so if the last path fails we must error any remaining I/O.
173962306a36Sopenharmony_ci * - Note that if the freeze_bdev fails while suspending, the
174062306a36Sopenharmony_ci *   queue_if_no_path state is lost - userspace should reset it.
174162306a36Sopenharmony_ci * Otherwise, during noflush suspend, queue_if_no_path will not change.
174262306a36Sopenharmony_ci */
174362306a36Sopenharmony_cistatic void multipath_presuspend(struct dm_target *ti)
174462306a36Sopenharmony_ci{
174562306a36Sopenharmony_ci	struct multipath *m = ti->private;
174662306a36Sopenharmony_ci
174762306a36Sopenharmony_ci	/* FIXME: bio-based shouldn't need to always disable queue_if_no_path */
174862306a36Sopenharmony_ci	if (m->queue_mode == DM_TYPE_BIO_BASED || !dm_noflush_suspending(m->ti))
174962306a36Sopenharmony_ci		queue_if_no_path(m, false, true, __func__);
175062306a36Sopenharmony_ci}
175162306a36Sopenharmony_ci
175262306a36Sopenharmony_cistatic void multipath_postsuspend(struct dm_target *ti)
175362306a36Sopenharmony_ci{
175462306a36Sopenharmony_ci	struct multipath *m = ti->private;
175562306a36Sopenharmony_ci
175662306a36Sopenharmony_ci	mutex_lock(&m->work_mutex);
175762306a36Sopenharmony_ci	flush_multipath_work(m);
175862306a36Sopenharmony_ci	mutex_unlock(&m->work_mutex);
175962306a36Sopenharmony_ci}
176062306a36Sopenharmony_ci
176162306a36Sopenharmony_ci/*
176262306a36Sopenharmony_ci * Restore the queue_if_no_path setting.
176362306a36Sopenharmony_ci */
176462306a36Sopenharmony_cistatic void multipath_resume(struct dm_target *ti)
176562306a36Sopenharmony_ci{
176662306a36Sopenharmony_ci	struct multipath *m = ti->private;
176762306a36Sopenharmony_ci	unsigned long flags;
176862306a36Sopenharmony_ci
176962306a36Sopenharmony_ci	spin_lock_irqsave(&m->lock, flags);
177062306a36Sopenharmony_ci	if (test_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags)) {
177162306a36Sopenharmony_ci		set_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags);
177262306a36Sopenharmony_ci		clear_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags);
177362306a36Sopenharmony_ci	}
177462306a36Sopenharmony_ci
177562306a36Sopenharmony_ci	DMDEBUG("%s: %s finished; QIFNP = %d; SQIFNP = %d",
177662306a36Sopenharmony_ci		dm_table_device_name(m->ti->table), __func__,
177762306a36Sopenharmony_ci		test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags),
177862306a36Sopenharmony_ci		test_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags));
177962306a36Sopenharmony_ci
178062306a36Sopenharmony_ci	spin_unlock_irqrestore(&m->lock, flags);
178162306a36Sopenharmony_ci}
178262306a36Sopenharmony_ci
178362306a36Sopenharmony_ci/*
178462306a36Sopenharmony_ci * Info output has the following format:
178562306a36Sopenharmony_ci * num_multipath_feature_args [multipath_feature_args]*
178662306a36Sopenharmony_ci * num_handler_status_args [handler_status_args]*
178762306a36Sopenharmony_ci * num_groups init_group_number
178862306a36Sopenharmony_ci *            [A|D|E num_ps_status_args [ps_status_args]*
178962306a36Sopenharmony_ci *             num_paths num_selector_args
179062306a36Sopenharmony_ci *             [path_dev A|F fail_count [selector_args]* ]+ ]+
179162306a36Sopenharmony_ci *
179262306a36Sopenharmony_ci * Table output has the following format (identical to the constructor string):
179362306a36Sopenharmony_ci * num_feature_args [features_args]*
179462306a36Sopenharmony_ci * num_handler_args hw_handler [hw_handler_args]*
179562306a36Sopenharmony_ci * num_groups init_group_number
179662306a36Sopenharmony_ci *     [priority selector-name num_ps_args [ps_args]*
179762306a36Sopenharmony_ci *      num_paths num_selector_args [path_dev [selector_args]* ]+ ]+
179862306a36Sopenharmony_ci */
179962306a36Sopenharmony_cistatic void multipath_status(struct dm_target *ti, status_type_t type,
180062306a36Sopenharmony_ci			     unsigned int status_flags, char *result, unsigned int maxlen)
180162306a36Sopenharmony_ci{
180262306a36Sopenharmony_ci	int sz = 0, pg_counter, pgpath_counter;
180362306a36Sopenharmony_ci	unsigned long flags;
180462306a36Sopenharmony_ci	struct multipath *m = ti->private;
180562306a36Sopenharmony_ci	struct priority_group *pg;
180662306a36Sopenharmony_ci	struct pgpath *p;
180762306a36Sopenharmony_ci	unsigned int pg_num;
180862306a36Sopenharmony_ci	char state;
180962306a36Sopenharmony_ci
181062306a36Sopenharmony_ci	spin_lock_irqsave(&m->lock, flags);
181162306a36Sopenharmony_ci
181262306a36Sopenharmony_ci	/* Features */
181362306a36Sopenharmony_ci	if (type == STATUSTYPE_INFO)
181462306a36Sopenharmony_ci		DMEMIT("2 %u %u ", test_bit(MPATHF_QUEUE_IO, &m->flags),
181562306a36Sopenharmony_ci		       atomic_read(&m->pg_init_count));
181662306a36Sopenharmony_ci	else {
181762306a36Sopenharmony_ci		DMEMIT("%u ", test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags) +
181862306a36Sopenharmony_ci			      (m->pg_init_retries > 0) * 2 +
181962306a36Sopenharmony_ci			      (m->pg_init_delay_msecs != DM_PG_INIT_DELAY_DEFAULT) * 2 +
182062306a36Sopenharmony_ci			      test_bit(MPATHF_RETAIN_ATTACHED_HW_HANDLER, &m->flags) +
182162306a36Sopenharmony_ci			      (m->queue_mode != DM_TYPE_REQUEST_BASED) * 2);
182262306a36Sopenharmony_ci
182362306a36Sopenharmony_ci		if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))
182462306a36Sopenharmony_ci			DMEMIT("queue_if_no_path ");
182562306a36Sopenharmony_ci		if (m->pg_init_retries)
182662306a36Sopenharmony_ci			DMEMIT("pg_init_retries %u ", m->pg_init_retries);
182762306a36Sopenharmony_ci		if (m->pg_init_delay_msecs != DM_PG_INIT_DELAY_DEFAULT)
182862306a36Sopenharmony_ci			DMEMIT("pg_init_delay_msecs %u ", m->pg_init_delay_msecs);
182962306a36Sopenharmony_ci		if (test_bit(MPATHF_RETAIN_ATTACHED_HW_HANDLER, &m->flags))
183062306a36Sopenharmony_ci			DMEMIT("retain_attached_hw_handler ");
183162306a36Sopenharmony_ci		if (m->queue_mode != DM_TYPE_REQUEST_BASED) {
183262306a36Sopenharmony_ci			switch (m->queue_mode) {
183362306a36Sopenharmony_ci			case DM_TYPE_BIO_BASED:
183462306a36Sopenharmony_ci				DMEMIT("queue_mode bio ");
183562306a36Sopenharmony_ci				break;
183662306a36Sopenharmony_ci			default:
183762306a36Sopenharmony_ci				WARN_ON_ONCE(true);
183862306a36Sopenharmony_ci				break;
183962306a36Sopenharmony_ci			}
184062306a36Sopenharmony_ci		}
184162306a36Sopenharmony_ci	}
184262306a36Sopenharmony_ci
184362306a36Sopenharmony_ci	if (!m->hw_handler_name || type == STATUSTYPE_INFO)
184462306a36Sopenharmony_ci		DMEMIT("0 ");
184562306a36Sopenharmony_ci	else
184662306a36Sopenharmony_ci		DMEMIT("1 %s ", m->hw_handler_name);
184762306a36Sopenharmony_ci
184862306a36Sopenharmony_ci	DMEMIT("%u ", m->nr_priority_groups);
184962306a36Sopenharmony_ci
185062306a36Sopenharmony_ci	if (m->next_pg)
185162306a36Sopenharmony_ci		pg_num = m->next_pg->pg_num;
185262306a36Sopenharmony_ci	else if (m->current_pg)
185362306a36Sopenharmony_ci		pg_num = m->current_pg->pg_num;
185462306a36Sopenharmony_ci	else
185562306a36Sopenharmony_ci		pg_num = (m->nr_priority_groups ? 1 : 0);
185662306a36Sopenharmony_ci
185762306a36Sopenharmony_ci	DMEMIT("%u ", pg_num);
185862306a36Sopenharmony_ci
185962306a36Sopenharmony_ci	switch (type) {
186062306a36Sopenharmony_ci	case STATUSTYPE_INFO:
186162306a36Sopenharmony_ci		list_for_each_entry(pg, &m->priority_groups, list) {
186262306a36Sopenharmony_ci			if (pg->bypassed)
186362306a36Sopenharmony_ci				state = 'D';	/* Disabled */
186462306a36Sopenharmony_ci			else if (pg == m->current_pg)
186562306a36Sopenharmony_ci				state = 'A';	/* Currently Active */
186662306a36Sopenharmony_ci			else
186762306a36Sopenharmony_ci				state = 'E';	/* Enabled */
186862306a36Sopenharmony_ci
186962306a36Sopenharmony_ci			DMEMIT("%c ", state);
187062306a36Sopenharmony_ci
187162306a36Sopenharmony_ci			if (pg->ps.type->status)
187262306a36Sopenharmony_ci				sz += pg->ps.type->status(&pg->ps, NULL, type,
187362306a36Sopenharmony_ci							  result + sz,
187462306a36Sopenharmony_ci							  maxlen - sz);
187562306a36Sopenharmony_ci			else
187662306a36Sopenharmony_ci				DMEMIT("0 ");
187762306a36Sopenharmony_ci
187862306a36Sopenharmony_ci			DMEMIT("%u %u ", pg->nr_pgpaths,
187962306a36Sopenharmony_ci			       pg->ps.type->info_args);
188062306a36Sopenharmony_ci
188162306a36Sopenharmony_ci			list_for_each_entry(p, &pg->pgpaths, list) {
188262306a36Sopenharmony_ci				DMEMIT("%s %s %u ", p->path.dev->name,
188362306a36Sopenharmony_ci				       p->is_active ? "A" : "F",
188462306a36Sopenharmony_ci				       p->fail_count);
188562306a36Sopenharmony_ci				if (pg->ps.type->status)
188662306a36Sopenharmony_ci					sz += pg->ps.type->status(&pg->ps,
188762306a36Sopenharmony_ci					      &p->path, type, result + sz,
188862306a36Sopenharmony_ci					      maxlen - sz);
188962306a36Sopenharmony_ci			}
189062306a36Sopenharmony_ci		}
189162306a36Sopenharmony_ci		break;
189262306a36Sopenharmony_ci
189362306a36Sopenharmony_ci	case STATUSTYPE_TABLE:
189462306a36Sopenharmony_ci		list_for_each_entry(pg, &m->priority_groups, list) {
189562306a36Sopenharmony_ci			DMEMIT("%s ", pg->ps.type->name);
189662306a36Sopenharmony_ci
189762306a36Sopenharmony_ci			if (pg->ps.type->status)
189862306a36Sopenharmony_ci				sz += pg->ps.type->status(&pg->ps, NULL, type,
189962306a36Sopenharmony_ci							  result + sz,
190062306a36Sopenharmony_ci							  maxlen - sz);
190162306a36Sopenharmony_ci			else
190262306a36Sopenharmony_ci				DMEMIT("0 ");
190362306a36Sopenharmony_ci
190462306a36Sopenharmony_ci			DMEMIT("%u %u ", pg->nr_pgpaths,
190562306a36Sopenharmony_ci			       pg->ps.type->table_args);
190662306a36Sopenharmony_ci
190762306a36Sopenharmony_ci			list_for_each_entry(p, &pg->pgpaths, list) {
190862306a36Sopenharmony_ci				DMEMIT("%s ", p->path.dev->name);
190962306a36Sopenharmony_ci				if (pg->ps.type->status)
191062306a36Sopenharmony_ci					sz += pg->ps.type->status(&pg->ps,
191162306a36Sopenharmony_ci					      &p->path, type, result + sz,
191262306a36Sopenharmony_ci					      maxlen - sz);
191362306a36Sopenharmony_ci			}
191462306a36Sopenharmony_ci		}
191562306a36Sopenharmony_ci		break;
191662306a36Sopenharmony_ci
191762306a36Sopenharmony_ci	case STATUSTYPE_IMA:
191862306a36Sopenharmony_ci		sz = 0; /*reset the result pointer*/
191962306a36Sopenharmony_ci
192062306a36Sopenharmony_ci		DMEMIT_TARGET_NAME_VERSION(ti->type);
192162306a36Sopenharmony_ci		DMEMIT(",nr_priority_groups=%u", m->nr_priority_groups);
192262306a36Sopenharmony_ci
192362306a36Sopenharmony_ci		pg_counter = 0;
192462306a36Sopenharmony_ci		list_for_each_entry(pg, &m->priority_groups, list) {
192562306a36Sopenharmony_ci			if (pg->bypassed)
192662306a36Sopenharmony_ci				state = 'D';	/* Disabled */
192762306a36Sopenharmony_ci			else if (pg == m->current_pg)
192862306a36Sopenharmony_ci				state = 'A';	/* Currently Active */
192962306a36Sopenharmony_ci			else
193062306a36Sopenharmony_ci				state = 'E';	/* Enabled */
193162306a36Sopenharmony_ci			DMEMIT(",pg_state_%d=%c", pg_counter, state);
193262306a36Sopenharmony_ci			DMEMIT(",nr_pgpaths_%d=%u", pg_counter, pg->nr_pgpaths);
193362306a36Sopenharmony_ci			DMEMIT(",path_selector_name_%d=%s", pg_counter, pg->ps.type->name);
193462306a36Sopenharmony_ci
193562306a36Sopenharmony_ci			pgpath_counter = 0;
193662306a36Sopenharmony_ci			list_for_each_entry(p, &pg->pgpaths, list) {
193762306a36Sopenharmony_ci				DMEMIT(",path_name_%d_%d=%s,is_active_%d_%d=%c,fail_count_%d_%d=%u",
193862306a36Sopenharmony_ci				       pg_counter, pgpath_counter, p->path.dev->name,
193962306a36Sopenharmony_ci				       pg_counter, pgpath_counter, p->is_active ? 'A' : 'F',
194062306a36Sopenharmony_ci				       pg_counter, pgpath_counter, p->fail_count);
194162306a36Sopenharmony_ci				if (pg->ps.type->status) {
194262306a36Sopenharmony_ci					DMEMIT(",path_selector_status_%d_%d=",
194362306a36Sopenharmony_ci					       pg_counter, pgpath_counter);
194462306a36Sopenharmony_ci					sz += pg->ps.type->status(&pg->ps, &p->path,
194562306a36Sopenharmony_ci								  type, result + sz,
194662306a36Sopenharmony_ci								  maxlen - sz);
194762306a36Sopenharmony_ci				}
194862306a36Sopenharmony_ci				pgpath_counter++;
194962306a36Sopenharmony_ci			}
195062306a36Sopenharmony_ci			pg_counter++;
195162306a36Sopenharmony_ci		}
195262306a36Sopenharmony_ci		DMEMIT(";");
195362306a36Sopenharmony_ci		break;
195462306a36Sopenharmony_ci	}
195562306a36Sopenharmony_ci
195662306a36Sopenharmony_ci	spin_unlock_irqrestore(&m->lock, flags);
195762306a36Sopenharmony_ci}
195862306a36Sopenharmony_ci
195962306a36Sopenharmony_cistatic int multipath_message(struct dm_target *ti, unsigned int argc, char **argv,
196062306a36Sopenharmony_ci			     char *result, unsigned int maxlen)
196162306a36Sopenharmony_ci{
196262306a36Sopenharmony_ci	int r = -EINVAL;
196362306a36Sopenharmony_ci	struct dm_dev *dev;
196462306a36Sopenharmony_ci	struct multipath *m = ti->private;
196562306a36Sopenharmony_ci	action_fn action;
196662306a36Sopenharmony_ci	unsigned long flags;
196762306a36Sopenharmony_ci
196862306a36Sopenharmony_ci	mutex_lock(&m->work_mutex);
196962306a36Sopenharmony_ci
197062306a36Sopenharmony_ci	if (dm_suspended(ti)) {
197162306a36Sopenharmony_ci		r = -EBUSY;
197262306a36Sopenharmony_ci		goto out;
197362306a36Sopenharmony_ci	}
197462306a36Sopenharmony_ci
197562306a36Sopenharmony_ci	if (argc == 1) {
197662306a36Sopenharmony_ci		if (!strcasecmp(argv[0], "queue_if_no_path")) {
197762306a36Sopenharmony_ci			r = queue_if_no_path(m, true, false, __func__);
197862306a36Sopenharmony_ci			spin_lock_irqsave(&m->lock, flags);
197962306a36Sopenharmony_ci			enable_nopath_timeout(m);
198062306a36Sopenharmony_ci			spin_unlock_irqrestore(&m->lock, flags);
198162306a36Sopenharmony_ci			goto out;
198262306a36Sopenharmony_ci		} else if (!strcasecmp(argv[0], "fail_if_no_path")) {
198362306a36Sopenharmony_ci			r = queue_if_no_path(m, false, false, __func__);
198462306a36Sopenharmony_ci			disable_nopath_timeout(m);
198562306a36Sopenharmony_ci			goto out;
198662306a36Sopenharmony_ci		}
198762306a36Sopenharmony_ci	}
198862306a36Sopenharmony_ci
198962306a36Sopenharmony_ci	if (argc != 2) {
199062306a36Sopenharmony_ci		DMWARN("Invalid multipath message arguments. Expected 2 arguments, got %d.", argc);
199162306a36Sopenharmony_ci		goto out;
199262306a36Sopenharmony_ci	}
199362306a36Sopenharmony_ci
199462306a36Sopenharmony_ci	if (!strcasecmp(argv[0], "disable_group")) {
199562306a36Sopenharmony_ci		r = bypass_pg_num(m, argv[1], true);
199662306a36Sopenharmony_ci		goto out;
199762306a36Sopenharmony_ci	} else if (!strcasecmp(argv[0], "enable_group")) {
199862306a36Sopenharmony_ci		r = bypass_pg_num(m, argv[1], false);
199962306a36Sopenharmony_ci		goto out;
200062306a36Sopenharmony_ci	} else if (!strcasecmp(argv[0], "switch_group")) {
200162306a36Sopenharmony_ci		r = switch_pg_num(m, argv[1]);
200262306a36Sopenharmony_ci		goto out;
200362306a36Sopenharmony_ci	} else if (!strcasecmp(argv[0], "reinstate_path"))
200462306a36Sopenharmony_ci		action = reinstate_path;
200562306a36Sopenharmony_ci	else if (!strcasecmp(argv[0], "fail_path"))
200662306a36Sopenharmony_ci		action = fail_path;
200762306a36Sopenharmony_ci	else {
200862306a36Sopenharmony_ci		DMWARN("Unrecognised multipath message received: %s", argv[0]);
200962306a36Sopenharmony_ci		goto out;
201062306a36Sopenharmony_ci	}
201162306a36Sopenharmony_ci
201262306a36Sopenharmony_ci	r = dm_get_device(ti, argv[1], dm_table_get_mode(ti->table), &dev);
201362306a36Sopenharmony_ci	if (r) {
201462306a36Sopenharmony_ci		DMWARN("message: error getting device %s",
201562306a36Sopenharmony_ci		       argv[1]);
201662306a36Sopenharmony_ci		goto out;
201762306a36Sopenharmony_ci	}
201862306a36Sopenharmony_ci
201962306a36Sopenharmony_ci	r = action_dev(m, dev, action);
202062306a36Sopenharmony_ci
202162306a36Sopenharmony_ci	dm_put_device(ti, dev);
202262306a36Sopenharmony_ci
202362306a36Sopenharmony_ciout:
202462306a36Sopenharmony_ci	mutex_unlock(&m->work_mutex);
202562306a36Sopenharmony_ci	return r;
202662306a36Sopenharmony_ci}
202762306a36Sopenharmony_ci
202862306a36Sopenharmony_cistatic int multipath_prepare_ioctl(struct dm_target *ti,
202962306a36Sopenharmony_ci				   struct block_device **bdev)
203062306a36Sopenharmony_ci{
203162306a36Sopenharmony_ci	struct multipath *m = ti->private;
203262306a36Sopenharmony_ci	struct pgpath *pgpath;
203362306a36Sopenharmony_ci	unsigned long flags;
203462306a36Sopenharmony_ci	int r;
203562306a36Sopenharmony_ci
203662306a36Sopenharmony_ci	pgpath = READ_ONCE(m->current_pgpath);
203762306a36Sopenharmony_ci	if (!pgpath || !mpath_double_check_test_bit(MPATHF_QUEUE_IO, m))
203862306a36Sopenharmony_ci		pgpath = choose_pgpath(m, 0);
203962306a36Sopenharmony_ci
204062306a36Sopenharmony_ci	if (pgpath) {
204162306a36Sopenharmony_ci		if (!mpath_double_check_test_bit(MPATHF_QUEUE_IO, m)) {
204262306a36Sopenharmony_ci			*bdev = pgpath->path.dev->bdev;
204362306a36Sopenharmony_ci			r = 0;
204462306a36Sopenharmony_ci		} else {
204562306a36Sopenharmony_ci			/* pg_init has not started or completed */
204662306a36Sopenharmony_ci			r = -ENOTCONN;
204762306a36Sopenharmony_ci		}
204862306a36Sopenharmony_ci	} else {
204962306a36Sopenharmony_ci		/* No path is available */
205062306a36Sopenharmony_ci		r = -EIO;
205162306a36Sopenharmony_ci		spin_lock_irqsave(&m->lock, flags);
205262306a36Sopenharmony_ci		if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))
205362306a36Sopenharmony_ci			r = -ENOTCONN;
205462306a36Sopenharmony_ci		spin_unlock_irqrestore(&m->lock, flags);
205562306a36Sopenharmony_ci	}
205662306a36Sopenharmony_ci
205762306a36Sopenharmony_ci	if (r == -ENOTCONN) {
205862306a36Sopenharmony_ci		if (!READ_ONCE(m->current_pg)) {
205962306a36Sopenharmony_ci			/* Path status changed, redo selection */
206062306a36Sopenharmony_ci			(void) choose_pgpath(m, 0);
206162306a36Sopenharmony_ci		}
206262306a36Sopenharmony_ci		spin_lock_irqsave(&m->lock, flags);
206362306a36Sopenharmony_ci		if (test_bit(MPATHF_PG_INIT_REQUIRED, &m->flags))
206462306a36Sopenharmony_ci			(void) __pg_init_all_paths(m);
206562306a36Sopenharmony_ci		spin_unlock_irqrestore(&m->lock, flags);
206662306a36Sopenharmony_ci		dm_table_run_md_queue_async(m->ti->table);
206762306a36Sopenharmony_ci		process_queued_io_list(m);
206862306a36Sopenharmony_ci	}
206962306a36Sopenharmony_ci
207062306a36Sopenharmony_ci	/*
207162306a36Sopenharmony_ci	 * Only pass ioctls through if the device sizes match exactly.
207262306a36Sopenharmony_ci	 */
207362306a36Sopenharmony_ci	if (!r && ti->len != bdev_nr_sectors((*bdev)))
207462306a36Sopenharmony_ci		return 1;
207562306a36Sopenharmony_ci	return r;
207662306a36Sopenharmony_ci}
207762306a36Sopenharmony_ci
207862306a36Sopenharmony_cistatic int multipath_iterate_devices(struct dm_target *ti,
207962306a36Sopenharmony_ci				     iterate_devices_callout_fn fn, void *data)
208062306a36Sopenharmony_ci{
208162306a36Sopenharmony_ci	struct multipath *m = ti->private;
208262306a36Sopenharmony_ci	struct priority_group *pg;
208362306a36Sopenharmony_ci	struct pgpath *p;
208462306a36Sopenharmony_ci	int ret = 0;
208562306a36Sopenharmony_ci
208662306a36Sopenharmony_ci	list_for_each_entry(pg, &m->priority_groups, list) {
208762306a36Sopenharmony_ci		list_for_each_entry(p, &pg->pgpaths, list) {
208862306a36Sopenharmony_ci			ret = fn(ti, p->path.dev, ti->begin, ti->len, data);
208962306a36Sopenharmony_ci			if (ret)
209062306a36Sopenharmony_ci				goto out;
209162306a36Sopenharmony_ci		}
209262306a36Sopenharmony_ci	}
209362306a36Sopenharmony_ci
209462306a36Sopenharmony_ciout:
209562306a36Sopenharmony_ci	return ret;
209662306a36Sopenharmony_ci}
209762306a36Sopenharmony_ci
209862306a36Sopenharmony_cistatic int pgpath_busy(struct pgpath *pgpath)
209962306a36Sopenharmony_ci{
210062306a36Sopenharmony_ci	struct request_queue *q = bdev_get_queue(pgpath->path.dev->bdev);
210162306a36Sopenharmony_ci
210262306a36Sopenharmony_ci	return blk_lld_busy(q);
210362306a36Sopenharmony_ci}
210462306a36Sopenharmony_ci
210562306a36Sopenharmony_ci/*
210662306a36Sopenharmony_ci * We return "busy", only when we can map I/Os but underlying devices
210762306a36Sopenharmony_ci * are busy (so even if we map I/Os now, the I/Os will wait on
210862306a36Sopenharmony_ci * the underlying queue).
210962306a36Sopenharmony_ci * In other words, if we want to kill I/Os or queue them inside us
211062306a36Sopenharmony_ci * due to map unavailability, we don't return "busy".  Otherwise,
211162306a36Sopenharmony_ci * dm core won't give us the I/Os and we can't do what we want.
211262306a36Sopenharmony_ci */
211362306a36Sopenharmony_cistatic int multipath_busy(struct dm_target *ti)
211462306a36Sopenharmony_ci{
211562306a36Sopenharmony_ci	bool busy = false, has_active = false;
211662306a36Sopenharmony_ci	struct multipath *m = ti->private;
211762306a36Sopenharmony_ci	struct priority_group *pg, *next_pg;
211862306a36Sopenharmony_ci	struct pgpath *pgpath;
211962306a36Sopenharmony_ci
212062306a36Sopenharmony_ci	/* pg_init in progress */
212162306a36Sopenharmony_ci	if (atomic_read(&m->pg_init_in_progress))
212262306a36Sopenharmony_ci		return true;
212362306a36Sopenharmony_ci
212462306a36Sopenharmony_ci	/* no paths available, for blk-mq: rely on IO mapping to delay requeue */
212562306a36Sopenharmony_ci	if (!atomic_read(&m->nr_valid_paths)) {
212662306a36Sopenharmony_ci		unsigned long flags;
212762306a36Sopenharmony_ci
212862306a36Sopenharmony_ci		spin_lock_irqsave(&m->lock, flags);
212962306a36Sopenharmony_ci		if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) {
213062306a36Sopenharmony_ci			spin_unlock_irqrestore(&m->lock, flags);
213162306a36Sopenharmony_ci			return (m->queue_mode != DM_TYPE_REQUEST_BASED);
213262306a36Sopenharmony_ci		}
213362306a36Sopenharmony_ci		spin_unlock_irqrestore(&m->lock, flags);
213462306a36Sopenharmony_ci	}
213562306a36Sopenharmony_ci
213662306a36Sopenharmony_ci	/* Guess which priority_group will be used at next mapping time */
213762306a36Sopenharmony_ci	pg = READ_ONCE(m->current_pg);
213862306a36Sopenharmony_ci	next_pg = READ_ONCE(m->next_pg);
213962306a36Sopenharmony_ci	if (unlikely(!READ_ONCE(m->current_pgpath) && next_pg))
214062306a36Sopenharmony_ci		pg = next_pg;
214162306a36Sopenharmony_ci
214262306a36Sopenharmony_ci	if (!pg) {
214362306a36Sopenharmony_ci		/*
214462306a36Sopenharmony_ci		 * We don't know which pg will be used at next mapping time.
214562306a36Sopenharmony_ci		 * We don't call choose_pgpath() here to avoid to trigger
214662306a36Sopenharmony_ci		 * pg_init just by busy checking.
214762306a36Sopenharmony_ci		 * So we don't know whether underlying devices we will be using
214862306a36Sopenharmony_ci		 * at next mapping time are busy or not. Just try mapping.
214962306a36Sopenharmony_ci		 */
215062306a36Sopenharmony_ci		return busy;
215162306a36Sopenharmony_ci	}
215262306a36Sopenharmony_ci
215362306a36Sopenharmony_ci	/*
215462306a36Sopenharmony_ci	 * If there is one non-busy active path at least, the path selector
215562306a36Sopenharmony_ci	 * will be able to select it. So we consider such a pg as not busy.
215662306a36Sopenharmony_ci	 */
215762306a36Sopenharmony_ci	busy = true;
215862306a36Sopenharmony_ci	list_for_each_entry(pgpath, &pg->pgpaths, list) {
215962306a36Sopenharmony_ci		if (pgpath->is_active) {
216062306a36Sopenharmony_ci			has_active = true;
216162306a36Sopenharmony_ci			if (!pgpath_busy(pgpath)) {
216262306a36Sopenharmony_ci				busy = false;
216362306a36Sopenharmony_ci				break;
216462306a36Sopenharmony_ci			}
216562306a36Sopenharmony_ci		}
216662306a36Sopenharmony_ci	}
216762306a36Sopenharmony_ci
216862306a36Sopenharmony_ci	if (!has_active) {
216962306a36Sopenharmony_ci		/*
217062306a36Sopenharmony_ci		 * No active path in this pg, so this pg won't be used and
217162306a36Sopenharmony_ci		 * the current_pg will be changed at next mapping time.
217262306a36Sopenharmony_ci		 * We need to try mapping to determine it.
217362306a36Sopenharmony_ci		 */
217462306a36Sopenharmony_ci		busy = false;
217562306a36Sopenharmony_ci	}
217662306a36Sopenharmony_ci
217762306a36Sopenharmony_ci	return busy;
217862306a36Sopenharmony_ci}
217962306a36Sopenharmony_ci
218062306a36Sopenharmony_ci/*
218162306a36Sopenharmony_ci *---------------------------------------------------------------
218262306a36Sopenharmony_ci * Module setup
218362306a36Sopenharmony_ci *---------------------------------------------------------------
218462306a36Sopenharmony_ci */
218562306a36Sopenharmony_cistatic struct target_type multipath_target = {
218662306a36Sopenharmony_ci	.name = "multipath",
218762306a36Sopenharmony_ci	.version = {1, 14, 0},
218862306a36Sopenharmony_ci	.features = DM_TARGET_SINGLETON | DM_TARGET_IMMUTABLE |
218962306a36Sopenharmony_ci		    DM_TARGET_PASSES_INTEGRITY,
219062306a36Sopenharmony_ci	.module = THIS_MODULE,
219162306a36Sopenharmony_ci	.ctr = multipath_ctr,
219262306a36Sopenharmony_ci	.dtr = multipath_dtr,
219362306a36Sopenharmony_ci	.clone_and_map_rq = multipath_clone_and_map,
219462306a36Sopenharmony_ci	.release_clone_rq = multipath_release_clone,
219562306a36Sopenharmony_ci	.rq_end_io = multipath_end_io,
219662306a36Sopenharmony_ci	.map = multipath_map_bio,
219762306a36Sopenharmony_ci	.end_io = multipath_end_io_bio,
219862306a36Sopenharmony_ci	.presuspend = multipath_presuspend,
219962306a36Sopenharmony_ci	.postsuspend = multipath_postsuspend,
220062306a36Sopenharmony_ci	.resume = multipath_resume,
220162306a36Sopenharmony_ci	.status = multipath_status,
220262306a36Sopenharmony_ci	.message = multipath_message,
220362306a36Sopenharmony_ci	.prepare_ioctl = multipath_prepare_ioctl,
220462306a36Sopenharmony_ci	.iterate_devices = multipath_iterate_devices,
220562306a36Sopenharmony_ci	.busy = multipath_busy,
220662306a36Sopenharmony_ci};
220762306a36Sopenharmony_ci
220862306a36Sopenharmony_cistatic int __init dm_multipath_init(void)
220962306a36Sopenharmony_ci{
221062306a36Sopenharmony_ci	int r = -ENOMEM;
221162306a36Sopenharmony_ci
221262306a36Sopenharmony_ci	kmultipathd = alloc_workqueue("kmpathd", WQ_MEM_RECLAIM, 0);
221362306a36Sopenharmony_ci	if (!kmultipathd) {
221462306a36Sopenharmony_ci		DMERR("failed to create workqueue kmpathd");
221562306a36Sopenharmony_ci		goto bad_alloc_kmultipathd;
221662306a36Sopenharmony_ci	}
221762306a36Sopenharmony_ci
221862306a36Sopenharmony_ci	/*
221962306a36Sopenharmony_ci	 * A separate workqueue is used to handle the device handlers
222062306a36Sopenharmony_ci	 * to avoid overloading existing workqueue. Overloading the
222162306a36Sopenharmony_ci	 * old workqueue would also create a bottleneck in the
222262306a36Sopenharmony_ci	 * path of the storage hardware device activation.
222362306a36Sopenharmony_ci	 */
222462306a36Sopenharmony_ci	kmpath_handlerd = alloc_ordered_workqueue("kmpath_handlerd",
222562306a36Sopenharmony_ci						  WQ_MEM_RECLAIM);
222662306a36Sopenharmony_ci	if (!kmpath_handlerd) {
222762306a36Sopenharmony_ci		DMERR("failed to create workqueue kmpath_handlerd");
222862306a36Sopenharmony_ci		goto bad_alloc_kmpath_handlerd;
222962306a36Sopenharmony_ci	}
223062306a36Sopenharmony_ci
223162306a36Sopenharmony_ci	dm_mpath_wq = alloc_workqueue("dm_mpath_wq", 0, 0);
223262306a36Sopenharmony_ci	if (!dm_mpath_wq) {
223362306a36Sopenharmony_ci		DMERR("failed to create workqueue dm_mpath_wq");
223462306a36Sopenharmony_ci		goto bad_alloc_dm_mpath_wq;
223562306a36Sopenharmony_ci	}
223662306a36Sopenharmony_ci
223762306a36Sopenharmony_ci	r = dm_register_target(&multipath_target);
223862306a36Sopenharmony_ci	if (r < 0)
223962306a36Sopenharmony_ci		goto bad_register_target;
224062306a36Sopenharmony_ci
224162306a36Sopenharmony_ci	return 0;
224262306a36Sopenharmony_ci
224362306a36Sopenharmony_cibad_register_target:
224462306a36Sopenharmony_ci	destroy_workqueue(dm_mpath_wq);
224562306a36Sopenharmony_cibad_alloc_dm_mpath_wq:
224662306a36Sopenharmony_ci	destroy_workqueue(kmpath_handlerd);
224762306a36Sopenharmony_cibad_alloc_kmpath_handlerd:
224862306a36Sopenharmony_ci	destroy_workqueue(kmultipathd);
224962306a36Sopenharmony_cibad_alloc_kmultipathd:
225062306a36Sopenharmony_ci	return r;
225162306a36Sopenharmony_ci}
225262306a36Sopenharmony_ci
225362306a36Sopenharmony_cistatic void __exit dm_multipath_exit(void)
225462306a36Sopenharmony_ci{
225562306a36Sopenharmony_ci	destroy_workqueue(dm_mpath_wq);
225662306a36Sopenharmony_ci	destroy_workqueue(kmpath_handlerd);
225762306a36Sopenharmony_ci	destroy_workqueue(kmultipathd);
225862306a36Sopenharmony_ci
225962306a36Sopenharmony_ci	dm_unregister_target(&multipath_target);
226062306a36Sopenharmony_ci}
226162306a36Sopenharmony_ci
226262306a36Sopenharmony_cimodule_init(dm_multipath_init);
226362306a36Sopenharmony_cimodule_exit(dm_multipath_exit);
226462306a36Sopenharmony_ci
226562306a36Sopenharmony_cimodule_param_named(queue_if_no_path_timeout_secs, queue_if_no_path_timeout_secs, ulong, 0644);
226662306a36Sopenharmony_ciMODULE_PARM_DESC(queue_if_no_path_timeout_secs, "No available paths queue IO timeout in seconds");
226762306a36Sopenharmony_ci
226862306a36Sopenharmony_ciMODULE_DESCRIPTION(DM_NAME " multipath target");
226962306a36Sopenharmony_ciMODULE_AUTHOR("Sistina Software <dm-devel@redhat.com>");
227062306a36Sopenharmony_ciMODULE_LICENSE("GPL");
2271