Remove blk request handling path
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
parent
7343cb55fa
commit
b82b338c53
@ -21,10 +21,10 @@ apply() {
|
|||||||
case "$1" in
|
case "$1" in
|
||||||
"1")
|
"1")
|
||||||
add_define "CAS_BLK_STATUS_T blk_status_t"
|
add_define "CAS_BLK_STATUS_T blk_status_t"
|
||||||
add_define "CAS_BLK_STS_OK BLK_STS_OK" ;;
|
add_define "CAS_BLK_STS_NOTSUPP BLK_STS_NOTSUPP" ;;
|
||||||
"2")
|
"2")
|
||||||
add_define "CAS_BLK_STATUS_T int"
|
add_define "CAS_BLK_STATUS_T int"
|
||||||
add_define "CAS_BLK_STS_OK 0" ;;
|
add_define "CAS_BLK_STS_NOTSUPP -ENOTSUPP" ;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -9,17 +9,6 @@
|
|||||||
#include "obj_blk.h"
|
#include "obj_blk.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
|
|
||||||
static inline bool cas_blk_is_flush_io(unsigned long flags)
|
|
||||||
{
|
|
||||||
if ((flags & CAS_WRITE_FLUSH) == CAS_WRITE_FLUSH)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if ((flags & CAS_WRITE_FLUSH_FUA) == CAS_WRITE_FLUSH_FUA)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct blkio {
|
struct blkio {
|
||||||
int error;
|
int error;
|
||||||
atomic_t rq_remaning;
|
atomic_t rq_remaning;
|
||||||
|
@ -6,34 +6,6 @@
|
|||||||
#include "cas_cache.h"
|
#include "cas_cache.h"
|
||||||
#include "utils/cas_err.h"
|
#include "utils/cas_err.h"
|
||||||
|
|
||||||
#define BLK_RQ_POS(rq) (CAS_BIO_BISECTOR((rq)->bio))
|
|
||||||
#define BLK_RQ_BYTES(rq) blk_rq_bytes(rq)
|
|
||||||
|
|
||||||
static inline void _blockdev_end_request_all(struct request *rq, int error)
|
|
||||||
{
|
|
||||||
CAS_END_REQUEST_ALL(rq, CAS_ERRNO_TO_BLK_STS(
|
|
||||||
map_cas_err_to_generic(error)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool _blockdev_can_handle_rq(struct request *rq)
|
|
||||||
{
|
|
||||||
int error = 0;
|
|
||||||
|
|
||||||
if (unlikely(!cas_is_rq_type_fs(rq)))
|
|
||||||
error = __LINE__;
|
|
||||||
|
|
||||||
if (unlikely(CAS_BLK_BIDI_RQ(rq)))
|
|
||||||
error = __LINE__;
|
|
||||||
|
|
||||||
if (error != 0) {
|
|
||||||
CAS_PRINT_RL(KERN_ERR "%s cannot handle request (ERROR %d)\n",
|
|
||||||
rq->rq_disk->disk_name, error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _blockdev_set_bio_data(struct blk_data *data, struct bio *bio)
|
static void _blockdev_set_bio_data(struct blk_data *data, struct bio *bio)
|
||||||
{
|
{
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
|
||||||
@ -80,400 +52,6 @@ void block_dev_start_bio(struct ocf_io *io)
|
|||||||
|
|
||||||
data->start_time = _blockdev_start_io_acct(bio);
|
data->start_time = _blockdev_start_io_acct(bio);
|
||||||
}
|
}
|
||||||
void block_dev_complete_rq(struct ocf_io *io, int error)
|
|
||||||
|
|
||||||
{
|
|
||||||
struct blk_data *data = ocf_io_get_data(io);
|
|
||||||
struct request *rq = data->master_io_req;
|
|
||||||
|
|
||||||
_blockdev_end_request_all(rq, error);
|
|
||||||
ocf_io_put(io);
|
|
||||||
cas_free_blk_data(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void block_dev_complete_sub_rq(struct ocf_io *io, int error)
|
|
||||||
{
|
|
||||||
struct blk_data *data = ocf_io_get_data(io);
|
|
||||||
struct ocf_io *master = data->master_io_req;
|
|
||||||
struct blk_data *master_data = ocf_io_get_data(master);
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
master_data->error = error;
|
|
||||||
|
|
||||||
if (atomic_dec_return(&master_data->master_remaining) == 0) {
|
|
||||||
_blockdev_end_request_all(master_data->master_io_req,
|
|
||||||
master_data->error);
|
|
||||||
cas_free_blk_data(master_data);
|
|
||||||
ocf_io_put(master);
|
|
||||||
}
|
|
||||||
|
|
||||||
ocf_io_put(io);
|
|
||||||
cas_free_blk_data(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void block_dev_complete_flush(struct ocf_io *io, int error)
|
|
||||||
{
|
|
||||||
struct request *rq = io->priv1;
|
|
||||||
|
|
||||||
_blockdev_end_request_all(rq, error);
|
|
||||||
ocf_io_put(io);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _blockdev_is_request_barier(struct request *rq)
|
|
||||||
{
|
|
||||||
struct bio *i_bio = rq->bio;
|
|
||||||
|
|
||||||
for_each_bio(i_bio) {
|
|
||||||
if (CAS_CHECK_BARRIER(i_bio))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _blockdev_alloc_many_requests(ocf_core_t core,
|
|
||||||
struct list_head *list, struct request *rq,
|
|
||||||
struct ocf_io *master)
|
|
||||||
{
|
|
||||||
ocf_cache_t cache = ocf_core_get_cache(core);
|
|
||||||
struct cache_priv *cache_priv = ocf_cache_get_priv(cache);
|
|
||||||
int error = 0;
|
|
||||||
int flags = 0;
|
|
||||||
struct bio *bio;
|
|
||||||
struct ocf_io *sub_io;
|
|
||||||
struct blk_data *master_data = ocf_io_get_data(master);
|
|
||||||
struct blk_data *data;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(list);
|
|
||||||
|
|
||||||
/* Go over requests and allocate sub requests */
|
|
||||||
bio = rq->bio;
|
|
||||||
for_each_bio(bio) {
|
|
||||||
/* Setup BIO flags */
|
|
||||||
if (CAS_IS_WRITE_FLUSH_FUA(CAS_BIO_OP_FLAGS(bio))) {
|
|
||||||
/* FLUSH and FUA */
|
|
||||||
flags = CAS_WRITE_FLUSH_FUA;
|
|
||||||
} else if (CAS_IS_WRITE_FUA(CAS_BIO_OP_FLAGS(bio))) {
|
|
||||||
/* FUA */
|
|
||||||
flags = CAS_WRITE_FUA;
|
|
||||||
} else if (CAS_IS_WRITE_FLUSH(CAS_BIO_OP_FLAGS(bio))) {
|
|
||||||
/* FLUSH - It shall be handled in request handler */
|
|
||||||
error = -EINVAL;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
flags = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
data = cas_alloc_blk_data(bio_segments(bio), GFP_NOIO);
|
|
||||||
if (!data) {
|
|
||||||
CAS_PRINT_RL(KERN_CRIT "BIO data vector allocation error\n");
|
|
||||||
error = -ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_blockdev_set_bio_data(data, bio);
|
|
||||||
|
|
||||||
data->master_io_req = master;
|
|
||||||
|
|
||||||
sub_io = ocf_core_new_io(core,
|
|
||||||
cache_priv->io_queues[smp_processor_id()],
|
|
||||||
CAS_BIO_BISECTOR(bio) << SECTOR_SHIFT,
|
|
||||||
CAS_BIO_BISIZE(bio), (bio_data_dir(bio) == READ) ?
|
|
||||||
OCF_READ : OCF_WRITE,
|
|
||||||
cas_cls_classify(cache, bio), flags);
|
|
||||||
|
|
||||||
if (!sub_io) {
|
|
||||||
cas_free_blk_data(data);
|
|
||||||
error = -ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->io = sub_io;
|
|
||||||
|
|
||||||
error = ocf_io_set_data(sub_io, data, 0);
|
|
||||||
if (error) {
|
|
||||||
ocf_io_put(sub_io);
|
|
||||||
cas_free_blk_data(data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ocf_io_set_cmpl(sub_io, NULL, NULL, block_dev_complete_sub_rq);
|
|
||||||
|
|
||||||
list_add_tail(&data->list, list);
|
|
||||||
atomic_inc(&master_data->master_remaining);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
CAS_PRINT_RL(KERN_ERR "Cannot handle request (ERROR %d)\n", error);
|
|
||||||
|
|
||||||
/* Go over list and free all */
|
|
||||||
while (!list_empty(list)) {
|
|
||||||
data = list_first_entry(list, struct blk_data, list);
|
|
||||||
list_del(&data->list);
|
|
||||||
|
|
||||||
sub_io = data->io;
|
|
||||||
ocf_io_put(sub_io);
|
|
||||||
cas_free_blk_data(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _blockdev_set_request_data(struct blk_data *data, struct request *rq)
|
|
||||||
{
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
|
|
||||||
struct req_iterator iter;
|
|
||||||
struct bio_vec *bvec;
|
|
||||||
uint32_t i = 0;
|
|
||||||
|
|
||||||
rq_for_each_segment(bvec, rq, iter) {
|
|
||||||
BUG_ON(i >= data->size);
|
|
||||||
data->vec[i] = *bvec;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
struct req_iterator iter;
|
|
||||||
struct bio_vec bvec;
|
|
||||||
uint32_t i = 0;
|
|
||||||
|
|
||||||
rq_for_each_segment(bvec, rq, iter) {
|
|
||||||
BUG_ON(i >= data->size);
|
|
||||||
data->vec[i] = bvec;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief push flush request upon execution queue for given core device
|
|
||||||
*/
|
|
||||||
static int _blkdev_handle_flush_request(struct request *rq, ocf_core_t core)
|
|
||||||
{
|
|
||||||
struct ocf_io *io;
|
|
||||||
ocf_cache_t cache = ocf_core_get_cache(core);
|
|
||||||
struct cache_priv *cache_priv = ocf_cache_get_priv(cache);
|
|
||||||
|
|
||||||
io = ocf_core_new_io(core, cache_priv->io_queues[smp_processor_id()],
|
|
||||||
0, 0, OCF_WRITE, 0, CAS_WRITE_FLUSH);
|
|
||||||
if (!io)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
ocf_io_set_cmpl(io, rq, NULL, block_dev_complete_flush);
|
|
||||||
|
|
||||||
ocf_core_submit_flush(io);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef RQ_CHECK_CONTINOUS
|
|
||||||
static inline bool _bvec_is_mergeable(struct bio_vec *bv1, struct bio_vec *bv2)
|
|
||||||
{
|
|
||||||
if (bv1 == NULL)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (BIOVEC_PHYS_MERGEABLE(bv1, bv2))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return !bv2->bv_offset && !((bv1->bv_offset + bv1->bv_len) % PAGE_SIZE);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static uint32_t _blkdev_scan_request(ocf_cache_t cache, struct request *rq,
|
|
||||||
struct ocf_io *io, bool *single_io)
|
|
||||||
{
|
|
||||||
uint32_t size = 0;
|
|
||||||
struct req_iterator iter;
|
|
||||||
struct bio *bio_prev = NULL;
|
|
||||||
uint32_t io_class;
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
|
|
||||||
struct bio_vec bvec;
|
|
||||||
#ifdef RQ_CHECK_CONTINOUS
|
|
||||||
struct bio_vec bvec_prev = { NULL, };
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
struct bio_vec *bvec;
|
|
||||||
#ifdef RQ_CHECK_CONTINOUS
|
|
||||||
struct bio_vec *bvec_prev = NULL;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*single_io = true;
|
|
||||||
|
|
||||||
/* Scan BIOs in the request to:
|
|
||||||
* 1. Count the segments number
|
|
||||||
* 2. Check if requests contains many IO classes
|
|
||||||
* 3. Check if request is continuous (when process kernel stack is 8KB)
|
|
||||||
*/
|
|
||||||
rq_for_each_segment(bvec, rq, iter) {
|
|
||||||
/* Increase BIO data vector counter */
|
|
||||||
size++;
|
|
||||||
|
|
||||||
if (*single_io == false) {
|
|
||||||
/* Already detected complex request */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef RQ_CHECK_CONTINOUS
|
|
||||||
/*
|
|
||||||
* If request is not continous submit each bio as separate
|
|
||||||
* request, and prevent nvme driver from splitting requests.
|
|
||||||
* For large requests, nvme splitting causes stack overrun.
|
|
||||||
*/
|
|
||||||
if (!_bvec_is_mergeable(CAS_SEGMENT_BVEC(bvec_prev),
|
|
||||||
CAS_SEGMENT_BVEC(bvec))) {
|
|
||||||
*single_io = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
bvec_prev = bvec;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (bio_prev == iter.bio)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
bio_prev = iter.bio;
|
|
||||||
|
|
||||||
/* Get class ID for given BIO */
|
|
||||||
io_class = cas_cls_classify(cache, iter.bio);
|
|
||||||
|
|
||||||
if (io->io_class != io_class) {
|
|
||||||
/*
|
|
||||||
* Request contains BIO with different IO classes and
|
|
||||||
* need to handle BIO separately
|
|
||||||
*/
|
|
||||||
*single_io = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __block_dev_queue_rq(struct request *rq, ocf_core_t core)
|
|
||||||
{
|
|
||||||
ocf_cache_t cache = ocf_core_get_cache(core);
|
|
||||||
struct cache_priv *cache_priv = ocf_cache_get_priv(cache);
|
|
||||||
struct ocf_io *io;
|
|
||||||
struct blk_data *data;
|
|
||||||
int master_flags = 0;
|
|
||||||
bool single_io;
|
|
||||||
uint32_t size;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (_blockdev_is_request_barier(rq) || !_blockdev_can_handle_rq(rq)) {
|
|
||||||
CAS_PRINT_RL(KERN_WARNING
|
|
||||||
"special bio was sent,not supported!\n");
|
|
||||||
return -ENOTSUPP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((rq->cmd_flags & REQ_FUA) && CAS_RQ_IS_FLUSH(rq)) {
|
|
||||||
/* FLUSH and FUA */
|
|
||||||
master_flags = CAS_WRITE_FLUSH_FUA;
|
|
||||||
} else if (rq->cmd_flags & REQ_FUA) {
|
|
||||||
/* FUA */
|
|
||||||
master_flags = CAS_WRITE_FUA;
|
|
||||||
} else if (CAS_RQ_IS_FLUSH(rq)) {
|
|
||||||
/* FLUSH */
|
|
||||||
return _blkdev_handle_flush_request(rq, core);
|
|
||||||
}
|
|
||||||
|
|
||||||
io = ocf_core_new_io(core, cache_priv->io_queues[smp_processor_id()],
|
|
||||||
BLK_RQ_POS(rq) << SECTOR_SHIFT, BLK_RQ_BYTES(rq),
|
|
||||||
(rq_data_dir(rq) == CAS_RQ_DATA_DIR_WR) ?
|
|
||||||
OCF_WRITE : OCF_READ,
|
|
||||||
cas_cls_classify(cache, rq->bio), master_flags);
|
|
||||||
if (!io) {
|
|
||||||
CAS_PRINT_RL(KERN_CRIT "Out of memory. Ending IO processing.\n");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size = _blkdev_scan_request(cache, rq, io, &single_io);
|
|
||||||
|
|
||||||
if (unlikely(size == 0)) {
|
|
||||||
CAS_PRINT_RL(KERN_ERR "Empty IO request\n");
|
|
||||||
ocf_io_put(io);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (single_io) {
|
|
||||||
data = cas_alloc_blk_data(size, GFP_NOIO);
|
|
||||||
if (data == NULL) {
|
|
||||||
CAS_PRINT_RL(KERN_CRIT
|
|
||||||
"Out of memory. Ending IO processing.\n");
|
|
||||||
ocf_io_put(io);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
_blockdev_set_request_data(data, rq);
|
|
||||||
|
|
||||||
data->master_io_req = rq;
|
|
||||||
|
|
||||||
ret = ocf_io_set_data(io, data, 0);
|
|
||||||
if (ret) {
|
|
||||||
ocf_io_put(io);
|
|
||||||
cas_free_blk_data(data);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ocf_io_set_cmpl(io, NULL, NULL, block_dev_complete_rq);
|
|
||||||
|
|
||||||
ocf_core_submit_io(io);
|
|
||||||
} else {
|
|
||||||
struct list_head list = LIST_HEAD_INIT(list);
|
|
||||||
|
|
||||||
data = cas_alloc_blk_data(0, GFP_NOIO);
|
|
||||||
if (data == NULL) {
|
|
||||||
printk(KERN_CRIT
|
|
||||||
"Out of memory. Ending IO processing.\n");
|
|
||||||
ocf_io_put(io);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
data->master_io_req = rq;
|
|
||||||
|
|
||||||
if (ocf_io_set_data(io, data, 0)) {
|
|
||||||
ocf_io_put(io);
|
|
||||||
cas_free_blk_data(data);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate setup and setup */
|
|
||||||
ret = _blockdev_alloc_many_requests(core, &list, rq, io);
|
|
||||||
if (ret < 0) {
|
|
||||||
printk(KERN_CRIT
|
|
||||||
"Out of memory. Ending IO processing.\n");
|
|
||||||
cas_free_blk_data(data);
|
|
||||||
ocf_io_put(io);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
BUG_ON(list_empty(&list));
|
|
||||||
|
|
||||||
/* Go over list and push request to the engine */
|
|
||||||
while (!list_empty(&list)) {
|
|
||||||
struct ocf_io *sub_io;
|
|
||||||
|
|
||||||
data = list_first_entry(&list, struct blk_data, list);
|
|
||||||
list_del(&data->list);
|
|
||||||
|
|
||||||
sub_io = data->io;
|
|
||||||
|
|
||||||
ocf_core_submit_io(sub_io);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CAS_BLK_STATUS_T _block_dev_queue_request(struct casdsk_disk *dsk, struct request *rq, void *private)
|
|
||||||
{
|
|
||||||
ocf_core_t core = private;
|
|
||||||
int ret = __block_dev_queue_rq(rq, core);
|
|
||||||
if (ret)
|
|
||||||
_blockdev_end_request_all(rq, ret);
|
|
||||||
|
|
||||||
return CAS_ERRNO_TO_BLK_STS(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int _blkdev_can_hndl_bio(struct bio *bio)
|
static inline int _blkdev_can_hndl_bio(struct bio *bio)
|
||||||
{
|
{
|
||||||
if (CAS_CHECK_BARRIER(bio)) {
|
if (CAS_CHECK_BARRIER(bio)) {
|
||||||
@ -847,7 +425,6 @@ static void _blockdev_submit_bio(struct casdsk_disk *dsk,
|
|||||||
|
|
||||||
static struct casdsk_exp_obj_ops _blockdev_exp_obj_ops = {
|
static struct casdsk_exp_obj_ops _blockdev_exp_obj_ops = {
|
||||||
.set_geometry = _blockdev_set_geometry,
|
.set_geometry = _blockdev_set_geometry,
|
||||||
.queue_rq_fn = _block_dev_queue_request,
|
|
||||||
.submit_bio = _blockdev_submit_bio,
|
.submit_bio = _blockdev_submit_bio,
|
||||||
.pending_rq_inc = _blockdev_pending_req_inc,
|
.pending_rq_inc = _blockdev_pending_req_inc,
|
||||||
.pending_rq_dec = _blockdev_pending_req_dec,
|
.pending_rq_dec = _blockdev_pending_req_dec,
|
||||||
|
@ -45,13 +45,6 @@ struct casdsk_exp_obj_ops {
|
|||||||
void (*submit_bio)(struct casdsk_disk *dsk,
|
void (*submit_bio)(struct casdsk_disk *dsk,
|
||||||
struct bio *bio, void *private);
|
struct bio *bio, void *private);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief queue_rq_fn of exported object (top) block device.
|
|
||||||
* Called by cas_disk when cas_disk device is in attached mode.
|
|
||||||
*/
|
|
||||||
CAS_BLK_STATUS_T (*queue_rq_fn)(struct casdsk_disk *dsk, struct request *rq,
|
|
||||||
void *private);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Increment exported object pending request counter.
|
* @brief Increment exported object pending request counter.
|
||||||
*/
|
*/
|
||||||
|
@ -461,30 +461,9 @@ static int _casdsk_exp_obj_init_kobject(struct casdsk_disk *dsk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static CAS_BLK_STATUS_T _casdsk_exp_obj_queue_rq(struct blk_mq_hw_ctx *hctx,
|
static CAS_BLK_STATUS_T _casdsk_exp_obj_queue_rq(struct blk_mq_hw_ctx *hctx,
|
||||||
const struct blk_mq_queue_data *bd)
|
const struct blk_mq_queue_data *bd)
|
||||||
{
|
{
|
||||||
struct casdsk_disk *dsk = hctx->driver_data;
|
return CAS_BLK_STS_NOTSUPP;
|
||||||
struct casdsk_exp_obj *exp_obj = dsk->exp_obj;
|
|
||||||
struct request *rq = bd->rq;
|
|
||||||
CAS_BLK_STATUS_T result = CAS_BLK_STS_OK;
|
|
||||||
|
|
||||||
if (likely(exp_obj->ops && exp_obj->ops->queue_rq_fn)) {
|
|
||||||
exp_obj->ops->pending_rq_inc(dsk, dsk->private);
|
|
||||||
|
|
||||||
result = exp_obj->ops->queue_rq_fn(dsk, rq, dsk->private);
|
|
||||||
|
|
||||||
exp_obj->ops->pending_rq_dec(dsk, dsk->private);
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* queue_rq_fn() is required, as we can't do any default
|
|
||||||
* action in attached mode. In PT mode we handle all bios
|
|
||||||
* directly in make_request_fn(), so queue_rq_fn() will not
|
|
||||||
* be called.
|
|
||||||
*/
|
|
||||||
BUG_ON(rq);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct blk_mq_ops casdsk_mq_ops = {
|
static struct blk_mq_ops casdsk_mq_ops = {
|
||||||
|
Loading…
Reference in New Issue
Block a user