[SCSI] scsi_dh: Change the scsidh_activate interface to be asynchronous
Make scsi_dh_activate() function asynchronous, by taking in two additional parameters, one is the callback function and the other is the data to call the callback function with. Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
Родитель
42e62a7437
Коммит
3ae31f6a7b
|
@ -1116,8 +1116,9 @@ static int pg_init_limit_reached(struct multipath *m, struct pgpath *pgpath)
|
|||
return limit_reached;
|
||||
}
|
||||
|
||||
static void pg_init_done(struct dm_path *path, int errors)
|
||||
static void pg_init_done(void *data, int errors)
|
||||
{
|
||||
struct dm_path *path = data;
|
||||
struct pgpath *pgpath = path_to_pgpath(path);
|
||||
struct priority_group *pg = pgpath->pg;
|
||||
struct multipath *m = pg->m;
|
||||
|
@ -1183,12 +1184,11 @@ static void pg_init_done(struct dm_path *path, int errors)
|
|||
|
||||
static void activate_path(struct work_struct *work)
|
||||
{
|
||||
int ret;
|
||||
struct pgpath *pgpath =
|
||||
container_of(work, struct pgpath, activate_path);
|
||||
|
||||
ret = scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev));
|
||||
pg_init_done(&pgpath->path, ret);
|
||||
scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev),
|
||||
pg_init_done, &pgpath->path);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -226,7 +226,7 @@ store_dh_state(struct device *dev, struct device_attribute *attr,
|
|||
* Activate a device handler
|
||||
*/
|
||||
if (scsi_dh->activate)
|
||||
err = scsi_dh->activate(sdev);
|
||||
err = scsi_dh->activate(sdev, NULL, NULL);
|
||||
else
|
||||
err = 0;
|
||||
}
|
||||
|
@ -423,10 +423,17 @@ EXPORT_SYMBOL_GPL(scsi_unregister_device_handler);
|
|||
/*
|
||||
* scsi_dh_activate - activate the path associated with the scsi_device
|
||||
* corresponding to the given request queue.
|
||||
* @q - Request queue that is associated with the scsi_device to be
|
||||
* activated.
|
||||
* Returns immediately without waiting for activation to be completed.
|
||||
* @q - Request queue that is associated with the scsi_device to be
|
||||
* activated.
|
||||
* @fn - Function to be called upon completion of the activation.
|
||||
* Function fn is called with data (below) and the error code.
|
||||
* Function fn may be called from the same calling context. So,
|
||||
* do not hold the lock in the caller which may be needed in fn.
|
||||
* @data - data passed to the function fn upon completion.
|
||||
*
|
||||
*/
|
||||
int scsi_dh_activate(struct request_queue *q)
|
||||
int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned long flags;
|
||||
|
@ -445,7 +452,7 @@ int scsi_dh_activate(struct request_queue *q)
|
|||
return err;
|
||||
|
||||
if (scsi_dh->activate)
|
||||
err = scsi_dh->activate(sdev);
|
||||
err = scsi_dh->activate(sdev, fn, data);
|
||||
put_device(&sdev->sdev_gendev);
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -652,7 +652,8 @@ out:
|
|||
* based on a certain policy. But until we actually encounter them it
|
||||
* should be okay.
|
||||
*/
|
||||
static int alua_activate(struct scsi_device *sdev)
|
||||
static int alua_activate(struct scsi_device *sdev,
|
||||
activate_complete fn, void *data)
|
||||
{
|
||||
struct alua_dh_data *h = get_alua_data(sdev);
|
||||
int err = SCSI_DH_OK;
|
||||
|
@ -667,7 +668,9 @@ static int alua_activate(struct scsi_device *sdev)
|
|||
err = alua_stpg(sdev, TPGS_STATE_OPTIMIZED, h);
|
||||
|
||||
out:
|
||||
return err;
|
||||
if (fn)
|
||||
fn(data, err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -528,7 +528,8 @@ retry:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int clariion_activate(struct scsi_device *sdev)
|
||||
static int clariion_activate(struct scsi_device *sdev,
|
||||
activate_complete fn, void *data)
|
||||
{
|
||||
struct clariion_dh_data *csdev = get_clariion_data(sdev);
|
||||
int result;
|
||||
|
@ -559,7 +560,9 @@ done:
|
|||
csdev->port, lun_state[csdev->lun_state],
|
||||
csdev->default_sp + 'A');
|
||||
|
||||
return result;
|
||||
if (fn)
|
||||
fn(data, result);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* params - parameters in the following format
|
||||
|
|
|
@ -268,7 +268,8 @@ static int hp_sw_prep_fn(struct scsi_device *sdev, struct request *req)
|
|||
* activate the passive path (and deactivate the
|
||||
* previously active one).
|
||||
*/
|
||||
static int hp_sw_activate(struct scsi_device *sdev)
|
||||
static int hp_sw_activate(struct scsi_device *sdev,
|
||||
activate_complete fn, void *data)
|
||||
{
|
||||
int ret = SCSI_DH_OK;
|
||||
struct hp_sw_dh_data *h = get_hp_sw_data(sdev);
|
||||
|
@ -283,7 +284,9 @@ static int hp_sw_activate(struct scsi_device *sdev)
|
|||
HP_SW_NAME);
|
||||
}
|
||||
|
||||
return ret;
|
||||
if (fn)
|
||||
fn(data, ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct scsi_dh_devlist hp_sw_dh_data_list[] = {
|
||||
|
|
|
@ -568,7 +568,8 @@ done:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int rdac_activate(struct scsi_device *sdev)
|
||||
static int rdac_activate(struct scsi_device *sdev,
|
||||
activate_complete fn, void *data)
|
||||
{
|
||||
struct rdac_dh_data *h = get_rdac_data(sdev);
|
||||
int err = SCSI_DH_OK;
|
||||
|
@ -580,7 +581,9 @@ static int rdac_activate(struct scsi_device *sdev)
|
|||
if (h->lun_state == RDAC_LUN_UNOWNED)
|
||||
err = send_mode_select(sdev, h);
|
||||
done:
|
||||
return err;
|
||||
if (fn)
|
||||
fn(data, err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rdac_prep_fn(struct scsi_device *sdev, struct request *req)
|
||||
|
|
|
@ -177,6 +177,7 @@ struct scsi_dh_devlist {
|
|||
char *model;
|
||||
};
|
||||
|
||||
typedef void (*activate_complete)(void *, int);
|
||||
struct scsi_device_handler {
|
||||
/* Used by the infrastructure */
|
||||
struct list_head list; /* list of scsi_device_handlers */
|
||||
|
@ -188,7 +189,7 @@ struct scsi_device_handler {
|
|||
int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *);
|
||||
int (*attach)(struct scsi_device *);
|
||||
void (*detach)(struct scsi_device *);
|
||||
int (*activate)(struct scsi_device *);
|
||||
int (*activate)(struct scsi_device *, activate_complete, void *);
|
||||
int (*prep_fn)(struct scsi_device *, struct request *);
|
||||
int (*set_params)(struct scsi_device *, const char *);
|
||||
};
|
||||
|
|
|
@ -56,14 +56,16 @@ enum {
|
|||
SCSI_DH_DRIVER_MAX,
|
||||
};
|
||||
#if defined(CONFIG_SCSI_DH) || defined(CONFIG_SCSI_DH_MODULE)
|
||||
extern int scsi_dh_activate(struct request_queue *);
|
||||
extern int scsi_dh_activate(struct request_queue *, activate_complete, void *);
|
||||
extern int scsi_dh_handler_exist(const char *);
|
||||
extern int scsi_dh_attach(struct request_queue *, const char *);
|
||||
extern void scsi_dh_detach(struct request_queue *);
|
||||
extern int scsi_dh_set_params(struct request_queue *, const char *);
|
||||
#else
|
||||
static inline int scsi_dh_activate(struct request_queue *req)
|
||||
static inline int scsi_dh_activate(struct request_queue *req,
|
||||
activate_complete fn, void *data)
|
||||
{
|
||||
fn(data, 0);
|
||||
return 0;
|
||||
}
|
||||
static inline int scsi_dh_handler_exist(const char *name)
|
||||
|
|
Загрузка…
Ссылка в новой задаче