From: Benjamin Block <bblock@linux.vnet.ibm.com>
To: Christoph Hellwig <hch@lst.de>
Cc: "James E . J . Bottomley" <jejb@linux.vnet.ibm.com>,
"Martin K . Petersen" <martin.petersen@oracle.com>,
Jens Axboe <axboe@kernel.dk>,
linux-block@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-scsi@vger.kernel.org,
Johannes Thumshirn <jthumshirn@suse.de>,
Steffen Maier <maier@linux.vnet.ibm.com>,
open-iscsi@googlegroups.com
Subject: Re: [RFC PATCH 1/6] bsg: fix kernel panic resulting from missing allocation of a reply-buffer
Date: Mon, 14 Aug 2017 18:32:17 +0200 [thread overview]
Message-ID: <20170814163217.GA18228@bblock-ThinkPad-W530> (raw)
In-Reply-To: <20170811160142.GB31625@bblock-ThinkPad-W530>
Hey Christoph,
I looked over the patch in detail, see below.
> From f5b03b82df0569c035022c1c2535696186907f1a Mon Sep 17 00:00:00 2001
> From: Christoph Hellwig <hch@lst.de>
> Date: Fri, 11 Aug 2017 11:03:29 +0200
> Subject: bsg-lib: allocate sense data for each request
>
> Since we split the scsi_request out of the request the driver is supposed
> to provide storage for the sense buffer. The bsg-lib code failed to do so,
> though and will crash anytime it is used.
>
> This patch moves bsg-lib to allocate and setup the bsg_job ahead of time,
> and allocate the sense data, which is used as reply buffer in bsg.
>
> Reported-by: Steffen Maier <maier@linux.vnet.ibm.com>
> Signed-off-by: Benjamin Block <bblock@linux.vnet.ibm.com>
> Fixes: 82ed4db499b8 ("block: split scsi_request out of struct request")
> Cc: <stable@vger.kernel.org> #4.11+
> ---
> block/bsg-lib.c | 51 +++++++++++++++++++++++++++----------------------
> include/linux/blkdev.h | 1 -
> include/linux/bsg-lib.h | 2 ++
> 3 files changed, 30 insertions(+), 24 deletions(-)
>
> diff --git a/block/bsg-lib.c b/block/bsg-lib.c
> index c4513b23f57a..c07333c3b785 100644
> --- a/block/bsg-lib.c
> +++ b/block/bsg-lib.c
> @@ -37,13 +37,11 @@ static void bsg_destroy_job(struct kref *kref)
> struct bsg_job *job = container_of(kref, struct bsg_job, kref);
> struct request *rq = job->req;
>
> - blk_end_request_all(rq, BLK_STS_OK);
> -
> put_device(job->dev); /* release reference for the request */
>
> kfree(job->request_payload.sg_list);
> kfree(job->reply_payload.sg_list);
> - kfree(job);
> + blk_end_request_all(rq, BLK_STS_OK);
What is the reason for moving that last line? Just wondering whether
that might change the behavior somehow, although it doesn't look like it
from the code.
> }
>
> void bsg_job_put(struct bsg_job *job)
> @@ -100,7 +98,7 @@ EXPORT_SYMBOL_GPL(bsg_job_done);
> */
> static void bsg_softirq_done(struct request *rq)
> {
> - struct bsg_job *job = rq->special;
> + struct bsg_job *job = blk_mq_rq_to_pdu(rq);
>
> bsg_job_put(job);
> }
> @@ -129,24 +127,11 @@ static int bsg_map_buffer(struct bsg_buffer *buf, struct request *req)
> static int bsg_create_job(struct device *dev, struct request *req)
> {
> struct request *rsp = req->next_rq;
> - struct request_queue *q = req->q;
> + struct bsg_job *job = blk_mq_rq_to_pdu(req);
> struct scsi_request *rq = scsi_req(req);
> - struct bsg_job *job;
> int ret;
>
> - BUG_ON(req->special);
> -
> - job = kzalloc(sizeof(struct bsg_job) + q->bsg_job_size, GFP_KERNEL);
> - if (!job)
> - return -ENOMEM;
> -
> - req->special = job;
> - job->req = req;
> - if (q->bsg_job_size)
> - job->dd_data = (void *)&job[1];
> - job->request = rq->cmd;
> job->request_len = rq->cmd_len;
> - job->reply = rq->sense;
> job->reply_len = SCSI_SENSE_BUFFERSIZE; /* Size of sense buffer
> * allocated */
> if (req->bio) {
> @@ -187,7 +172,6 @@ static void bsg_request_fn(struct request_queue *q)
> {
> struct device *dev = q->queuedata;
> struct request *req;
> - struct bsg_job *job;
> int ret;
>
> if (!get_device(dev))
> @@ -207,8 +191,7 @@ static void bsg_request_fn(struct request_queue *q)
> continue;
> }
>
> - job = req->special;
> - ret = q->bsg_job_fn(job);
> + ret = q->bsg_job_fn(blk_mq_rq_to_pdu(req));
> spin_lock_irq(q->queue_lock);
> if (ret)
> break;
> @@ -219,6 +202,27 @@ static void bsg_request_fn(struct request_queue *q)
> spin_lock_irq(q->queue_lock);
> }
>
> +static int bsg_init_rq(struct request_queue *q, struct request *req, gfp_t gfp)
> +{
> + struct bsg_job *job = blk_mq_rq_to_pdu(req);
> +
> + memset(job, 0, sizeof(*job));
> + job->req = req;
> + job->request = job->sreq.cmd;
That doesn't work with bsg.c if the request submitted by the user is
bigger than BLK_MAX_CDB. There is code in blk_fill_sgv4_hdr_rq() that
will reassign the req->cmd point in that case to something else.
This is maybe wrong in the same vein as my Patch 1 is. If not for the
legacy code in bsg.c, setting this here, will miss changes to that
pointer between request-allocation and job-submission.
So maybe just move this to bsg_create_job().
> + job->dd_data = job + 1;
> + job->reply = job->sreq.sense = kzalloc(job->reply_len, gfp);
job->reply_len will be 0 here, won't it? You probably have to pull the
"job->reply_len = SCSI_SENSE_BUFFERSIZE" here from bsg_create_job().
> + if (!job->reply)
> + return -ENOMEM;
> + return 0;
> +}
> +
> +static void bsg_exit_rq(struct request_queue *q, struct request *req)
> +{
> + struct bsg_job *job = blk_mq_rq_to_pdu(req);
> +
> + kfree(job->reply);
Don't we need to free the reply-buffer as well?
Not sure how you wanna proceed. I can also sketch something up and
already test it on our cards, to prevent the ping-pong.
Beste Gr��e / Best regards,
- Benjamin Block
> +}
> +
> /**
> * bsg_setup_queue - Create and add the bsg hooks so we can receive requests
> * @dev: device to attach bsg device to
> @@ -235,7 +239,9 @@ struct request_queue *bsg_setup_queue(struct device *dev, char *name,
> q = blk_alloc_queue(GFP_KERNEL);
> if (!q)
> return ERR_PTR(-ENOMEM);
> - q->cmd_size = sizeof(struct scsi_request);
> + q->cmd_size = sizeof(struct bsg_job) + dd_job_size;
> + q->init_rq_fn = bsg_init_rq;
> + q->exit_rq_fn = bsg_exit_rq;
> q->request_fn = bsg_request_fn;
>
> ret = blk_init_allocated_queue(q);
> @@ -243,7 +249,6 @@ struct request_queue *bsg_setup_queue(struct device *dev, char *name,
> goto out_cleanup_queue;
>
> q->queuedata = dev;
> - q->bsg_job_size = dd_job_size;
> q->bsg_job_fn = job_fn;
> queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
> queue_flag_set_unlocked(QUEUE_FLAG_SCSI_PASSTHROUGH, q);
> diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
> index f45f157b2910..6ae9aa6f93f0 100644
> --- a/include/linux/blkdev.h
> +++ b/include/linux/blkdev.h
> @@ -568,7 +568,6 @@ struct request_queue {
>
> #if defined(CONFIG_BLK_DEV_BSG)
> bsg_job_fn *bsg_job_fn;
> - int bsg_job_size;
> struct bsg_class_device bsg_dev;
> #endif
>
> diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h
> index e34dde2da0ef..637a20cfb237 100644
> --- a/include/linux/bsg-lib.h
> +++ b/include/linux/bsg-lib.h
> @@ -24,6 +24,7 @@
> #define _BLK_BSG_
>
> #include <linux/blkdev.h>
> +#include <scsi/scsi_request.h>
>
> struct request;
> struct device;
> @@ -37,6 +38,7 @@ struct bsg_buffer {
> };
>
> struct bsg_job {
> + struct scsi_request sreq;
> struct device *dev;
> struct request *req;
>
> --
> 2.11.0
>
--
Linux on z Systems Development / IBM Systems & Technology Group
IBM Deutschland Research & Development GmbH
Vorsitz. AufsR.: Martina Koederitz / Gesch�ftsf�hrung: Dirk Wittkopp
Sitz der Gesellschaft: B�blingen / Registergericht: AmtsG Stuttgart, HRB 243294
WARNING: multiple messages have this Message-ID (diff)
From: Benjamin Block <bblock-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
To: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
Cc: "James E . J . Bottomley"
<jejb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>,
"Martin K . Petersen"
<martin.petersen-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>,
Jens Axboe <axboe-tSWWG44O7X1aa/9Udqfwiw@public.gmane.org>,
linux-block-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-scsi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Johannes Thumshirn <jthumshirn-l3A5Bk7waGM@public.gmane.org>,
Steffen Maier
<maier-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>,
open-iscsi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
Subject: Re: [RFC PATCH 1/6] bsg: fix kernel panic resulting from missing allocation of a reply-buffer
Date: Mon, 14 Aug 2017 18:32:17 +0200 [thread overview]
Message-ID: <20170814163217.GA18228@bblock-ThinkPad-W530> (raw)
In-Reply-To: <20170811160142.GB31625@bblock-ThinkPad-W530>
Hey Christoph,
I looked over the patch in detail, see below.
> From f5b03b82df0569c035022c1c2535696186907f1a Mon Sep 17 00:00:00 2001
> From: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
> Date: Fri, 11 Aug 2017 11:03:29 +0200
> Subject: bsg-lib: allocate sense data for each request
>
> Since we split the scsi_request out of the request the driver is supposed
> to provide storage for the sense buffer. The bsg-lib code failed to do so,
> though and will crash anytime it is used.
>
> This patch moves bsg-lib to allocate and setup the bsg_job ahead of time,
> and allocate the sense data, which is used as reply buffer in bsg.
>
> Reported-by: Steffen Maier <maier-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> Signed-off-by: Benjamin Block <bblock-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> Fixes: 82ed4db499b8 ("block: split scsi_request out of struct request")
> Cc: <stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org> #4.11+
> ---
> block/bsg-lib.c | 51 +++++++++++++++++++++++++++----------------------
> include/linux/blkdev.h | 1 -
> include/linux/bsg-lib.h | 2 ++
> 3 files changed, 30 insertions(+), 24 deletions(-)
>
> diff --git a/block/bsg-lib.c b/block/bsg-lib.c
> index c4513b23f57a..c07333c3b785 100644
> --- a/block/bsg-lib.c
> +++ b/block/bsg-lib.c
> @@ -37,13 +37,11 @@ static void bsg_destroy_job(struct kref *kref)
> struct bsg_job *job = container_of(kref, struct bsg_job, kref);
> struct request *rq = job->req;
>
> - blk_end_request_all(rq, BLK_STS_OK);
> -
> put_device(job->dev); /* release reference for the request */
>
> kfree(job->request_payload.sg_list);
> kfree(job->reply_payload.sg_list);
> - kfree(job);
> + blk_end_request_all(rq, BLK_STS_OK);
What is the reason for moving that last line? Just wondering whether
that might change the behavior somehow, although it doesn't look like it
from the code.
> }
>
> void bsg_job_put(struct bsg_job *job)
> @@ -100,7 +98,7 @@ EXPORT_SYMBOL_GPL(bsg_job_done);
> */
> static void bsg_softirq_done(struct request *rq)
> {
> - struct bsg_job *job = rq->special;
> + struct bsg_job *job = blk_mq_rq_to_pdu(rq);
>
> bsg_job_put(job);
> }
> @@ -129,24 +127,11 @@ static int bsg_map_buffer(struct bsg_buffer *buf, struct request *req)
> static int bsg_create_job(struct device *dev, struct request *req)
> {
> struct request *rsp = req->next_rq;
> - struct request_queue *q = req->q;
> + struct bsg_job *job = blk_mq_rq_to_pdu(req);
> struct scsi_request *rq = scsi_req(req);
> - struct bsg_job *job;
> int ret;
>
> - BUG_ON(req->special);
> -
> - job = kzalloc(sizeof(struct bsg_job) + q->bsg_job_size, GFP_KERNEL);
> - if (!job)
> - return -ENOMEM;
> -
> - req->special = job;
> - job->req = req;
> - if (q->bsg_job_size)
> - job->dd_data = (void *)&job[1];
> - job->request = rq->cmd;
> job->request_len = rq->cmd_len;
> - job->reply = rq->sense;
> job->reply_len = SCSI_SENSE_BUFFERSIZE; /* Size of sense buffer
> * allocated */
> if (req->bio) {
> @@ -187,7 +172,6 @@ static void bsg_request_fn(struct request_queue *q)
> {
> struct device *dev = q->queuedata;
> struct request *req;
> - struct bsg_job *job;
> int ret;
>
> if (!get_device(dev))
> @@ -207,8 +191,7 @@ static void bsg_request_fn(struct request_queue *q)
> continue;
> }
>
> - job = req->special;
> - ret = q->bsg_job_fn(job);
> + ret = q->bsg_job_fn(blk_mq_rq_to_pdu(req));
> spin_lock_irq(q->queue_lock);
> if (ret)
> break;
> @@ -219,6 +202,27 @@ static void bsg_request_fn(struct request_queue *q)
> spin_lock_irq(q->queue_lock);
> }
>
> +static int bsg_init_rq(struct request_queue *q, struct request *req, gfp_t gfp)
> +{
> + struct bsg_job *job = blk_mq_rq_to_pdu(req);
> +
> + memset(job, 0, sizeof(*job));
> + job->req = req;
> + job->request = job->sreq.cmd;
That doesn't work with bsg.c if the request submitted by the user is
bigger than BLK_MAX_CDB. There is code in blk_fill_sgv4_hdr_rq() that
will reassign the req->cmd point in that case to something else.
This is maybe wrong in the same vein as my Patch 1 is. If not for the
legacy code in bsg.c, setting this here, will miss changes to that
pointer between request-allocation and job-submission.
So maybe just move this to bsg_create_job().
> + job->dd_data = job + 1;
> + job->reply = job->sreq.sense = kzalloc(job->reply_len, gfp);
job->reply_len will be 0 here, won't it? You probably have to pull the
"job->reply_len = SCSI_SENSE_BUFFERSIZE" here from bsg_create_job().
> + if (!job->reply)
> + return -ENOMEM;
> + return 0;
> +}
> +
> +static void bsg_exit_rq(struct request_queue *q, struct request *req)
> +{
> + struct bsg_job *job = blk_mq_rq_to_pdu(req);
> +
> + kfree(job->reply);
Don't we need to free the reply-buffer as well?
Not sure how you wanna proceed. I can also sketch something up and
already test it on our cards, to prevent the ping-pong.
Beste Grüße / Best regards,
- Benjamin Block
> +}
> +
> /**
> * bsg_setup_queue - Create and add the bsg hooks so we can receive requests
> * @dev: device to attach bsg device to
> @@ -235,7 +239,9 @@ struct request_queue *bsg_setup_queue(struct device *dev, char *name,
> q = blk_alloc_queue(GFP_KERNEL);
> if (!q)
> return ERR_PTR(-ENOMEM);
> - q->cmd_size = sizeof(struct scsi_request);
> + q->cmd_size = sizeof(struct bsg_job) + dd_job_size;
> + q->init_rq_fn = bsg_init_rq;
> + q->exit_rq_fn = bsg_exit_rq;
> q->request_fn = bsg_request_fn;
>
> ret = blk_init_allocated_queue(q);
> @@ -243,7 +249,6 @@ struct request_queue *bsg_setup_queue(struct device *dev, char *name,
> goto out_cleanup_queue;
>
> q->queuedata = dev;
> - q->bsg_job_size = dd_job_size;
> q->bsg_job_fn = job_fn;
> queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
> queue_flag_set_unlocked(QUEUE_FLAG_SCSI_PASSTHROUGH, q);
> diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
> index f45f157b2910..6ae9aa6f93f0 100644
> --- a/include/linux/blkdev.h
> +++ b/include/linux/blkdev.h
> @@ -568,7 +568,6 @@ struct request_queue {
>
> #if defined(CONFIG_BLK_DEV_BSG)
> bsg_job_fn *bsg_job_fn;
> - int bsg_job_size;
> struct bsg_class_device bsg_dev;
> #endif
>
> diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h
> index e34dde2da0ef..637a20cfb237 100644
> --- a/include/linux/bsg-lib.h
> +++ b/include/linux/bsg-lib.h
> @@ -24,6 +24,7 @@
> #define _BLK_BSG_
>
> #include <linux/blkdev.h>
> +#include <scsi/scsi_request.h>
>
> struct request;
> struct device;
> @@ -37,6 +38,7 @@ struct bsg_buffer {
> };
>
> struct bsg_job {
> + struct scsi_request sreq;
> struct device *dev;
> struct request *req;
>
> --
> 2.11.0
>
--
Linux on z Systems Development / IBM Systems & Technology Group
IBM Deutschland Research & Development GmbH
Vorsitz. AufsR.: Martina Koederitz / Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen / Registergericht: AmtsG Stuttgart, HRB 243294
--
You received this message because you are subscribed to the Google Groups "open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to open-iscsi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To post to this group, send email to open-iscsi-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
Visit this group at https://groups.google.com/group/open-iscsi.
For more options, visit https://groups.google.com/d/optout.
WARNING: multiple messages have this Message-ID (diff)
From: Benjamin Block <bblock@linux.vnet.ibm.com>
To: Christoph Hellwig <hch@lst.de>
Cc: "James E . J . Bottomley" <jejb@linux.vnet.ibm.com>,
"Martin K . Petersen" <martin.petersen@oracle.com>,
Jens Axboe <axboe@kernel.dk>,
linux-block@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-scsi@vger.kernel.org,
Johannes Thumshirn <jthumshirn@suse.de>,
Steffen Maier <maier@linux.vnet.ibm.com>,
open-iscsi@googlegroups.com
Subject: Re: [RFC PATCH 1/6] bsg: fix kernel panic resulting from missing allocation of a reply-buffer
Date: Mon, 14 Aug 2017 18:32:17 +0200 [thread overview]
Message-ID: <20170814163217.GA18228@bblock-ThinkPad-W530> (raw)
In-Reply-To: <20170811160142.GB31625@bblock-ThinkPad-W530>
Hey Christoph,
I looked over the patch in detail, see below.
> From f5b03b82df0569c035022c1c2535696186907f1a Mon Sep 17 00:00:00 2001
> From: Christoph Hellwig <hch@lst.de>
> Date: Fri, 11 Aug 2017 11:03:29 +0200
> Subject: bsg-lib: allocate sense data for each request
>
> Since we split the scsi_request out of the request the driver is supposed
> to provide storage for the sense buffer. The bsg-lib code failed to do so,
> though and will crash anytime it is used.
>
> This patch moves bsg-lib to allocate and setup the bsg_job ahead of time,
> and allocate the sense data, which is used as reply buffer in bsg.
>
> Reported-by: Steffen Maier <maier@linux.vnet.ibm.com>
> Signed-off-by: Benjamin Block <bblock@linux.vnet.ibm.com>
> Fixes: 82ed4db499b8 ("block: split scsi_request out of struct request")
> Cc: <stable@vger.kernel.org> #4.11+
> ---
> block/bsg-lib.c | 51 +++++++++++++++++++++++++++----------------------
> include/linux/blkdev.h | 1 -
> include/linux/bsg-lib.h | 2 ++
> 3 files changed, 30 insertions(+), 24 deletions(-)
>
> diff --git a/block/bsg-lib.c b/block/bsg-lib.c
> index c4513b23f57a..c07333c3b785 100644
> --- a/block/bsg-lib.c
> +++ b/block/bsg-lib.c
> @@ -37,13 +37,11 @@ static void bsg_destroy_job(struct kref *kref)
> struct bsg_job *job = container_of(kref, struct bsg_job, kref);
> struct request *rq = job->req;
>
> - blk_end_request_all(rq, BLK_STS_OK);
> -
> put_device(job->dev); /* release reference for the request */
>
> kfree(job->request_payload.sg_list);
> kfree(job->reply_payload.sg_list);
> - kfree(job);
> + blk_end_request_all(rq, BLK_STS_OK);
What is the reason for moving that last line? Just wondering whether
that might change the behavior somehow, although it doesn't look like it
from the code.
> }
>
> void bsg_job_put(struct bsg_job *job)
> @@ -100,7 +98,7 @@ EXPORT_SYMBOL_GPL(bsg_job_done);
> */
> static void bsg_softirq_done(struct request *rq)
> {
> - struct bsg_job *job = rq->special;
> + struct bsg_job *job = blk_mq_rq_to_pdu(rq);
>
> bsg_job_put(job);
> }
> @@ -129,24 +127,11 @@ static int bsg_map_buffer(struct bsg_buffer *buf, struct request *req)
> static int bsg_create_job(struct device *dev, struct request *req)
> {
> struct request *rsp = req->next_rq;
> - struct request_queue *q = req->q;
> + struct bsg_job *job = blk_mq_rq_to_pdu(req);
> struct scsi_request *rq = scsi_req(req);
> - struct bsg_job *job;
> int ret;
>
> - BUG_ON(req->special);
> -
> - job = kzalloc(sizeof(struct bsg_job) + q->bsg_job_size, GFP_KERNEL);
> - if (!job)
> - return -ENOMEM;
> -
> - req->special = job;
> - job->req = req;
> - if (q->bsg_job_size)
> - job->dd_data = (void *)&job[1];
> - job->request = rq->cmd;
> job->request_len = rq->cmd_len;
> - job->reply = rq->sense;
> job->reply_len = SCSI_SENSE_BUFFERSIZE; /* Size of sense buffer
> * allocated */
> if (req->bio) {
> @@ -187,7 +172,6 @@ static void bsg_request_fn(struct request_queue *q)
> {
> struct device *dev = q->queuedata;
> struct request *req;
> - struct bsg_job *job;
> int ret;
>
> if (!get_device(dev))
> @@ -207,8 +191,7 @@ static void bsg_request_fn(struct request_queue *q)
> continue;
> }
>
> - job = req->special;
> - ret = q->bsg_job_fn(job);
> + ret = q->bsg_job_fn(blk_mq_rq_to_pdu(req));
> spin_lock_irq(q->queue_lock);
> if (ret)
> break;
> @@ -219,6 +202,27 @@ static void bsg_request_fn(struct request_queue *q)
> spin_lock_irq(q->queue_lock);
> }
>
> +static int bsg_init_rq(struct request_queue *q, struct request *req, gfp_t gfp)
> +{
> + struct bsg_job *job = blk_mq_rq_to_pdu(req);
> +
> + memset(job, 0, sizeof(*job));
> + job->req = req;
> + job->request = job->sreq.cmd;
That doesn't work with bsg.c if the request submitted by the user is
bigger than BLK_MAX_CDB. There is code in blk_fill_sgv4_hdr_rq() that
will reassign the req->cmd point in that case to something else.
This is maybe wrong in the same vein as my Patch 1 is. If not for the
legacy code in bsg.c, setting this here, will miss changes to that
pointer between request-allocation and job-submission.
So maybe just move this to bsg_create_job().
> + job->dd_data = job + 1;
> + job->reply = job->sreq.sense = kzalloc(job->reply_len, gfp);
job->reply_len will be 0 here, won't it? You probably have to pull the
"job->reply_len = SCSI_SENSE_BUFFERSIZE" here from bsg_create_job().
> + if (!job->reply)
> + return -ENOMEM;
> + return 0;
> +}
> +
> +static void bsg_exit_rq(struct request_queue *q, struct request *req)
> +{
> + struct bsg_job *job = blk_mq_rq_to_pdu(req);
> +
> + kfree(job->reply);
Don't we need to free the reply-buffer as well?
Not sure how you wanna proceed. I can also sketch something up and
already test it on our cards, to prevent the ping-pong.
Beste Grüße / Best regards,
- Benjamin Block
> +}
> +
> /**
> * bsg_setup_queue - Create and add the bsg hooks so we can receive requests
> * @dev: device to attach bsg device to
> @@ -235,7 +239,9 @@ struct request_queue *bsg_setup_queue(struct device *dev, char *name,
> q = blk_alloc_queue(GFP_KERNEL);
> if (!q)
> return ERR_PTR(-ENOMEM);
> - q->cmd_size = sizeof(struct scsi_request);
> + q->cmd_size = sizeof(struct bsg_job) + dd_job_size;
> + q->init_rq_fn = bsg_init_rq;
> + q->exit_rq_fn = bsg_exit_rq;
> q->request_fn = bsg_request_fn;
>
> ret = blk_init_allocated_queue(q);
> @@ -243,7 +249,6 @@ struct request_queue *bsg_setup_queue(struct device *dev, char *name,
> goto out_cleanup_queue;
>
> q->queuedata = dev;
> - q->bsg_job_size = dd_job_size;
> q->bsg_job_fn = job_fn;
> queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
> queue_flag_set_unlocked(QUEUE_FLAG_SCSI_PASSTHROUGH, q);
> diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
> index f45f157b2910..6ae9aa6f93f0 100644
> --- a/include/linux/blkdev.h
> +++ b/include/linux/blkdev.h
> @@ -568,7 +568,6 @@ struct request_queue {
>
> #if defined(CONFIG_BLK_DEV_BSG)
> bsg_job_fn *bsg_job_fn;
> - int bsg_job_size;
> struct bsg_class_device bsg_dev;
> #endif
>
> diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h
> index e34dde2da0ef..637a20cfb237 100644
> --- a/include/linux/bsg-lib.h
> +++ b/include/linux/bsg-lib.h
> @@ -24,6 +24,7 @@
> #define _BLK_BSG_
>
> #include <linux/blkdev.h>
> +#include <scsi/scsi_request.h>
>
> struct request;
> struct device;
> @@ -37,6 +38,7 @@ struct bsg_buffer {
> };
>
> struct bsg_job {
> + struct scsi_request sreq;
> struct device *dev;
> struct request *req;
>
> --
> 2.11.0
>
--
Linux on z Systems Development / IBM Systems & Technology Group
IBM Deutschland Research & Development GmbH
Vorsitz. AufsR.: Martina Koederitz / Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen / Registergericht: AmtsG Stuttgart, HRB 243294
next prev parent reply other threads:[~2017-08-14 16:32 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-09 14:11 [RFC PATCH 0/6] bsg: fix regression resulting in panics when sending commands via BSG and some sanity cleanups Benjamin Block
2017-08-09 14:11 ` [RFC PATCH 1/6] bsg: fix kernel panic resulting from missing allocation of a reply-buffer Benjamin Block
2017-08-09 14:11 ` Benjamin Block
2017-08-10 9:32 ` Christoph Hellwig
2017-08-10 9:32 ` Christoph Hellwig
2017-08-10 22:10 ` Benjamin Block
2017-08-10 22:10 ` Benjamin Block
2017-08-10 22:45 ` Benjamin Block
2017-08-10 22:45 ` Benjamin Block
2017-08-10 22:45 ` Benjamin Block
2017-08-11 8:38 ` Christoph Hellwig
2017-08-11 8:38 ` Christoph Hellwig
2017-08-11 9:14 ` Christoph Hellwig
2017-08-11 13:49 ` Benjamin Block
2017-08-11 13:49 ` Benjamin Block
2017-08-11 14:36 ` Christoph Hellwig
2017-08-11 15:32 ` Benjamin Block
2017-08-11 15:32 ` Benjamin Block
2017-08-11 15:35 ` Christoph Hellwig
2017-08-11 16:01 ` Benjamin Block
2017-08-11 16:01 ` Benjamin Block
2017-08-13 14:39 ` Christoph Hellwig
2017-08-14 16:33 ` Benjamin Block
2017-08-14 16:33 ` Benjamin Block
2017-08-14 16:32 ` Benjamin Block [this message]
2017-08-14 16:32 ` Benjamin Block
2017-08-14 16:32 ` Benjamin Block
2017-08-16 10:53 ` Christoph Hellwig
2017-08-09 14:11 ` [RFC PATCH 2/6] bsg: assign sense_len instead of fixed SCSI_SENSE_BUFFERSIZE Benjamin Block
2017-08-09 14:11 ` Benjamin Block
2017-08-10 9:32 ` Christoph Hellwig
2017-08-10 9:32 ` Christoph Hellwig
2017-08-09 14:11 ` [RFC PATCH 3/6] bsg: scsi-transport: add compile-tests to prevent reply-buffer overflows Benjamin Block
2017-08-10 9:32 ` Christoph Hellwig
2017-08-10 9:32 ` Christoph Hellwig
2017-08-09 14:11 ` [RFC PATCH 4/6] bsg: refactor ioctl to use regular BSG-command infrastructure for SG_IO Benjamin Block
2017-08-09 14:11 ` Benjamin Block
2017-08-10 8:24 ` Johannes Thumshirn
2017-08-10 8:24 ` Johannes Thumshirn
2017-08-10 9:34 ` Christoph Hellwig
2017-08-10 22:12 ` Benjamin Block
2017-08-10 22:12 ` Benjamin Block
2017-08-09 14:11 ` [RFC PATCH 5/6] bsg: reduce unnecessary arguments for bsg_map_hdr() Benjamin Block
2017-08-09 14:11 ` Benjamin Block
2017-08-10 8:26 ` Johannes Thumshirn
2017-08-10 8:26 ` Johannes Thumshirn
2017-08-10 8:26 ` Johannes Thumshirn
2017-08-10 9:35 ` Christoph Hellwig
2017-08-10 22:19 ` Benjamin Block
2017-08-10 22:19 ` Benjamin Block
2017-08-10 22:19 ` Benjamin Block
2017-08-09 14:11 ` [RFC PATCH 6/6] bsg: reduce unnecessary arguments for blk_complete_sgv4_hdr_rq() Benjamin Block
2017-08-09 14:11 ` Benjamin Block
2017-08-10 8:27 ` Johannes Thumshirn
2017-08-10 8:27 ` Johannes Thumshirn
2017-08-10 9:35 ` Christoph Hellwig
2017-08-10 9:35 ` Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170814163217.GA18228@bblock-ThinkPad-W530 \
--to=bblock@linux.vnet.ibm.com \
--cc=axboe@kernel.dk \
--cc=hch@lst.de \
--cc=jejb@linux.vnet.ibm.com \
--cc=jthumshirn@suse.de \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=maier@linux.vnet.ibm.com \
--cc=martin.petersen@oracle.com \
--cc=open-iscsi@googlegroups.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.